V8 Project
machine-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 
5 #include "src/base/bits.h"
9 #include "src/compiler/typer.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14 
16  public:
17  explicit MachineOperatorReducerTest(int num_parameters = 2)
18  : GraphTest(num_parameters) {}
19 
20  protected:
21  Reduction Reduce(Node* node) {
22  Typer typer(zone());
23  JSOperatorBuilder javascript(zone());
24  JSGraph jsgraph(graph(), common(), &javascript, &typer, &machine_);
25  MachineOperatorReducer reducer(&jsgraph);
26  return reducer.Reduce(node);
27  }
28 
29  MachineOperatorBuilder* machine() { return &machine_; }
30 
31  private:
32  MachineOperatorBuilder machine_;
33 };
34 
35 
36 template <typename T>
39  public ::testing::WithParamInterface<T> {
40  public:
41  explicit MachineOperatorReducerTestWithParam(int num_parameters = 2)
42  : MachineOperatorReducerTest(num_parameters) {}
44 };
45 
46 
47 namespace {
48 
49 static const float kFloat32Values[] = {
50  -std::numeric_limits<float>::infinity(), -2.70497e+38f, -1.4698e+37f,
51  -1.22813e+35f, -1.20555e+35f, -1.34584e+34f,
52  -1.0079e+32f, -6.49364e+26f, -3.06077e+25f,
53  -1.46821e+25f, -1.17658e+23f, -1.9617e+22f,
54  -2.7357e+20f, -1.48708e+13f, -1.89633e+12f,
55  -4.66622e+11f, -2.22581e+11f, -1.45381e+10f,
56  -1.3956e+09f, -1.32951e+09f, -1.30721e+09f,
57  -1.19756e+09f, -9.26822e+08f, -6.35647e+08f,
58  -4.00037e+08f, -1.81227e+08f, -5.09256e+07f,
59  -964300.0f, -192446.0f, -28455.0f,
60  -27194.0f, -26401.0f, -20575.0f,
61  -17069.0f, -9167.0f, -960.178f,
62  -113.0f, -62.0f, -15.0f,
63  -7.0f, -0.0256635f, -4.60374e-07f,
64  -3.63759e-10f, -4.30175e-14f, -5.27385e-15f,
65  -1.48084e-15f, -1.05755e-19f, -3.2995e-21f,
66  -1.67354e-23f, -1.11885e-23f, -1.78506e-30f,
67  -5.07594e-31f, -3.65799e-31f, -1.43718e-34f,
68  -1.27126e-38f, -0.0f, 0.0f,
69  1.17549e-38f, 1.56657e-37f, 4.08512e-29f,
70  3.31357e-28f, 6.25073e-22f, 4.1723e-13f,
71  1.44343e-09f, 5.27004e-08f, 9.48298e-08f,
72  5.57888e-07f, 4.89988e-05f, 0.244326f,
73  12.4895f, 19.0f, 47.0f,
74  106.0f, 538.324f, 564.536f,
75  819.124f, 7048.0f, 12611.0f,
76  19878.0f, 20309.0f, 797056.0f,
77  1.77219e+09f, 1.51116e+11f, 4.18193e+13f,
78  3.59167e+16f, 3.38211e+19f, 2.67488e+20f,
79  1.78831e+21f, 9.20914e+21f, 8.35654e+23f,
80  1.4495e+24f, 5.94015e+25f, 4.43608e+30f,
81  2.44502e+33f, 2.61152e+33f, 1.38178e+37f,
82  1.71306e+37f, 3.31899e+38f, 3.40282e+38f,
83  std::numeric_limits<float>::infinity()};
84 
85 
86 static const double kFloat64Values[] = {
87  -V8_INFINITY, -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212,
88  -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100,
89  -1.67813e+72, -2.3382e+55, -3.179e+30, -1.441e+09, -1.0647e+09,
90  -7.99361e+08, -5.77375e+08, -2.20984e+08, -32757, -13171,
91  -9970, -3984, -107, -105, -92,
92  -77, -61, -0.000208163, -1.86685e-06, -1.17296e-10,
93  -9.26358e-11, -5.08004e-60, -1.74753e-65, -1.06561e-71, -5.67879e-79,
94  -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
95  -4.40497e-267, -2.19666e-273, -4.9998e-276, -5.59821e-278, -2.03855e-282,
96  -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0, 0.0,
97  2.22507e-308, 1.30127e-270, 7.62898e-260, 4.00313e-249, 3.16829e-233,
98  1.85244e-228, 2.03544e-129, 1.35126e-110, 1.01182e-106, 5.26333e-94,
99  1.35292e-90, 2.85394e-83, 1.78323e-77, 5.4967e-57, 1.03207e-25,
100  4.57401e-25, 1.58738e-05, 2, 125, 2310,
101  9636, 14802, 17168, 28945, 29305,
102  4.81336e+07, 1.41207e+08, 4.65962e+08, 1.40499e+09, 2.12648e+09,
103  8.80006e+30, 1.4446e+45, 1.12164e+54, 2.48188e+89, 6.71121e+102,
104  3.074e+112, 4.9699e+152, 5.58383e+166, 4.30654e+172, 7.08824e+185,
105  9.6586e+214, 2.028e+223, 6.63277e+243, 1.56192e+261, 1.23202e+269,
106  5.72883e+289, 8.5798e+290, 1.40256e+294, 1.79769e+308, V8_INFINITY};
107 
108 
109 static const int32_t kInt32Values[] = {
110  -2147483647 - 1, -1914954528, -1698749618, -1578693386, -1577976073,
111  -1573998034, -1529085059, -1499540537, -1299205097, -1090814845,
112  -938186388, -806828902, -750927650, -520676892, -513661538,
113  -453036354, -433622833, -282638793, -28375, -27788,
114  -22770, -18806, -14173, -11956, -11200,
115  -10212, -8160, -3751, -2758, -1522,
116  -121, -120, -118, -117, -106,
117  -84, -80, -74, -59, -52,
118  -48, -39, -35, -17, -11,
119  -10, -9, -7, -5, 0,
120  9, 12, 17, 23, 29,
121  31, 33, 35, 40, 47,
122  55, 56, 62, 64, 67,
123  68, 69, 74, 79, 84,
124  89, 90, 97, 104, 118,
125  124, 126, 127, 7278, 17787,
126  24136, 24202, 25570, 26680, 30242,
127  32399, 420886487, 642166225, 821912648, 822577803,
128  851385718, 1212241078, 1411419304, 1589626102, 1596437184,
129  1876245816, 1954730266, 2008792749, 2045320228, 2147483647};
130 
131 
132 static const int64_t kInt64Values[] = {
133  V8_INT64_C(-9223372036854775807) - 1, V8_INT64_C(-8974392461363618006),
134  V8_INT64_C(-8874367046689588135), V8_INT64_C(-8269197512118230839),
135  V8_INT64_C(-8146091527100606733), V8_INT64_C(-7550917981466150848),
136  V8_INT64_C(-7216590251577894337), V8_INT64_C(-6464086891160048440),
137  V8_INT64_C(-6365616494908257190), V8_INT64_C(-6305630541365849726),
138  V8_INT64_C(-5982222642272245453), V8_INT64_C(-5510103099058504169),
139  V8_INT64_C(-5496838675802432701), V8_INT64_C(-4047626578868642657),
140  V8_INT64_C(-4033755046900164544), V8_INT64_C(-3554299241457877041),
141  V8_INT64_C(-2482258764588614470), V8_INT64_C(-1688515425526875335),
142  V8_INT64_C(-924784137176548532), V8_INT64_C(-725316567157391307),
143  V8_INT64_C(-439022654781092241), V8_INT64_C(-105545757668917080),
144  V8_INT64_C(-2088319373), V8_INT64_C(-2073699916),
145  V8_INT64_C(-1844949911), V8_INT64_C(-1831090548),
146  V8_INT64_C(-1756711933), V8_INT64_C(-1559409497),
147  V8_INT64_C(-1281179700), V8_INT64_C(-1211513985),
148  V8_INT64_C(-1182371520), V8_INT64_C(-785934753),
149  V8_INT64_C(-767480697), V8_INT64_C(-705745662),
150  V8_INT64_C(-514362436), V8_INT64_C(-459916580),
151  V8_INT64_C(-312328082), V8_INT64_C(-302949707),
152  V8_INT64_C(-285499304), V8_INT64_C(-125701262),
153  V8_INT64_C(-95139843), V8_INT64_C(-32768),
154  V8_INT64_C(-27542), V8_INT64_C(-23600),
155  V8_INT64_C(-18582), V8_INT64_C(-17770),
156  V8_INT64_C(-9086), V8_INT64_C(-9010),
157  V8_INT64_C(-8244), V8_INT64_C(-2890),
158  V8_INT64_C(-103), V8_INT64_C(-34),
159  V8_INT64_C(-27), V8_INT64_C(-25),
160  V8_INT64_C(-9), V8_INT64_C(-7),
161  V8_INT64_C(0), V8_INT64_C(2),
162  V8_INT64_C(38), V8_INT64_C(58),
163  V8_INT64_C(65), V8_INT64_C(93),
164  V8_INT64_C(111), V8_INT64_C(1003),
165  V8_INT64_C(1267), V8_INT64_C(12797),
166  V8_INT64_C(23122), V8_INT64_C(28200),
167  V8_INT64_C(30888), V8_INT64_C(42648848),
168  V8_INT64_C(116836693), V8_INT64_C(263003643),
169  V8_INT64_C(571039860), V8_INT64_C(1079398689),
170  V8_INT64_C(1145196402), V8_INT64_C(1184846321),
171  V8_INT64_C(1758281648), V8_INT64_C(1859991374),
172  V8_INT64_C(1960251588), V8_INT64_C(2042443199),
173  V8_INT64_C(296220586027987448), V8_INT64_C(1015494173071134726),
174  V8_INT64_C(1151237951914455318), V8_INT64_C(1331941174616854174),
175  V8_INT64_C(2022020418667972654), V8_INT64_C(2450251424374977035),
176  V8_INT64_C(3668393562685561486), V8_INT64_C(4858229301215502171),
177  V8_INT64_C(4919426235170669383), V8_INT64_C(5034286595330341762),
178  V8_INT64_C(5055797915536941182), V8_INT64_C(6072389716149252074),
179  V8_INT64_C(6185309910199801210), V8_INT64_C(6297328311011094138),
180  V8_INT64_C(6932372858072165827), V8_INT64_C(8483640924987737210),
181  V8_INT64_C(8663764179455849203), V8_INT64_C(8877197042645298254),
182  V8_INT64_C(8901543506779157333), V8_INT64_C(9223372036854775807)};
183 
184 
185 static const uint32_t kUint32Values[] = {
186  0x00000000, 0x00000001, 0xffffffff, 0x1b09788b, 0x04c5fce8, 0xcc0de5bf,
187  0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
188  0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
189  0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
190  0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000,
191  0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
192  0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff,
193  0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff};
194 
195 } // namespace
196 
197 
198 // -----------------------------------------------------------------------------
199 // Unary operators
200 
201 
202 namespace {
203 
205  const Operator* (MachineOperatorBuilder::*constructor)();
206  const char* constructor_name;
207 };
208 
209 
210 std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
211  return os << unop.constructor_name;
212 }
213 
214 
215 static const UnaryOperator kUnaryOperators[] = {
216  {&MachineOperatorBuilder::ChangeInt32ToFloat64, "ChangeInt32ToFloat64"},
217  {&MachineOperatorBuilder::ChangeUint32ToFloat64, "ChangeUint32ToFloat64"},
218  {&MachineOperatorBuilder::ChangeFloat64ToInt32, "ChangeFloat64ToInt32"},
219  {&MachineOperatorBuilder::ChangeFloat64ToUint32, "ChangeFloat64ToUint32"},
220  {&MachineOperatorBuilder::ChangeInt32ToInt64, "ChangeInt32ToInt64"},
221  {&MachineOperatorBuilder::ChangeUint32ToUint64, "ChangeUint32ToUint64"},
222  {&MachineOperatorBuilder::TruncateFloat64ToInt32, "TruncateFloat64ToInt32"},
223  {&MachineOperatorBuilder::TruncateInt64ToInt32, "TruncateInt64ToInt32"}};
224 
225 } // namespace
226 
227 
228 typedef MachineOperatorReducerTestWithParam<UnaryOperator>
230 
231 
233  const UnaryOperator unop = GetParam();
234  Reduction reduction =
235  Reduce(graph()->NewNode((machine()->*unop.constructor)(), Parameter(0)));
236  EXPECT_FALSE(reduction.Changed());
237 }
238 
239 
242  ::testing::ValuesIn(kUnaryOperators));
243 
244 
245 // -----------------------------------------------------------------------------
246 // ChangeFloat64ToFloat32
247 
248 
249 TEST_F(MachineOperatorReducerTest, ChangeFloat64ToFloat32WithConstant) {
250  TRACED_FOREACH(float, x, kFloat32Values) {
251  Reduction reduction = Reduce(graph()->NewNode(
252  machine()->ChangeFloat32ToFloat64(), Float32Constant(x)));
253  ASSERT_TRUE(reduction.Changed());
254  EXPECT_THAT(reduction.replacement(), IsFloat64Constant(x));
255  }
256 }
257 
258 
259 // -----------------------------------------------------------------------------
260 // ChangeFloat64ToInt32
261 
262 
264  ChangeFloat64ToInt32WithChangeInt32ToFloat64) {
265  Node* value = Parameter(0);
266  Reduction reduction = Reduce(graph()->NewNode(
267  machine()->ChangeFloat64ToInt32(),
268  graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
269  ASSERT_TRUE(reduction.Changed());
270  EXPECT_EQ(value, reduction.replacement());
271 }
272 
273 
274 TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt32WithConstant) {
275  TRACED_FOREACH(int32_t, x, kInt32Values) {
276  Reduction reduction = Reduce(graph()->NewNode(
277  machine()->ChangeFloat64ToInt32(), Float64Constant(FastI2D(x))));
278  ASSERT_TRUE(reduction.Changed());
279  EXPECT_THAT(reduction.replacement(), IsInt32Constant(x));
280  }
281 }
282 
283 
284 // -----------------------------------------------------------------------------
285 // ChangeFloat64ToUint32
286 
287 
289  ChangeFloat64ToUint32WithChangeUint32ToFloat64) {
290  Node* value = Parameter(0);
291  Reduction reduction = Reduce(graph()->NewNode(
292  machine()->ChangeFloat64ToUint32(),
293  graph()->NewNode(machine()->ChangeUint32ToFloat64(), value)));
294  ASSERT_TRUE(reduction.Changed());
295  EXPECT_EQ(value, reduction.replacement());
296 }
297 
298 
299 TEST_F(MachineOperatorReducerTest, ChangeFloat64ToUint32WithConstant) {
300  TRACED_FOREACH(uint32_t, x, kUint32Values) {
301  Reduction reduction = Reduce(graph()->NewNode(
302  machine()->ChangeFloat64ToUint32(), Float64Constant(FastUI2D(x))));
303  ASSERT_TRUE(reduction.Changed());
304  EXPECT_THAT(reduction.replacement(), IsInt32Constant(bit_cast<int32_t>(x)));
305  }
306 }
307 
308 
309 // -----------------------------------------------------------------------------
310 // ChangeInt32ToFloat64
311 
312 
313 TEST_F(MachineOperatorReducerTest, ChangeInt32ToFloat64WithConstant) {
314  TRACED_FOREACH(int32_t, x, kInt32Values) {
315  Reduction reduction = Reduce(
316  graph()->NewNode(machine()->ChangeInt32ToFloat64(), Int32Constant(x)));
317  ASSERT_TRUE(reduction.Changed());
318  EXPECT_THAT(reduction.replacement(), IsFloat64Constant(FastI2D(x)));
319  }
320 }
321 
322 
323 // -----------------------------------------------------------------------------
324 // ChangeInt32ToInt64
325 
326 
327 TEST_F(MachineOperatorReducerTest, ChangeInt32ToInt64WithConstant) {
328  TRACED_FOREACH(int32_t, x, kInt32Values) {
329  Reduction reduction = Reduce(
330  graph()->NewNode(machine()->ChangeInt32ToInt64(), Int32Constant(x)));
331  ASSERT_TRUE(reduction.Changed());
332  EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
333  }
334 }
335 
336 
337 // -----------------------------------------------------------------------------
338 // ChangeUint32ToFloat64
339 
340 
341 TEST_F(MachineOperatorReducerTest, ChangeUint32ToFloat64WithConstant) {
342  TRACED_FOREACH(uint32_t, x, kUint32Values) {
343  Reduction reduction =
344  Reduce(graph()->NewNode(machine()->ChangeUint32ToFloat64(),
345  Int32Constant(bit_cast<int32_t>(x))));
346  ASSERT_TRUE(reduction.Changed());
347  EXPECT_THAT(reduction.replacement(), IsFloat64Constant(FastUI2D(x)));
348  }
349 }
350 
351 
352 // -----------------------------------------------------------------------------
353 // ChangeUint32ToUint64
354 
355 
356 TEST_F(MachineOperatorReducerTest, ChangeUint32ToUint64WithConstant) {
357  TRACED_FOREACH(uint32_t, x, kUint32Values) {
358  Reduction reduction =
359  Reduce(graph()->NewNode(machine()->ChangeUint32ToUint64(),
360  Int32Constant(bit_cast<int32_t>(x))));
361  ASSERT_TRUE(reduction.Changed());
362  EXPECT_THAT(reduction.replacement(),
363  IsInt64Constant(bit_cast<int64_t>(static_cast<uint64_t>(x))));
364  }
365 }
366 
367 
368 // -----------------------------------------------------------------------------
369 // TruncateFloat64ToFloat32
370 
371 
373  TruncateFloat64ToFloat32WithChangeFloat32ToFloat64) {
374  Node* value = Parameter(0);
375  Reduction reduction = Reduce(graph()->NewNode(
376  machine()->TruncateFloat64ToFloat32(),
377  graph()->NewNode(machine()->ChangeFloat32ToFloat64(), value)));
378  ASSERT_TRUE(reduction.Changed());
379  EXPECT_EQ(value, reduction.replacement());
380 }
381 
382 
383 TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
384  TRACED_FOREACH(double, x, kFloat64Values) {
385  Reduction reduction = Reduce(graph()->NewNode(
386  machine()->TruncateFloat64ToFloat32(), Float64Constant(x)));
387  ASSERT_TRUE(reduction.Changed());
388  EXPECT_THAT(reduction.replacement(), IsFloat32Constant(DoubleToFloat32(x)));
389  }
390 }
391 
392 
393 // -----------------------------------------------------------------------------
394 // TruncateFloat64ToInt32
395 
396 
398  TruncateFloat64ToInt32WithChangeInt32ToFloat64) {
399  Node* value = Parameter(0);
400  Reduction reduction = Reduce(graph()->NewNode(
401  machine()->TruncateFloat64ToInt32(),
402  graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
403  ASSERT_TRUE(reduction.Changed());
404  EXPECT_EQ(value, reduction.replacement());
405 }
406 
407 
408 TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithConstant) {
409  TRACED_FOREACH(double, x, kFloat64Values) {
410  Reduction reduction = Reduce(graph()->NewNode(
411  machine()->TruncateFloat64ToInt32(), Float64Constant(x)));
412  ASSERT_TRUE(reduction.Changed());
413  EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
414  }
415 }
416 
417 
418 // -----------------------------------------------------------------------------
419 // TruncateInt64ToInt32
420 
421 
422 TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithChangeInt32ToInt64) {
423  Node* value = Parameter(0);
424  Reduction reduction = Reduce(graph()->NewNode(
425  machine()->TruncateInt64ToInt32(),
426  graph()->NewNode(machine()->ChangeInt32ToInt64(), value)));
427  ASSERT_TRUE(reduction.Changed());
428  EXPECT_EQ(value, reduction.replacement());
429 }
430 
431 
432 TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithConstant) {
433  TRACED_FOREACH(int64_t, x, kInt64Values) {
434  Reduction reduction = Reduce(
435  graph()->NewNode(machine()->TruncateInt64ToInt32(), Int64Constant(x)));
436  ASSERT_TRUE(reduction.Changed());
437  EXPECT_THAT(reduction.replacement(),
438  IsInt32Constant(bit_cast<int32_t>(
439  static_cast<uint32_t>(bit_cast<uint64_t>(x)))));
440  }
441 }
442 
443 
444 // -----------------------------------------------------------------------------
445 // Word32Ror
446 
447 
448 TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
449  Node* value = Parameter(0);
450  Node* shift = Parameter(1);
451  Node* shl = graph()->NewNode(machine()->Word32Shl(), value, shift);
452  Node* shr = graph()->NewNode(
453  machine()->Word32Shr(), value,
454  graph()->NewNode(machine()->Int32Sub(), Int32Constant(32), shift));
455 
456  // (x << y) | (x >> (32 - y)) => x ror y
457  Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
458  Reduction reduction1 = Reduce(node1);
459  EXPECT_TRUE(reduction1.Changed());
460  EXPECT_EQ(reduction1.replacement(), node1);
461  EXPECT_THAT(reduction1.replacement(), IsWord32Ror(value, shift));
462 
463  // (x >> (32 - y)) | (x << y) => x ror y
464  Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
465  Reduction reduction2 = Reduce(node2);
466  EXPECT_TRUE(reduction2.Changed());
467  EXPECT_EQ(reduction2.replacement(), node2);
468  EXPECT_THAT(reduction2.replacement(), IsWord32Ror(value, shift));
469 }
470 
471 
472 TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
473  Node* value = Parameter(0);
474  TRACED_FORRANGE(int32_t, k, 0, 31) {
475  Node* shl =
476  graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(k));
477  Node* shr =
478  graph()->NewNode(machine()->Word32Shr(), value, Int32Constant(32 - k));
479 
480  // (x << K) | (x >> ((32 - K) - y)) => x ror K
481  Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
482  Reduction reduction1 = Reduce(node1);
483  EXPECT_TRUE(reduction1.Changed());
484  EXPECT_EQ(reduction1.replacement(), node1);
485  EXPECT_THAT(reduction1.replacement(),
486  IsWord32Ror(value, IsInt32Constant(k)));
487 
488  // (x >> (32 - K)) | (x << K) => x ror K
489  Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
490  Reduction reduction2 = Reduce(node2);
491  EXPECT_TRUE(reduction2.Changed());
492  EXPECT_EQ(reduction2.replacement(), node2);
493  EXPECT_THAT(reduction2.replacement(),
494  IsWord32Ror(value, IsInt32Constant(k)));
495  }
496 }
497 
498 
499 TEST_F(MachineOperatorReducerTest, Word32RorWithZeroShift) {
500  Node* value = Parameter(0);
501  Node* node =
502  graph()->NewNode(machine()->Word32Ror(), value, Int32Constant(0));
503  Reduction reduction = Reduce(node);
504  EXPECT_TRUE(reduction.Changed());
505  EXPECT_EQ(reduction.replacement(), value);
506 }
507 
508 
509 TEST_F(MachineOperatorReducerTest, Word32RorWithConstants) {
510  TRACED_FOREACH(int32_t, x, kUint32Values) {
511  TRACED_FORRANGE(int32_t, y, 0, 31) {
512  Node* node = graph()->NewNode(machine()->Word32Ror(), Int32Constant(x),
513  Int32Constant(y));
514  Reduction reduction = Reduce(node);
515  EXPECT_TRUE(reduction.Changed());
516  EXPECT_THAT(reduction.replacement(),
518  }
519  }
520 }
521 
522 
523 // -----------------------------------------------------------------------------
524 // Word32Shl
525 
526 
527 TEST_F(MachineOperatorReducerTest, Word32ShlWithZeroShift) {
528  Node* p0 = Parameter(0);
529  Node* node = graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(0));
530  Reduction r = Reduce(node);
531  ASSERT_TRUE(r.Changed());
532  EXPECT_EQ(p0, r.replacement());
533 }
534 
535 
536 TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Sar) {
537  Node* p0 = Parameter(0);
538  TRACED_FORRANGE(int32_t, x, 1, 31) {
539  Node* node = graph()->NewNode(
540  machine()->Word32Shl(),
541  graph()->NewNode(machine()->Word32Sar(), p0, Int32Constant(x)),
542  Int32Constant(x));
543  Reduction r = Reduce(node);
544  ASSERT_TRUE(r.Changed());
545  int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
546  EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
547  }
548 }
549 
550 
551 TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Shr) {
552  Node* p0 = Parameter(0);
553  TRACED_FORRANGE(int32_t, x, 1, 31) {
554  Node* node = graph()->NewNode(
555  machine()->Word32Shl(),
556  graph()->NewNode(machine()->Word32Shr(), p0, Int32Constant(x)),
557  Int32Constant(x));
558  Reduction r = Reduce(node);
559  ASSERT_TRUE(r.Changed());
560  int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
561  EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
562  }
563 }
564 
565 
566 // -----------------------------------------------------------------------------
567 // Int32AddWithOverflow
568 
569 
570 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
571  Node* p0 = Parameter(0);
572  {
573  Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
574  Int32Constant(0), p0);
575 
576  Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
577  ASSERT_TRUE(r.Changed());
578  EXPECT_THAT(r.replacement(), IsInt32Constant(0));
579 
580  r = Reduce(graph()->NewNode(common()->Projection(0), add));
581  ASSERT_TRUE(r.Changed());
582  EXPECT_EQ(p0, r.replacement());
583  }
584  {
585  Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
586  Int32Constant(0));
587 
588  Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
589  ASSERT_TRUE(r.Changed());
590  EXPECT_THAT(r.replacement(), IsInt32Constant(0));
591 
592  r = Reduce(graph()->NewNode(common()->Projection(0), add));
593  ASSERT_TRUE(r.Changed());
594  EXPECT_EQ(p0, r.replacement());
595  }
596 }
597 
598 
599 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
600  TRACED_FOREACH(int32_t, x, kInt32Values) {
601  TRACED_FOREACH(int32_t, y, kInt32Values) {
602  int32_t z;
603  Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
604  Int32Constant(x), Int32Constant(y));
605 
606  Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
607  ASSERT_TRUE(r.Changed());
608  EXPECT_THAT(r.replacement(),
610 
611  r = Reduce(graph()->NewNode(common()->Projection(0), add));
612  ASSERT_TRUE(r.Changed());
613  EXPECT_THAT(r.replacement(), IsInt32Constant(z));
614  }
615  }
616 }
617 
618 
619 // -----------------------------------------------------------------------------
620 // Int32SubWithOverflow
621 
622 
623 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
624  Node* p0 = Parameter(0);
625  Node* add =
626  graph()->NewNode(machine()->Int32SubWithOverflow(), p0, Int32Constant(0));
627 
628  Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
629  ASSERT_TRUE(r.Changed());
630  EXPECT_THAT(r.replacement(), IsInt32Constant(0));
631 
632  r = Reduce(graph()->NewNode(common()->Projection(0), add));
633  ASSERT_TRUE(r.Changed());
634  EXPECT_EQ(p0, r.replacement());
635 }
636 
637 
638 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
639  TRACED_FOREACH(int32_t, x, kInt32Values) {
640  TRACED_FOREACH(int32_t, y, kInt32Values) {
641  int32_t z;
642  Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
643  Int32Constant(x), Int32Constant(y));
644 
645  Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
646  ASSERT_TRUE(r.Changed());
647  EXPECT_THAT(r.replacement(),
649 
650  r = Reduce(graph()->NewNode(common()->Projection(0), add));
651  ASSERT_TRUE(r.Changed());
652  EXPECT_THAT(r.replacement(), IsInt32Constant(z));
653  }
654  }
655 }
656 
657 } // namespace compiler
658 } // namespace internal
659 } // namespace v8
CommonOperatorBuilder * common()
enable harmony numeric enable harmony object literal extensions Optimize object Array shift
#define V8_INFINITY
Definition: globals.h:25
#define V8_INT64_C(x)
Definition: macros.h:358
int int32_t
Definition: unicode.cc:24
uint32_t RotateRight32(uint32_t value, uint32_t shift)
Definition: bits.h:107
bool SignedAddOverflow32(int32_t lhs, int32_t rhs, int32_t *val)
Definition: bits.h:122
bool SignedSubOverflow32(int32_t lhs, int32_t rhs, int32_t *val)
Definition: bits.h:136
Matcher< Node * > IsFloat64Constant(const Matcher< double > &value_matcher)
Matcher< Node * > IsInt64Constant(const Matcher< int64_t > &value_matcher)
MachineOperatorReducerTestWithParam< UnaryOperator > MachineUnaryOperatorReducerTest
std::ostream & operator<<(std::ostream &os, const MachineType &type)
Matcher< Node * > IsFloat32Constant(const Matcher< float > &value_matcher)
Matcher< Node * > IsWord32Ror(const Matcher< Node * > &lhs_matcher, const Matcher< Node * > &rhs_matcher)
Matcher< Node * > IsInt32Constant(const Matcher< int32_t > &value_matcher)
Matcher< Node * > IsWord32And(const Matcher< Node * > &lhs_matcher, const Matcher< Node * > &rhs_matcher)
TEST_P(InstructionSelectorDPITest, Parameters)
INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest, ::testing::ValuesIn(kDPIs))
TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter)
double FastI2D(int x)
Definition: conversions.h:64
int32_t DoubleToInt32(double x)
float DoubleToFloat32(double x)
double FastUI2D(unsigned x)
Definition: conversions.h:72
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20