V8 Project
simplified-operator-reducer-unittest.cc
Go to the documentation of this file.
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
9 #include "src/compiler/typer.h"
10 #include "src/conversions.h"
11 
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15 
17  public:
18  explicit SimplifiedOperatorReducerTest(int num_parameters = 1)
19  : GraphTest(num_parameters), simplified_(zone()) {}
21 
22  protected:
23  Reduction Reduce(Node* node) {
24  Typer typer(zone());
25  MachineOperatorBuilder machine;
26  JSOperatorBuilder javascript(zone());
27  JSGraph jsgraph(graph(), common(), &javascript, &typer, &machine);
28  SimplifiedOperatorReducer reducer(&jsgraph);
29  return reducer.Reduce(node);
30  }
31 
32  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
33 
34  private:
35  SimplifiedOperatorBuilder simplified_;
36 };
37 
38 
39 template <typename T>
42  public ::testing::WithParamInterface<T> {
43  public:
44  explicit SimplifiedOperatorReducerTestWithParam(int num_parameters = 1)
45  : SimplifiedOperatorReducerTest(num_parameters) {}
47 };
48 
49 
50 namespace {
51 
52 static const double kFloat64Values[] = {
53  -V8_INFINITY, -6.52696e+290, -1.05768e+290, -5.34203e+268, -1.01997e+268,
54  -8.22758e+266, -1.58402e+261, -5.15246e+241, -5.92107e+226, -1.21477e+226,
55  -1.67913e+188, -1.6257e+184, -2.60043e+170, -2.52941e+168, -3.06033e+116,
56  -4.56201e+52, -3.56788e+50, -9.9066e+38, -3.07261e+31, -2.1271e+09,
57  -1.91489e+09, -1.73053e+09, -9.30675e+08, -26030, -20453,
58  -15790, -11699, -111, -97, -78,
59  -63, -58, -1.53858e-06, -2.98914e-12, -1.14741e-39,
60  -8.20347e-57, -1.48932e-59, -3.17692e-66, -8.93103e-81, -3.91337e-83,
61  -6.0489e-92, -8.83291e-113, -4.28266e-117, -1.92058e-178, -2.0567e-192,
62  -1.68167e-194, -1.51841e-214, -3.98738e-234, -7.31851e-242, -2.21875e-253,
63  -1.11612e-293, -0.0, 0.0, 2.22507e-308, 1.06526e-307,
64  4.16643e-227, 6.76624e-223, 2.0432e-197, 3.16254e-184, 1.37315e-173,
65  2.88603e-172, 1.54155e-99, 4.42923e-81, 1.40539e-73, 5.4462e-73,
66  1.24064e-58, 3.11167e-58, 2.75826e-39, 0.143815, 58,
67  67, 601, 7941, 11644, 13697,
68  25680, 29882, 1.32165e+08, 1.62439e+08, 4.16837e+08,
69  9.59097e+08, 1.32491e+09, 1.8728e+09, 1.0672e+17, 2.69606e+46,
70  1.98285e+79, 1.0098e+82, 7.93064e+88, 3.67444e+121, 9.36506e+123,
71  7.27954e+162, 3.05316e+168, 1.16171e+175, 1.64771e+189, 1.1622e+202,
72  2.00748e+239, 2.51778e+244, 3.90282e+306, 1.79769e+308, V8_INFINITY};
73 
74 
75 static const int32_t kInt32Values[] = {
76  -2147483647 - 1, -2104508227, -2103151830, -1435284490, -1378926425,
77  -1318814539, -1289388009, -1287537572, -1279026536, -1241605942,
78  -1226046939, -941837148, -779818051, -413830641, -245798087,
79  -184657557, -127145950, -105483328, -32325, -26653,
80  -23858, -23834, -22363, -19858, -19044,
81  -18744, -15528, -5309, -3372, -2093,
82  -104, -98, -97, -93, -84,
83  -80, -78, -76, -72, -58,
84  -57, -56, -55, -45, -40,
85  -34, -32, -25, -24, -5,
86  -2, 0, 3, 10, 24,
87  34, 42, 46, 47, 48,
88  52, 56, 64, 65, 71,
89  76, 79, 81, 82, 97,
90  102, 103, 104, 106, 107,
91  109, 116, 122, 3653, 4485,
92  12405, 16504, 26262, 28704, 29755,
93  30554, 16476817, 605431957, 832401070, 873617242,
94  914205764, 1062628108, 1087581664, 1488498068, 1534668023,
95  1661587028, 1696896187, 1866841746, 2032089723, 2147483647};
96 
97 
98 static const uint32_t kUint32Values[] = {
99  0x0, 0x5, 0x8, 0xc, 0xd, 0x26,
100  0x28, 0x29, 0x30, 0x34, 0x3e, 0x42,
101  0x50, 0x5b, 0x63, 0x71, 0x77, 0x7c,
102  0x83, 0x88, 0x96, 0x9c, 0xa3, 0xfa,
103  0x7a7, 0x165d, 0x234d, 0x3acb, 0x43a5, 0x4573,
104  0x5b4f, 0x5f14, 0x6996, 0x6c6e, 0x7289, 0x7b9a,
105  0x7bc9, 0x86bb, 0xa839, 0xaa41, 0xb03b, 0xc942,
106  0xce68, 0xcf4c, 0xd3ad, 0xdea3, 0xe90c, 0xed86,
107  0xfba5, 0x172dcc6, 0x114d8fc1, 0x182d6c9d, 0x1b1e3fad, 0x1db033bf,
108  0x1e1de755, 0x1f625c80, 0x28f6cf00, 0x2acb6a94, 0x2c20240e, 0x2f0fe54e,
109  0x31863a7c, 0x33325474, 0x3532fae3, 0x3bab82ea, 0x4c4b83a2, 0x4cd93d1e,
110  0x4f7331d4, 0x5491b09b, 0x57cc6ff9, 0x60d3b4dc, 0x653f5904, 0x690ae256,
111  0x69fe3276, 0x6bebf0ba, 0x6e2c69a3, 0x73b84ff7, 0x7b3a1924, 0x7ed032d9,
112  0x84dd734b, 0x8552ea53, 0x8680754f, 0x8e9660eb, 0x94fe2b9c, 0x972d30cf,
113  0x9b98c482, 0xb158667e, 0xb432932c, 0xb5b70989, 0xb669971a, 0xb7c359d1,
114  0xbeb15c0d, 0xc171c53d, 0xc743dd38, 0xc8e2af50, 0xc98e2df0, 0xd9d1cdf9,
115  0xdcc91049, 0xe46f396d, 0xee991950, 0xef64e521, 0xf7aeefc9, 0xffffffff};
116 
117 
118 MATCHER(IsNaN, std::string(negation ? "isn't" : "is") + " NaN") {
119  return std::isnan(arg);
120 }
121 
122 } // namespace
123 
124 
125 // -----------------------------------------------------------------------------
126 // Unary operators
127 
128 
129 namespace {
130 
132  const Operator* (SimplifiedOperatorBuilder::*constructor)();
133  const char* constructor_name;
134 };
135 
136 
137 std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
138  return os << unop.constructor_name;
139 }
140 
141 
142 static const UnaryOperator kUnaryOperators[] = {
143  {&SimplifiedOperatorBuilder::BooleanNot, "BooleanNot"},
144  {&SimplifiedOperatorBuilder::ChangeBitToBool, "ChangeBitToBool"},
145  {&SimplifiedOperatorBuilder::ChangeBoolToBit, "ChangeBoolToBit"},
146  {&SimplifiedOperatorBuilder::ChangeFloat64ToTagged,
147  "ChangeFloat64ToTagged"},
148  {&SimplifiedOperatorBuilder::ChangeInt32ToTagged, "ChangeInt32ToTagged"},
149  {&SimplifiedOperatorBuilder::ChangeTaggedToFloat64,
150  "ChangeTaggedToFloat64"},
151  {&SimplifiedOperatorBuilder::ChangeTaggedToInt32, "ChangeTaggedToInt32"},
152  {&SimplifiedOperatorBuilder::ChangeTaggedToUint32, "ChangeTaggedToUint32"},
153  {&SimplifiedOperatorBuilder::ChangeUint32ToTagged, "ChangeUint32ToTagged"}};
154 
155 } // namespace
156 
157 
158 typedef SimplifiedOperatorReducerTestWithParam<UnaryOperator>
160 
161 
163  const UnaryOperator& unop = GetParam();
164  Reduction reduction = Reduce(
165  graph()->NewNode((simplified()->*unop.constructor)(), Parameter(0)));
166  EXPECT_FALSE(reduction.Changed());
167 }
168 
169 
172  ::testing::ValuesIn(kUnaryOperators));
173 
174 
175 // -----------------------------------------------------------------------------
176 // BooleanNot
177 
178 
179 TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithBooleanNot) {
180  Node* param0 = Parameter(0);
181  Reduction reduction = Reduce(
182  graph()->NewNode(simplified()->BooleanNot(),
183  graph()->NewNode(simplified()->BooleanNot(), param0)));
184  ASSERT_TRUE(reduction.Changed());
185  EXPECT_EQ(param0, reduction.replacement());
186 }
187 
188 
189 TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithFalseConstant) {
190  Reduction reduction0 =
191  Reduce(graph()->NewNode(simplified()->BooleanNot(), FalseConstant()));
192  ASSERT_TRUE(reduction0.Changed());
193  EXPECT_THAT(reduction0.replacement(), IsTrueConstant());
194 }
195 
196 
197 TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithTrueConstant) {
198  Reduction reduction1 =
199  Reduce(graph()->NewNode(simplified()->BooleanNot(), TrueConstant()));
200  ASSERT_TRUE(reduction1.Changed());
201  EXPECT_THAT(reduction1.replacement(), IsFalseConstant());
202 }
203 
204 
205 // -----------------------------------------------------------------------------
206 // ChangeBoolToBit
207 
208 
209 TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithChangeBoolToBit) {
210  Node* param0 = Parameter(0);
211  Reduction reduction = Reduce(graph()->NewNode(
212  simplified()->ChangeBitToBool(),
213  graph()->NewNode(simplified()->ChangeBoolToBit(), param0)));
214  ASSERT_TRUE(reduction.Changed());
215  EXPECT_EQ(param0, reduction.replacement());
216 }
217 
218 
219 TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithZeroConstant) {
220  Reduction reduction = Reduce(
221  graph()->NewNode(simplified()->ChangeBitToBool(), Int32Constant(0)));
222  ASSERT_TRUE(reduction.Changed());
223  EXPECT_THAT(reduction.replacement(), IsFalseConstant());
224 }
225 
226 
227 TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithOneConstant) {
228  Reduction reduction = Reduce(
229  graph()->NewNode(simplified()->ChangeBitToBool(), Int32Constant(1)));
230  ASSERT_TRUE(reduction.Changed());
231  EXPECT_THAT(reduction.replacement(), IsTrueConstant());
232 }
233 
234 
235 // -----------------------------------------------------------------------------
236 // ChangeBoolToBit
237 
238 
239 TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithFalseConstant) {
240  Reduction reduction = Reduce(
241  graph()->NewNode(simplified()->ChangeBoolToBit(), FalseConstant()));
242  ASSERT_TRUE(reduction.Changed());
243  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
244 }
245 
246 
247 TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithTrueConstant) {
248  Reduction reduction =
249  Reduce(graph()->NewNode(simplified()->ChangeBoolToBit(), TrueConstant()));
250  ASSERT_TRUE(reduction.Changed());
251  EXPECT_THAT(reduction.replacement(), IsInt32Constant(1));
252 }
253 
254 
255 TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithChangeBitToBool) {
256  Node* param0 = Parameter(0);
257  Reduction reduction = Reduce(graph()->NewNode(
258  simplified()->ChangeBoolToBit(),
259  graph()->NewNode(simplified()->ChangeBitToBool(), param0)));
260  ASSERT_TRUE(reduction.Changed());
261  EXPECT_EQ(param0, reduction.replacement());
262 }
263 
264 
265 // -----------------------------------------------------------------------------
266 // ChangeFloat64ToTagged
267 
268 
269 TEST_F(SimplifiedOperatorReducerTest, ChangeFloat64ToTaggedWithConstant) {
270  TRACED_FOREACH(double, n, kFloat64Values) {
271  Reduction reduction = Reduce(graph()->NewNode(
272  simplified()->ChangeFloat64ToTagged(), Float64Constant(n)));
273  ASSERT_TRUE(reduction.Changed());
274  EXPECT_THAT(reduction.replacement(), IsNumberConstant(n));
275  }
276 }
277 
278 
279 // -----------------------------------------------------------------------------
280 // ChangeInt32ToTagged
281 
282 
283 TEST_F(SimplifiedOperatorReducerTest, ChangeInt32ToTaggedWithConstant) {
284  TRACED_FOREACH(int32_t, n, kInt32Values) {
285  Reduction reduction = Reduce(graph()->NewNode(
286  simplified()->ChangeInt32ToTagged(), Int32Constant(n)));
287  ASSERT_TRUE(reduction.Changed());
288  EXPECT_THAT(reduction.replacement(), IsNumberConstant(FastI2D(n)));
289  }
290 }
291 
292 
293 // -----------------------------------------------------------------------------
294 // ChangeTaggedToFloat64
295 
296 
298  ChangeTaggedToFloat64WithChangeFloat64ToTagged) {
299  Node* param0 = Parameter(0);
300  Reduction reduction = Reduce(graph()->NewNode(
301  simplified()->ChangeTaggedToFloat64(),
302  graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
303  ASSERT_TRUE(reduction.Changed());
304  EXPECT_EQ(param0, reduction.replacement());
305 }
306 
307 
309  ChangeTaggedToFloat64WithChangeInt32ToTagged) {
310  Node* param0 = Parameter(0);
311  Reduction reduction = Reduce(graph()->NewNode(
312  simplified()->ChangeTaggedToFloat64(),
313  graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
314  ASSERT_TRUE(reduction.Changed());
315  EXPECT_THAT(reduction.replacement(), IsChangeInt32ToFloat64(param0));
316 }
317 
318 
320  ChangeTaggedToFloat64WithChangeUint32ToTagged) {
321  Node* param0 = Parameter(0);
322  Reduction reduction = Reduce(graph()->NewNode(
323  simplified()->ChangeTaggedToFloat64(),
324  graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
325  ASSERT_TRUE(reduction.Changed());
326  EXPECT_THAT(reduction.replacement(), IsChangeUint32ToFloat64(param0));
327 }
328 
329 
330 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithConstant) {
331  TRACED_FOREACH(double, n, kFloat64Values) {
332  Reduction reduction = Reduce(graph()->NewNode(
333  simplified()->ChangeTaggedToFloat64(), NumberConstant(n)));
334  ASSERT_TRUE(reduction.Changed());
335  EXPECT_THAT(reduction.replacement(), IsFloat64Constant(n));
336  }
337 }
338 
339 
340 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant1) {
341  Reduction reduction =
342  Reduce(graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
343  NumberConstant(-base::OS::nan_value())));
344  ASSERT_TRUE(reduction.Changed());
345  EXPECT_THAT(reduction.replacement(), IsFloat64Constant(IsNaN()));
346 }
347 
348 
349 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant2) {
350  Reduction reduction =
351  Reduce(graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
352  NumberConstant(base::OS::nan_value())));
353  ASSERT_TRUE(reduction.Changed());
354  EXPECT_THAT(reduction.replacement(), IsFloat64Constant(IsNaN()));
355 }
356 
357 
358 // -----------------------------------------------------------------------------
359 // ChangeTaggedToInt32
360 
361 
363  ChangeTaggedToInt32WithChangeFloat64ToTagged) {
364  Node* param0 = Parameter(0);
365  Reduction reduction = Reduce(graph()->NewNode(
366  simplified()->ChangeTaggedToInt32(),
367  graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
368  ASSERT_TRUE(reduction.Changed());
369  EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToInt32(param0));
370 }
371 
372 
374  ChangeTaggedToInt32WithChangeInt32ToTagged) {
375  Node* param0 = Parameter(0);
376  Reduction reduction = Reduce(graph()->NewNode(
377  simplified()->ChangeTaggedToInt32(),
378  graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
379  ASSERT_TRUE(reduction.Changed());
380  EXPECT_EQ(param0, reduction.replacement());
381 }
382 
383 
384 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithConstant) {
385  TRACED_FOREACH(double, n, kFloat64Values) {
386  Reduction reduction = Reduce(graph()->NewNode(
387  simplified()->ChangeTaggedToInt32(), NumberConstant(n)));
388  ASSERT_TRUE(reduction.Changed());
389  EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(n)));
390  }
391 }
392 
393 
394 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithNaNConstant1) {
395  Reduction reduction =
396  Reduce(graph()->NewNode(simplified()->ChangeTaggedToInt32(),
397  NumberConstant(-base::OS::nan_value())));
398  ASSERT_TRUE(reduction.Changed());
399  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
400 }
401 
402 
403 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithNaNConstant2) {
404  Reduction reduction =
405  Reduce(graph()->NewNode(simplified()->ChangeTaggedToInt32(),
406  NumberConstant(base::OS::nan_value())));
407  ASSERT_TRUE(reduction.Changed());
408  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
409 }
410 
411 
412 // -----------------------------------------------------------------------------
413 // ChangeTaggedToUint32
414 
415 
417  ChangeTaggedToUint32WithChangeFloat64ToTagged) {
418  Node* param0 = Parameter(0);
419  Reduction reduction = Reduce(graph()->NewNode(
420  simplified()->ChangeTaggedToUint32(),
421  graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
422  ASSERT_TRUE(reduction.Changed());
423  EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToUint32(param0));
424 }
425 
426 
428  ChangeTaggedToUint32WithChangeUint32ToTagged) {
429  Node* param0 = Parameter(0);
430  Reduction reduction = Reduce(graph()->NewNode(
431  simplified()->ChangeTaggedToUint32(),
432  graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
433  ASSERT_TRUE(reduction.Changed());
434  EXPECT_EQ(param0, reduction.replacement());
435 }
436 
437 
438 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithConstant) {
439  TRACED_FOREACH(double, n, kFloat64Values) {
440  Reduction reduction = Reduce(graph()->NewNode(
441  simplified()->ChangeTaggedToUint32(), NumberConstant(n)));
442  ASSERT_TRUE(reduction.Changed());
443  EXPECT_THAT(reduction.replacement(),
444  IsInt32Constant(bit_cast<int32_t>(DoubleToUint32(n))));
445  }
446 }
447 
448 
449 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithNaNConstant1) {
450  Reduction reduction =
451  Reduce(graph()->NewNode(simplified()->ChangeTaggedToUint32(),
452  NumberConstant(-base::OS::nan_value())));
453  ASSERT_TRUE(reduction.Changed());
454  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
455 }
456 
457 
458 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithNaNConstant2) {
459  Reduction reduction =
460  Reduce(graph()->NewNode(simplified()->ChangeTaggedToUint32(),
461  NumberConstant(base::OS::nan_value())));
462  ASSERT_TRUE(reduction.Changed());
463  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
464 }
465 
466 
467 // -----------------------------------------------------------------------------
468 // ChangeUint32ToTagged
469 
470 
471 TEST_F(SimplifiedOperatorReducerTest, ChangeUint32ToTagged) {
472  TRACED_FOREACH(uint32_t, n, kUint32Values) {
473  Reduction reduction =
474  Reduce(graph()->NewNode(simplified()->ChangeUint32ToTagged(),
475  Int32Constant(bit_cast<int32_t>(n))));
476  ASSERT_TRUE(reduction.Changed());
477  EXPECT_THAT(reduction.replacement(), IsNumberConstant(FastUI2D(n)));
478  }
479 }
480 
481 } // namespace compiler
482 } // namespace internal
483 } // namespace v8
static double nan_value()
CommonOperatorBuilder * common()
#define V8_INFINITY
Definition: globals.h:25
int int32_t
Definition: unicode.cc:24
Matcher< Node * > IsFloat64Constant(const Matcher< double > &value_matcher)
Matcher< Node * > IsChangeUint32ToFloat64(const Matcher< Node * > &input_matcher)
std::ostream & operator<<(std::ostream &os, const MachineType &type)
Matcher< Node * > IsNumberConstant(const Matcher< double > &value_matcher)
Matcher< Node * > IsChangeInt32ToFloat64(const Matcher< Node * > &input_matcher)
Matcher< Node * > IsInt32Constant(const Matcher< int32_t > &value_matcher)
TEST_P(InstructionSelectorDPITest, Parameters)
INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest, ::testing::ValuesIn(kDPIs))
Matcher< Node * > IsChangeFloat64ToUint32(const Matcher< Node * > &input_matcher)
SimplifiedOperatorReducerTestWithParam< UnaryOperator > SimplifiedUnaryOperatorTest
TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter)
Matcher< Node * > IsChangeFloat64ToInt32(const Matcher< Node * > &input_matcher)
uint32_t DoubleToUint32(double x)
Definition: conversions.h:93
double FastI2D(int x)
Definition: conversions.h:64
int32_t DoubleToInt32(double x)
double FastUI2D(unsigned x)
Definition: conversions.h:72
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20