deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / test / unittests / compiler / machine-operator-reducer-unittest.cc
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"
6 #include "src/base/division-by-constant.h"
7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/machine-operator-reducer.h"
9 #include "src/compiler/typer.h"
10 #include "test/unittests/compiler/graph-unittest.h"
11 #include "test/unittests/compiler/node-test-utils.h"
12 #include "testing/gmock-support.h"
13
14 using testing::AllOf;
15 using testing::BitEq;
16 using testing::Capture;
17 using testing::CaptureEq;
18
19 namespace v8 {
20 namespace internal {
21 namespace compiler {
22
23 class MachineOperatorReducerTest : public TypedGraphTest {
24  public:
25   explicit MachineOperatorReducerTest(int num_parameters = 2)
26       : TypedGraphTest(num_parameters), machine_(zone()) {}
27
28  protected:
29   Reduction Reduce(Node* node) {
30     JSOperatorBuilder javascript(zone());
31     JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine_);
32     MachineOperatorReducer reducer(&jsgraph);
33     return reducer.Reduce(node);
34   }
35
36   Matcher<Node*> IsTruncatingDiv(const Matcher<Node*>& dividend_matcher,
37                                  const int32_t divisor) {
38     base::MagicNumbersForDivision<uint32_t> const mag =
39         base::SignedDivisionByConstant(bit_cast<uint32_t>(divisor));
40     int32_t const multiplier = bit_cast<int32_t>(mag.multiplier);
41     int32_t const shift = bit_cast<int32_t>(mag.shift);
42     Matcher<Node*> quotient_matcher =
43         IsInt32MulHigh(dividend_matcher, IsInt32Constant(multiplier));
44     if (divisor > 0 && multiplier < 0) {
45       quotient_matcher = IsInt32Add(quotient_matcher, dividend_matcher);
46     } else if (divisor < 0 && multiplier > 0) {
47       quotient_matcher = IsInt32Sub(quotient_matcher, dividend_matcher);
48     }
49     if (shift) {
50       quotient_matcher = IsWord32Sar(quotient_matcher, IsInt32Constant(shift));
51     }
52     return IsInt32Add(quotient_matcher,
53                       IsWord32Shr(dividend_matcher, IsInt32Constant(31)));
54   }
55
56   MachineOperatorBuilder* machine() { return &machine_; }
57
58  private:
59   MachineOperatorBuilder machine_;
60 };
61
62
63 template <typename T>
64 class MachineOperatorReducerTestWithParam
65     : public MachineOperatorReducerTest,
66       public ::testing::WithParamInterface<T> {
67  public:
68   explicit MachineOperatorReducerTestWithParam(int num_parameters = 2)
69       : MachineOperatorReducerTest(num_parameters) {}
70   ~MachineOperatorReducerTestWithParam() OVERRIDE {}
71 };
72
73
74 namespace {
75
76 const float kFloat32Values[] = {
77     -std::numeric_limits<float>::infinity(), -2.70497e+38f, -1.4698e+37f,
78     -1.22813e+35f,                           -1.20555e+35f, -1.34584e+34f,
79     -1.0079e+32f,                            -6.49364e+26f, -3.06077e+25f,
80     -1.46821e+25f,                           -1.17658e+23f, -1.9617e+22f,
81     -2.7357e+20f,                            -1.48708e+13f, -1.89633e+12f,
82     -4.66622e+11f,                           -2.22581e+11f, -1.45381e+10f,
83     -1.3956e+09f,                            -1.32951e+09f, -1.30721e+09f,
84     -1.19756e+09f,                           -9.26822e+08f, -6.35647e+08f,
85     -4.00037e+08f,                           -1.81227e+08f, -5.09256e+07f,
86     -964300.0f,                              -192446.0f,    -28455.0f,
87     -27194.0f,                               -26401.0f,     -20575.0f,
88     -17069.0f,                               -9167.0f,      -960.178f,
89     -113.0f,                                 -62.0f,        -15.0f,
90     -7.0f,                                   -0.0256635f,   -4.60374e-07f,
91     -3.63759e-10f,                           -4.30175e-14f, -5.27385e-15f,
92     -1.48084e-15f,                           -1.05755e-19f, -3.2995e-21f,
93     -1.67354e-23f,                           -1.11885e-23f, -1.78506e-30f,
94     -5.07594e-31f,                           -3.65799e-31f, -1.43718e-34f,
95     -1.27126e-38f,                           -0.0f,         0.0f,
96     1.17549e-38f,                            1.56657e-37f,  4.08512e-29f,
97     3.31357e-28f,                            6.25073e-22f,  4.1723e-13f,
98     1.44343e-09f,                            5.27004e-08f,  9.48298e-08f,
99     5.57888e-07f,                            4.89988e-05f,  0.244326f,
100     12.4895f,                                19.0f,         47.0f,
101     106.0f,                                  538.324f,      564.536f,
102     819.124f,                                7048.0f,       12611.0f,
103     19878.0f,                                20309.0f,      797056.0f,
104     1.77219e+09f,                            1.51116e+11f,  4.18193e+13f,
105     3.59167e+16f,                            3.38211e+19f,  2.67488e+20f,
106     1.78831e+21f,                            9.20914e+21f,  8.35654e+23f,
107     1.4495e+24f,                             5.94015e+25f,  4.43608e+30f,
108     2.44502e+33f,                            2.61152e+33f,  1.38178e+37f,
109     1.71306e+37f,                            3.31899e+38f,  3.40282e+38f,
110     std::numeric_limits<float>::infinity()};
111
112
113 const double kFloat64Values[] = {
114     -V8_INFINITY,  -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212,
115     -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100,
116     -1.67813e+72,  -2.3382e+55,   -3.179e+30,    -1.441e+09,    -1.0647e+09,
117     -7.99361e+08,  -5.77375e+08,  -2.20984e+08,  -32757,        -13171,
118     -9970,         -3984,         -107,          -105,          -92,
119     -77,           -61,           -0.000208163,  -1.86685e-06,  -1.17296e-10,
120     -9.26358e-11,  -5.08004e-60,  -1.74753e-65,  -1.06561e-71,  -5.67879e-79,
121     -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
122     -4.40497e-267, -2.19666e-273, -4.9998e-276,  -5.59821e-278, -2.03855e-282,
123     -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0,          0.0,
124     2.22507e-308,  1.30127e-270,  7.62898e-260,  4.00313e-249,  3.16829e-233,
125     1.85244e-228,  2.03544e-129,  1.35126e-110,  1.01182e-106,  5.26333e-94,
126     1.35292e-90,   2.85394e-83,   1.78323e-77,   5.4967e-57,    1.03207e-25,
127     4.57401e-25,   1.58738e-05,   2,             125,           2310,
128     9636,          14802,         17168,         28945,         29305,
129     4.81336e+07,   1.41207e+08,   4.65962e+08,   1.40499e+09,   2.12648e+09,
130     8.80006e+30,   1.4446e+45,    1.12164e+54,   2.48188e+89,   6.71121e+102,
131     3.074e+112,    4.9699e+152,   5.58383e+166,  4.30654e+172,  7.08824e+185,
132     9.6586e+214,   2.028e+223,    6.63277e+243,  1.56192e+261,  1.23202e+269,
133     5.72883e+289,  8.5798e+290,   1.40256e+294,  1.79769e+308,  V8_INFINITY};
134
135
136 const int32_t kInt32Values[] = {
137     std::numeric_limits<int32_t>::min(), -1914954528, -1698749618,
138     -1578693386,                         -1577976073, -1573998034,
139     -1529085059,                         -1499540537, -1299205097,
140     -1090814845,                         -938186388,  -806828902,
141     -750927650,                          -520676892,  -513661538,
142     -453036354,                          -433622833,  -282638793,
143     -28375,                              -27788,      -22770,
144     -18806,                              -14173,      -11956,
145     -11200,                              -10212,      -8160,
146     -3751,                               -2758,       -1522,
147     -121,                                -120,        -118,
148     -117,                                -106,        -84,
149     -80,                                 -74,         -59,
150     -52,                                 -48,         -39,
151     -35,                                 -17,         -11,
152     -10,                                 -9,          -7,
153     -5,                                  0,           9,
154     12,                                  17,          23,
155     29,                                  31,          33,
156     35,                                  40,          47,
157     55,                                  56,          62,
158     64,                                  67,          68,
159     69,                                  74,          79,
160     84,                                  89,          90,
161     97,                                  104,         118,
162     124,                                 126,         127,
163     7278,                                17787,       24136,
164     24202,                               25570,       26680,
165     30242,                               32399,       420886487,
166     642166225,                           821912648,   822577803,
167     851385718,                           1212241078,  1411419304,
168     1589626102,                          1596437184,  1876245816,
169     1954730266,                          2008792749,  2045320228,
170     std::numeric_limits<int32_t>::max()};
171
172
173 const int64_t kInt64Values[] = {
174     std::numeric_limits<int64_t>::min(), V8_INT64_C(-8974392461363618006),
175     V8_INT64_C(-8874367046689588135),    V8_INT64_C(-8269197512118230839),
176     V8_INT64_C(-8146091527100606733),    V8_INT64_C(-7550917981466150848),
177     V8_INT64_C(-7216590251577894337),    V8_INT64_C(-6464086891160048440),
178     V8_INT64_C(-6365616494908257190),    V8_INT64_C(-6305630541365849726),
179     V8_INT64_C(-5982222642272245453),    V8_INT64_C(-5510103099058504169),
180     V8_INT64_C(-5496838675802432701),    V8_INT64_C(-4047626578868642657),
181     V8_INT64_C(-4033755046900164544),    V8_INT64_C(-3554299241457877041),
182     V8_INT64_C(-2482258764588614470),    V8_INT64_C(-1688515425526875335),
183     V8_INT64_C(-924784137176548532),     V8_INT64_C(-725316567157391307),
184     V8_INT64_C(-439022654781092241),     V8_INT64_C(-105545757668917080),
185     V8_INT64_C(-2088319373),             V8_INT64_C(-2073699916),
186     V8_INT64_C(-1844949911),             V8_INT64_C(-1831090548),
187     V8_INT64_C(-1756711933),             V8_INT64_C(-1559409497),
188     V8_INT64_C(-1281179700),             V8_INT64_C(-1211513985),
189     V8_INT64_C(-1182371520),             V8_INT64_C(-785934753),
190     V8_INT64_C(-767480697),              V8_INT64_C(-705745662),
191     V8_INT64_C(-514362436),              V8_INT64_C(-459916580),
192     V8_INT64_C(-312328082),              V8_INT64_C(-302949707),
193     V8_INT64_C(-285499304),              V8_INT64_C(-125701262),
194     V8_INT64_C(-95139843),               V8_INT64_C(-32768),
195     V8_INT64_C(-27542),                  V8_INT64_C(-23600),
196     V8_INT64_C(-18582),                  V8_INT64_C(-17770),
197     V8_INT64_C(-9086),                   V8_INT64_C(-9010),
198     V8_INT64_C(-8244),                   V8_INT64_C(-2890),
199     V8_INT64_C(-103),                    V8_INT64_C(-34),
200     V8_INT64_C(-27),                     V8_INT64_C(-25),
201     V8_INT64_C(-9),                      V8_INT64_C(-7),
202     V8_INT64_C(0),                       V8_INT64_C(2),
203     V8_INT64_C(38),                      V8_INT64_C(58),
204     V8_INT64_C(65),                      V8_INT64_C(93),
205     V8_INT64_C(111),                     V8_INT64_C(1003),
206     V8_INT64_C(1267),                    V8_INT64_C(12797),
207     V8_INT64_C(23122),                   V8_INT64_C(28200),
208     V8_INT64_C(30888),                   V8_INT64_C(42648848),
209     V8_INT64_C(116836693),               V8_INT64_C(263003643),
210     V8_INT64_C(571039860),               V8_INT64_C(1079398689),
211     V8_INT64_C(1145196402),              V8_INT64_C(1184846321),
212     V8_INT64_C(1758281648),              V8_INT64_C(1859991374),
213     V8_INT64_C(1960251588),              V8_INT64_C(2042443199),
214     V8_INT64_C(296220586027987448),      V8_INT64_C(1015494173071134726),
215     V8_INT64_C(1151237951914455318),     V8_INT64_C(1331941174616854174),
216     V8_INT64_C(2022020418667972654),     V8_INT64_C(2450251424374977035),
217     V8_INT64_C(3668393562685561486),     V8_INT64_C(4858229301215502171),
218     V8_INT64_C(4919426235170669383),     V8_INT64_C(5034286595330341762),
219     V8_INT64_C(5055797915536941182),     V8_INT64_C(6072389716149252074),
220     V8_INT64_C(6185309910199801210),     V8_INT64_C(6297328311011094138),
221     V8_INT64_C(6932372858072165827),     V8_INT64_C(8483640924987737210),
222     V8_INT64_C(8663764179455849203),     V8_INT64_C(8877197042645298254),
223     V8_INT64_C(8901543506779157333),     std::numeric_limits<int64_t>::max()};
224
225
226 const uint32_t kUint32Values[] = {
227     0x00000000, 0x00000001, 0xffffffff, 0x1b09788b, 0x04c5fce8, 0xcc0de5bf,
228     0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
229     0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
230     0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
231     0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000,
232     0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
233     0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff,
234     0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff};
235
236
237 struct ComparisonBinaryOperator {
238   const Operator* (MachineOperatorBuilder::*constructor)();
239   const char* constructor_name;
240 };
241
242
243 std::ostream& operator<<(std::ostream& os,
244                          ComparisonBinaryOperator const& cbop) {
245   return os << cbop.constructor_name;
246 }
247
248
249 const ComparisonBinaryOperator kComparisonBinaryOperators[] = {
250 #define OPCODE(Opcode)                         \
251   { &MachineOperatorBuilder::Opcode, #Opcode } \
252   ,
253     MACHINE_COMPARE_BINOP_LIST(OPCODE)
254 #undef OPCODE
255 };
256
257 }  // namespace
258
259
260 // -----------------------------------------------------------------------------
261 // Unary operators
262
263
264 namespace {
265
266 struct UnaryOperator {
267   const Operator* (MachineOperatorBuilder::*constructor)();
268   const char* constructor_name;
269 };
270
271
272 std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
273   return os << unop.constructor_name;
274 }
275
276
277 static const UnaryOperator kUnaryOperators[] = {
278     {&MachineOperatorBuilder::ChangeInt32ToFloat64, "ChangeInt32ToFloat64"},
279     {&MachineOperatorBuilder::ChangeUint32ToFloat64, "ChangeUint32ToFloat64"},
280     {&MachineOperatorBuilder::ChangeFloat64ToInt32, "ChangeFloat64ToInt32"},
281     {&MachineOperatorBuilder::ChangeFloat64ToUint32, "ChangeFloat64ToUint32"},
282     {&MachineOperatorBuilder::ChangeInt32ToInt64, "ChangeInt32ToInt64"},
283     {&MachineOperatorBuilder::ChangeUint32ToUint64, "ChangeUint32ToUint64"},
284     {&MachineOperatorBuilder::TruncateFloat64ToInt32, "TruncateFloat64ToInt32"},
285     {&MachineOperatorBuilder::TruncateInt64ToInt32, "TruncateInt64ToInt32"}};
286
287 }  // namespace
288
289
290 typedef MachineOperatorReducerTestWithParam<UnaryOperator>
291     MachineUnaryOperatorReducerTest;
292
293
294 TEST_P(MachineUnaryOperatorReducerTest, Parameter) {
295   const UnaryOperator unop = GetParam();
296   Reduction reduction =
297       Reduce(graph()->NewNode((machine()->*unop.constructor)(), Parameter(0)));
298   EXPECT_FALSE(reduction.Changed());
299 }
300
301
302 INSTANTIATE_TEST_CASE_P(MachineOperatorReducerTest,
303                         MachineUnaryOperatorReducerTest,
304                         ::testing::ValuesIn(kUnaryOperators));
305
306
307 // -----------------------------------------------------------------------------
308 // ChangeFloat64ToFloat32
309
310
311 TEST_F(MachineOperatorReducerTest, ChangeFloat64ToFloat32WithConstant) {
312   TRACED_FOREACH(float, x, kFloat32Values) {
313     Reduction reduction = Reduce(graph()->NewNode(
314         machine()->ChangeFloat32ToFloat64(), Float32Constant(x)));
315     ASSERT_TRUE(reduction.Changed());
316     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq<double>(x)));
317   }
318 }
319
320
321 // -----------------------------------------------------------------------------
322 // ChangeFloat64ToInt32
323
324
325 TEST_F(MachineOperatorReducerTest,
326        ChangeFloat64ToInt32WithChangeInt32ToFloat64) {
327   Node* value = Parameter(0);
328   Reduction reduction = Reduce(graph()->NewNode(
329       machine()->ChangeFloat64ToInt32(),
330       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
331   ASSERT_TRUE(reduction.Changed());
332   EXPECT_EQ(value, reduction.replacement());
333 }
334
335
336 TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt32WithConstant) {
337   TRACED_FOREACH(int32_t, x, kInt32Values) {
338     Reduction reduction = Reduce(graph()->NewNode(
339         machine()->ChangeFloat64ToInt32(), Float64Constant(FastI2D(x))));
340     ASSERT_TRUE(reduction.Changed());
341     EXPECT_THAT(reduction.replacement(), IsInt32Constant(x));
342   }
343 }
344
345
346 // -----------------------------------------------------------------------------
347 // ChangeFloat64ToUint32
348
349
350 TEST_F(MachineOperatorReducerTest,
351        ChangeFloat64ToUint32WithChangeUint32ToFloat64) {
352   Node* value = Parameter(0);
353   Reduction reduction = Reduce(graph()->NewNode(
354       machine()->ChangeFloat64ToUint32(),
355       graph()->NewNode(machine()->ChangeUint32ToFloat64(), value)));
356   ASSERT_TRUE(reduction.Changed());
357   EXPECT_EQ(value, reduction.replacement());
358 }
359
360
361 TEST_F(MachineOperatorReducerTest, ChangeFloat64ToUint32WithConstant) {
362   TRACED_FOREACH(uint32_t, x, kUint32Values) {
363     Reduction reduction = Reduce(graph()->NewNode(
364         machine()->ChangeFloat64ToUint32(), Float64Constant(FastUI2D(x))));
365     ASSERT_TRUE(reduction.Changed());
366     EXPECT_THAT(reduction.replacement(), IsInt32Constant(bit_cast<int32_t>(x)));
367   }
368 }
369
370
371 // -----------------------------------------------------------------------------
372 // ChangeInt32ToFloat64
373
374
375 TEST_F(MachineOperatorReducerTest, ChangeInt32ToFloat64WithConstant) {
376   TRACED_FOREACH(int32_t, x, kInt32Values) {
377     Reduction reduction = Reduce(
378         graph()->NewNode(machine()->ChangeInt32ToFloat64(), Int32Constant(x)));
379     ASSERT_TRUE(reduction.Changed());
380     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastI2D(x))));
381   }
382 }
383
384
385 // -----------------------------------------------------------------------------
386 // ChangeInt32ToInt64
387
388
389 TEST_F(MachineOperatorReducerTest, ChangeInt32ToInt64WithConstant) {
390   TRACED_FOREACH(int32_t, x, kInt32Values) {
391     Reduction reduction = Reduce(
392         graph()->NewNode(machine()->ChangeInt32ToInt64(), Int32Constant(x)));
393     ASSERT_TRUE(reduction.Changed());
394     EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
395   }
396 }
397
398
399 // -----------------------------------------------------------------------------
400 // ChangeUint32ToFloat64
401
402
403 TEST_F(MachineOperatorReducerTest, ChangeUint32ToFloat64WithConstant) {
404   TRACED_FOREACH(uint32_t, x, kUint32Values) {
405     Reduction reduction =
406         Reduce(graph()->NewNode(machine()->ChangeUint32ToFloat64(),
407                                 Int32Constant(bit_cast<int32_t>(x))));
408     ASSERT_TRUE(reduction.Changed());
409     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastUI2D(x))));
410   }
411 }
412
413
414 // -----------------------------------------------------------------------------
415 // ChangeUint32ToUint64
416
417
418 TEST_F(MachineOperatorReducerTest, ChangeUint32ToUint64WithConstant) {
419   TRACED_FOREACH(uint32_t, x, kUint32Values) {
420     Reduction reduction =
421         Reduce(graph()->NewNode(machine()->ChangeUint32ToUint64(),
422                                 Int32Constant(bit_cast<int32_t>(x))));
423     ASSERT_TRUE(reduction.Changed());
424     EXPECT_THAT(reduction.replacement(),
425                 IsInt64Constant(bit_cast<int64_t>(static_cast<uint64_t>(x))));
426   }
427 }
428
429
430 // -----------------------------------------------------------------------------
431 // TruncateFloat64ToFloat32
432
433
434 TEST_F(MachineOperatorReducerTest,
435        TruncateFloat64ToFloat32WithChangeFloat32ToFloat64) {
436   Node* value = Parameter(0);
437   Reduction reduction = Reduce(graph()->NewNode(
438       machine()->TruncateFloat64ToFloat32(),
439       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), value)));
440   ASSERT_TRUE(reduction.Changed());
441   EXPECT_EQ(value, reduction.replacement());
442 }
443
444
445 TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
446   TRACED_FOREACH(double, x, kFloat64Values) {
447     Reduction reduction = Reduce(graph()->NewNode(
448         machine()->TruncateFloat64ToFloat32(), Float64Constant(x)));
449     ASSERT_TRUE(reduction.Changed());
450     EXPECT_THAT(reduction.replacement(),
451                 IsFloat32Constant(BitEq(DoubleToFloat32(x))));
452   }
453 }
454
455
456 // -----------------------------------------------------------------------------
457 // TruncateFloat64ToInt32
458
459
460 TEST_F(MachineOperatorReducerTest,
461        TruncateFloat64ToInt32WithChangeInt32ToFloat64) {
462   Node* value = Parameter(0);
463   Reduction reduction = Reduce(graph()->NewNode(
464       machine()->TruncateFloat64ToInt32(),
465       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
466   ASSERT_TRUE(reduction.Changed());
467   EXPECT_EQ(value, reduction.replacement());
468 }
469
470
471 TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithConstant) {
472   TRACED_FOREACH(double, x, kFloat64Values) {
473     Reduction reduction = Reduce(graph()->NewNode(
474         machine()->TruncateFloat64ToInt32(), Float64Constant(x)));
475     ASSERT_TRUE(reduction.Changed());
476     EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
477   }
478 }
479
480
481 TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithPhi) {
482   Node* const p0 = Parameter(0);
483   Node* const p1 = Parameter(1);
484   Node* const merge = graph()->start();
485   Reduction reduction = Reduce(graph()->NewNode(
486       machine()->TruncateFloat64ToInt32(),
487       graph()->NewNode(common()->Phi(kMachFloat64, 2), p0, p1, merge)));
488   ASSERT_TRUE(reduction.Changed());
489   EXPECT_THAT(reduction.replacement(),
490               IsPhi(kMachInt32, IsTruncateFloat64ToInt32(p0),
491                     IsTruncateFloat64ToInt32(p1), merge));
492 }
493
494
495 // -----------------------------------------------------------------------------
496 // TruncateInt64ToInt32
497
498
499 TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithChangeInt32ToInt64) {
500   Node* value = Parameter(0);
501   Reduction reduction = Reduce(graph()->NewNode(
502       machine()->TruncateInt64ToInt32(),
503       graph()->NewNode(machine()->ChangeInt32ToInt64(), value)));
504   ASSERT_TRUE(reduction.Changed());
505   EXPECT_EQ(value, reduction.replacement());
506 }
507
508
509 TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithConstant) {
510   TRACED_FOREACH(int64_t, x, kInt64Values) {
511     Reduction reduction = Reduce(
512         graph()->NewNode(machine()->TruncateInt64ToInt32(), Int64Constant(x)));
513     ASSERT_TRUE(reduction.Changed());
514     EXPECT_THAT(reduction.replacement(),
515                 IsInt32Constant(bit_cast<int32_t>(
516                     static_cast<uint32_t>(bit_cast<uint64_t>(x)))));
517   }
518 }
519
520
521 // -----------------------------------------------------------------------------
522 // Word32And
523
524
525 TEST_F(MachineOperatorReducerTest, Word32AndWithWord32ShlWithConstant) {
526   Node* const p0 = Parameter(0);
527
528   TRACED_FORRANGE(int32_t, l, 1, 31) {
529     TRACED_FORRANGE(int32_t, k, 1, l) {
530       // (x << L) & (-1 << K) => x << L
531       Reduction const r1 = Reduce(graph()->NewNode(
532           machine()->Word32And(),
533           graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(l)),
534           Int32Constant(-1 << k)));
535       ASSERT_TRUE(r1.Changed());
536       EXPECT_THAT(r1.replacement(), IsWord32Shl(p0, IsInt32Constant(l)));
537
538       // (-1 << K) & (x << L) => x << L
539       Reduction const r2 = Reduce(graph()->NewNode(
540           machine()->Word32And(), Int32Constant(-1 << k),
541           graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(l))));
542       ASSERT_TRUE(r2.Changed());
543       EXPECT_THAT(r2.replacement(), IsWord32Shl(p0, IsInt32Constant(l)));
544     }
545   }
546 }
547
548
549 TEST_F(MachineOperatorReducerTest, Word32AndWithWord32AndWithConstant) {
550   Node* const p0 = Parameter(0);
551
552   TRACED_FOREACH(int32_t, k, kInt32Values) {
553     TRACED_FOREACH(int32_t, l, kInt32Values) {
554       if (k == 0 || k == -1 || l == 0 || l == -1) continue;
555
556       // (x & K) & L => x & (K & L)
557       Reduction const r1 = Reduce(graph()->NewNode(
558           machine()->Word32And(),
559           graph()->NewNode(machine()->Word32And(), p0, Int32Constant(k)),
560           Int32Constant(l)));
561       ASSERT_TRUE(r1.Changed());
562       EXPECT_THAT(r1.replacement(),
563                   (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
564                           : IsInt32Constant(0));
565
566       // (K & x) & L => x & (K & L)
567       Reduction const r2 = Reduce(graph()->NewNode(
568           machine()->Word32And(),
569           graph()->NewNode(machine()->Word32And(), Int32Constant(k), p0),
570           Int32Constant(l)));
571       ASSERT_TRUE(r2.Changed());
572       EXPECT_THAT(r2.replacement(),
573                   (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
574                           : IsInt32Constant(0));
575     }
576   }
577 }
578
579
580 TEST_F(MachineOperatorReducerTest, Word32AndWithInt32AddAndConstant) {
581   Node* const p0 = Parameter(0);
582   Node* const p1 = Parameter(1);
583
584   TRACED_FORRANGE(int32_t, l, 1, 31) {
585     TRACED_FOREACH(int32_t, k, kInt32Values) {
586       if ((k << l) == 0) continue;
587       // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
588       Reduction const r = Reduce(graph()->NewNode(
589           machine()->Word32And(),
590           graph()->NewNode(machine()->Int32Add(), p0, Int32Constant(k << l)),
591           Int32Constant(-1 << l)));
592       ASSERT_TRUE(r.Changed());
593       EXPECT_THAT(r.replacement(),
594                   IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
595                              IsInt32Constant(k << l)));
596     }
597
598     Node* s1 = graph()->NewNode(machine()->Word32Shl(), p1, Int32Constant(l));
599
600     // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
601     Reduction const r1 = Reduce(graph()->NewNode(
602         machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), s1, p0),
603         Int32Constant(-1 << l)));
604     ASSERT_TRUE(r1.Changed());
605     EXPECT_THAT(r1.replacement(),
606                 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)), s1));
607
608     // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
609     Reduction const r2 = Reduce(graph()->NewNode(
610         machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), p0, s1),
611         Int32Constant(-1 << l)));
612     ASSERT_TRUE(r2.Changed());
613     EXPECT_THAT(r2.replacement(),
614                 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)), s1));
615   }
616 }
617
618
619 TEST_F(MachineOperatorReducerTest, Word32AndWithInt32MulAndConstant) {
620   Node* const p0 = Parameter(0);
621
622   TRACED_FORRANGE(int32_t, l, 1, 31) {
623     TRACED_FOREACH(int32_t, k, kInt32Values) {
624       if ((k << l) == 0) continue;
625
626       // (x * (K << L)) & (-1 << L) => x * (K << L)
627       Reduction const r1 = Reduce(graph()->NewNode(
628           machine()->Word32And(),
629           graph()->NewNode(machine()->Int32Mul(), p0, Int32Constant(k << l)),
630           Int32Constant(-1 << l)));
631       ASSERT_TRUE(r1.Changed());
632       EXPECT_THAT(r1.replacement(), IsInt32Mul(p0, IsInt32Constant(k << l)));
633
634       // ((K << L) * x) & (-1 << L) => x * (K << L)
635       Reduction const r2 = Reduce(graph()->NewNode(
636           machine()->Word32And(),
637           graph()->NewNode(machine()->Int32Mul(), Int32Constant(k << l), p0),
638           Int32Constant(-1 << l)));
639       ASSERT_TRUE(r2.Changed());
640       EXPECT_THAT(r2.replacement(), IsInt32Mul(p0, IsInt32Constant(k << l)));
641     }
642   }
643 }
644
645
646 TEST_F(MachineOperatorReducerTest,
647        Word32AndWithInt32AddAndInt32MulAndConstant) {
648   Node* const p0 = Parameter(0);
649   Node* const p1 = Parameter(1);
650
651   TRACED_FORRANGE(int32_t, l, 1, 31) {
652     TRACED_FOREACH(int32_t, k, kInt32Values) {
653       if ((k << l) == 0) continue;
654       // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
655       Reduction const r1 = Reduce(graph()->NewNode(
656           machine()->Word32And(),
657           graph()->NewNode(machine()->Int32Add(),
658                            graph()->NewNode(machine()->Int32Mul(), p1,
659                                             Int32Constant(k << l)),
660                            p0),
661           Int32Constant(-1 << l)));
662       ASSERT_TRUE(r1.Changed());
663       EXPECT_THAT(r1.replacement(),
664                   IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
665                              IsInt32Mul(p1, IsInt32Constant(k << l))));
666
667       // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
668       Reduction const r2 = Reduce(graph()->NewNode(
669           machine()->Word32And(),
670           graph()->NewNode(machine()->Int32Add(), p0,
671                            graph()->NewNode(machine()->Int32Mul(), p1,
672                                             Int32Constant(k << l))),
673           Int32Constant(-1 << l)));
674       ASSERT_TRUE(r2.Changed());
675       EXPECT_THAT(r2.replacement(),
676                   IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
677                              IsInt32Mul(p1, IsInt32Constant(k << l))));
678     }
679   }
680 }
681
682
683 TEST_F(MachineOperatorReducerTest, Word32AndWithComparisonAndConstantOne) {
684   Node* const p0 = Parameter(0);
685   Node* const p1 = Parameter(1);
686   TRACED_FOREACH(ComparisonBinaryOperator, cbop, kComparisonBinaryOperators) {
687     Node* cmp = graph()->NewNode((machine()->*cbop.constructor)(), p0, p1);
688
689     // cmp & 1 => cmp
690     Reduction const r1 =
691         Reduce(graph()->NewNode(machine()->Word32And(), cmp, Int32Constant(1)));
692     ASSERT_TRUE(r1.Changed());
693     EXPECT_EQ(cmp, r1.replacement());
694
695     // 1 & cmp => cmp
696     Reduction const r2 =
697         Reduce(graph()->NewNode(machine()->Word32And(), Int32Constant(1), cmp));
698     ASSERT_TRUE(r2.Changed());
699     EXPECT_EQ(cmp, r2.replacement());
700   }
701 }
702
703
704 // -----------------------------------------------------------------------------
705 // Word32Xor
706
707
708 TEST_F(MachineOperatorReducerTest, Word32XorWithWord32XorAndMinusOne) {
709   Node* const p0 = Parameter(0);
710
711   // (x ^ -1) ^ -1 => x
712   Reduction r1 = Reduce(graph()->NewNode(
713       machine()->Word32Xor(),
714       graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1)),
715       Int32Constant(-1)));
716   ASSERT_TRUE(r1.Changed());
717   EXPECT_EQ(r1.replacement(), p0);
718
719   // -1 ^ (x ^ -1) => x
720   Reduction r2 = Reduce(graph()->NewNode(
721       machine()->Word32Xor(), Int32Constant(-1),
722       graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1))));
723   ASSERT_TRUE(r2.Changed());
724   EXPECT_EQ(r2.replacement(), p0);
725
726   // (-1 ^ x) ^ -1 => x
727   Reduction r3 = Reduce(graph()->NewNode(
728       machine()->Word32Xor(),
729       graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0),
730       Int32Constant(-1)));
731   ASSERT_TRUE(r3.Changed());
732   EXPECT_EQ(r3.replacement(), p0);
733
734   // -1 ^ (-1 ^ x) => x
735   Reduction r4 = Reduce(graph()->NewNode(
736       machine()->Word32Xor(), Int32Constant(-1),
737       graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0)));
738   ASSERT_TRUE(r4.Changed());
739   EXPECT_EQ(r4.replacement(), p0);
740 }
741
742
743 // -----------------------------------------------------------------------------
744 // Word32Ror
745
746
747 TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
748   Node* value = Parameter(0);
749   Node* shift = Parameter(1);
750   Node* sub = graph()->NewNode(machine()->Int32Sub(), Int32Constant(32), shift);
751
752   // Testing rotate left.
753   Node* shl_l = graph()->NewNode(machine()->Word32Shl(), value, shift);
754   Node* shr_l = graph()->NewNode(machine()->Word32Shr(), value, sub);
755
756   // (x << y) | (x >>> (32 - y)) => x ror (32 - y)
757   Node* node1 = graph()->NewNode(machine()->Word32Or(), shl_l, shr_l);
758   Reduction reduction1 = Reduce(node1);
759   EXPECT_TRUE(reduction1.Changed());
760   EXPECT_EQ(reduction1.replacement(), node1);
761   EXPECT_THAT(reduction1.replacement(), IsWord32Ror(value, sub));
762
763   // (x >>> (32 - y)) | (x << y) => x ror (32 - y)
764   Node* node2 = graph()->NewNode(machine()->Word32Or(), shr_l, shl_l);
765   Reduction reduction2 = Reduce(node2);
766   EXPECT_TRUE(reduction2.Changed());
767   EXPECT_EQ(reduction2.replacement(), node2);
768   EXPECT_THAT(reduction2.replacement(), IsWord32Ror(value, sub));
769
770   // Testing rotate right.
771   Node* shl_r = graph()->NewNode(machine()->Word32Shl(), value, sub);
772   Node* shr_r = graph()->NewNode(machine()->Word32Shr(), value, shift);
773
774   // (x << (32 - y)) | (x >>> y) => x ror y
775   Node* node3 = graph()->NewNode(machine()->Word32Or(), shl_r, shr_r);
776   Reduction reduction3 = Reduce(node3);
777   EXPECT_TRUE(reduction3.Changed());
778   EXPECT_EQ(reduction3.replacement(), node3);
779   EXPECT_THAT(reduction3.replacement(), IsWord32Ror(value, shift));
780
781   // (x >>> y) | (x << (32 - y)) => x ror y
782   Node* node4 = graph()->NewNode(machine()->Word32Or(), shr_r, shl_r);
783   Reduction reduction4 = Reduce(node4);
784   EXPECT_TRUE(reduction4.Changed());
785   EXPECT_EQ(reduction4.replacement(), node4);
786   EXPECT_THAT(reduction4.replacement(), IsWord32Ror(value, shift));
787 }
788
789
790 TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
791   Node* value = Parameter(0);
792   TRACED_FORRANGE(int32_t, k, 0, 31) {
793     Node* shl =
794         graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(k));
795     Node* shr =
796         graph()->NewNode(machine()->Word32Shr(), value, Int32Constant(32 - k));
797
798     // (x << K) | (x >>> ((32 - K) - y)) => x ror (32 - K)
799     Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
800     Reduction reduction1 = Reduce(node1);
801     EXPECT_TRUE(reduction1.Changed());
802     EXPECT_EQ(reduction1.replacement(), node1);
803     EXPECT_THAT(reduction1.replacement(),
804                 IsWord32Ror(value, IsInt32Constant(32 - k)));
805
806     // (x >>> (32 - K)) | (x << K) => x ror (32 - K)
807     Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
808     Reduction reduction2 = Reduce(node2);
809     EXPECT_TRUE(reduction2.Changed());
810     EXPECT_EQ(reduction2.replacement(), node2);
811     EXPECT_THAT(reduction2.replacement(),
812                 IsWord32Ror(value, IsInt32Constant(32 - k)));
813   }
814 }
815
816
817 TEST_F(MachineOperatorReducerTest, Word32RorWithZeroShift) {
818   Node* value = Parameter(0);
819   Node* node =
820       graph()->NewNode(machine()->Word32Ror(), value, Int32Constant(0));
821   Reduction reduction = Reduce(node);
822   EXPECT_TRUE(reduction.Changed());
823   EXPECT_EQ(reduction.replacement(), value);
824 }
825
826
827 TEST_F(MachineOperatorReducerTest, Word32RorWithConstants) {
828   TRACED_FOREACH(int32_t, x, kUint32Values) {
829     TRACED_FORRANGE(int32_t, y, 0, 31) {
830       Node* node = graph()->NewNode(machine()->Word32Ror(), Int32Constant(x),
831                                     Int32Constant(y));
832       Reduction reduction = Reduce(node);
833       EXPECT_TRUE(reduction.Changed());
834       EXPECT_THAT(reduction.replacement(),
835                   IsInt32Constant(base::bits::RotateRight32(x, y)));
836     }
837   }
838 }
839
840
841 // -----------------------------------------------------------------------------
842 // Word32Sar
843
844
845 TEST_F(MachineOperatorReducerTest, Word32SarWithWord32ShlAndComparison) {
846   Node* const p0 = Parameter(0);
847   Node* const p1 = Parameter(1);
848
849   TRACED_FOREACH(ComparisonBinaryOperator, cbop, kComparisonBinaryOperators) {
850     Node* cmp = graph()->NewNode((machine()->*cbop.constructor)(), p0, p1);
851
852     // cmp << 31 >> 31 => 0 - cmp
853     Reduction const r = Reduce(graph()->NewNode(
854         machine()->Word32Sar(),
855         graph()->NewNode(machine()->Word32Shl(), cmp, Int32Constant(31)),
856         Int32Constant(31)));
857     ASSERT_TRUE(r.Changed());
858     EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0), cmp));
859   }
860 }
861
862
863 TEST_F(MachineOperatorReducerTest, Word32SarWithWord32ShlAndLoad) {
864   Node* const p0 = Parameter(0);
865   Node* const p1 = Parameter(1);
866   {
867     Node* const l = graph()->NewNode(machine()->Load(kMachInt8), p0, p1,
868                                      graph()->start(), graph()->start());
869     Reduction const r = Reduce(graph()->NewNode(
870         machine()->Word32Sar(),
871         graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(24)),
872         Int32Constant(24)));
873     ASSERT_TRUE(r.Changed());
874     EXPECT_EQ(l, r.replacement());
875   }
876   {
877     Node* const l = graph()->NewNode(machine()->Load(kMachInt16), p0, p1,
878                                      graph()->start(), graph()->start());
879     Reduction const r = Reduce(graph()->NewNode(
880         machine()->Word32Sar(),
881         graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(16)),
882         Int32Constant(16)));
883     ASSERT_TRUE(r.Changed());
884     EXPECT_EQ(l, r.replacement());
885   }
886 }
887
888
889 // -----------------------------------------------------------------------------
890 // Word32Shl
891
892
893 TEST_F(MachineOperatorReducerTest, Word32ShlWithZeroShift) {
894   Node* p0 = Parameter(0);
895   Node* node = graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(0));
896   Reduction r = Reduce(node);
897   ASSERT_TRUE(r.Changed());
898   EXPECT_EQ(p0, r.replacement());
899 }
900
901
902 TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Sar) {
903   Node* p0 = Parameter(0);
904   TRACED_FORRANGE(int32_t, x, 1, 31) {
905     Node* node = graph()->NewNode(
906         machine()->Word32Shl(),
907         graph()->NewNode(machine()->Word32Sar(), p0, Int32Constant(x)),
908         Int32Constant(x));
909     Reduction r = Reduce(node);
910     ASSERT_TRUE(r.Changed());
911     int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
912     EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
913   }
914 }
915
916
917 TEST_F(MachineOperatorReducerTest,
918        Word32ShlWithWord32SarAndInt32AddAndConstant) {
919   Node* const p0 = Parameter(0);
920   TRACED_FOREACH(int32_t, k, kInt32Values) {
921     TRACED_FORRANGE(int32_t, l, 1, 31) {
922       if ((k << l) == 0) continue;
923       // (x + (K << L)) >> L << L => (x & (-1 << L)) + (K << L)
924       Reduction const r = Reduce(graph()->NewNode(
925           machine()->Word32Shl(),
926           graph()->NewNode(machine()->Word32Sar(),
927                            graph()->NewNode(machine()->Int32Add(), p0,
928                                             Int32Constant(k << l)),
929                            Int32Constant(l)),
930           Int32Constant(l)));
931       ASSERT_TRUE(r.Changed());
932       EXPECT_THAT(r.replacement(),
933                   IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
934                              IsInt32Constant(k << l)));
935     }
936   }
937 }
938
939
940 TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Shr) {
941   Node* p0 = Parameter(0);
942   TRACED_FORRANGE(int32_t, x, 1, 31) {
943     Node* node = graph()->NewNode(
944         machine()->Word32Shl(),
945         graph()->NewNode(machine()->Word32Shr(), p0, Int32Constant(x)),
946         Int32Constant(x));
947     Reduction r = Reduce(node);
948     ASSERT_TRUE(r.Changed());
949     int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
950     EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
951   }
952 }
953
954
955 // -----------------------------------------------------------------------------
956 // Int32Sub
957
958
959 TEST_F(MachineOperatorReducerTest, Int32SubWithConstant) {
960   Node* const p0 = Parameter(0);
961   TRACED_FOREACH(int32_t, k, kInt32Values) {
962     Reduction const r =
963         Reduce(graph()->NewNode(machine()->Int32Sub(), p0, Int32Constant(k)));
964     ASSERT_TRUE(r.Changed());
965     if (k == 0) {
966       EXPECT_EQ(p0, r.replacement());
967     } else {
968       EXPECT_THAT(r.replacement(), IsInt32Add(p0, IsInt32Constant(-k)));
969     }
970   }
971 }
972
973
974 // -----------------------------------------------------------------------------
975 // Int32Div
976
977
978 TEST_F(MachineOperatorReducerTest, Int32DivWithConstant) {
979   Node* const p0 = Parameter(0);
980   {
981     Reduction const r = Reduce(graph()->NewNode(
982         machine()->Int32Div(), p0, Int32Constant(0), graph()->start()));
983     ASSERT_TRUE(r.Changed());
984     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
985   }
986   {
987     Reduction const r = Reduce(graph()->NewNode(
988         machine()->Int32Div(), p0, Int32Constant(1), graph()->start()));
989     ASSERT_TRUE(r.Changed());
990     EXPECT_EQ(r.replacement(), p0);
991   }
992   {
993     Reduction const r = Reduce(graph()->NewNode(
994         machine()->Int32Div(), p0, Int32Constant(-1), graph()->start()));
995     ASSERT_TRUE(r.Changed());
996     EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0), p0));
997   }
998   {
999     Reduction const r = Reduce(graph()->NewNode(
1000         machine()->Int32Div(), p0, Int32Constant(2), graph()->start()));
1001     ASSERT_TRUE(r.Changed());
1002     EXPECT_THAT(
1003         r.replacement(),
1004         IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
1005                     IsInt32Constant(1)));
1006   }
1007   {
1008     Reduction const r = Reduce(graph()->NewNode(
1009         machine()->Int32Div(), p0, Int32Constant(-2), graph()->start()));
1010     ASSERT_TRUE(r.Changed());
1011     EXPECT_THAT(
1012         r.replacement(),
1013         IsInt32Sub(
1014             IsInt32Constant(0),
1015             IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
1016                         IsInt32Constant(1))));
1017   }
1018   TRACED_FORRANGE(int32_t, shift, 2, 30) {
1019     Reduction const r =
1020         Reduce(graph()->NewNode(machine()->Int32Div(), p0,
1021                                 Int32Constant(1 << shift), graph()->start()));
1022     ASSERT_TRUE(r.Changed());
1023     EXPECT_THAT(
1024         r.replacement(),
1025         IsWord32Sar(IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
1026                                            IsInt32Constant(32 - shift)),
1027                                p0),
1028                     IsInt32Constant(shift)));
1029   }
1030   TRACED_FORRANGE(int32_t, shift, 2, 31) {
1031     Reduction const r = Reduce(graph()->NewNode(
1032         machine()->Int32Div(), p0,
1033         Uint32Constant(bit_cast<uint32_t, int32_t>(-1) << shift),
1034         graph()->start()));
1035     ASSERT_TRUE(r.Changed());
1036     EXPECT_THAT(
1037         r.replacement(),
1038         IsInt32Sub(
1039             IsInt32Constant(0),
1040             IsWord32Sar(
1041                 IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
1042                                        IsInt32Constant(32 - shift)),
1043                            p0),
1044                 IsInt32Constant(shift))));
1045   }
1046   TRACED_FOREACH(int32_t, divisor, kInt32Values) {
1047     if (divisor < 0) {
1048       if (base::bits::IsPowerOfTwo32(-divisor)) continue;
1049       Reduction const r = Reduce(graph()->NewNode(
1050           machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
1051       ASSERT_TRUE(r.Changed());
1052       EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0),
1053                                               IsTruncatingDiv(p0, -divisor)));
1054     } else if (divisor > 0) {
1055       if (base::bits::IsPowerOfTwo32(divisor)) continue;
1056       Reduction const r = Reduce(graph()->NewNode(
1057           machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
1058       ASSERT_TRUE(r.Changed());
1059       EXPECT_THAT(r.replacement(), IsTruncatingDiv(p0, divisor));
1060     }
1061   }
1062 }
1063
1064
1065 TEST_F(MachineOperatorReducerTest, Int32DivWithParameters) {
1066   Node* const p0 = Parameter(0);
1067   Reduction const r =
1068       Reduce(graph()->NewNode(machine()->Int32Div(), p0, p0, graph()->start()));
1069   ASSERT_TRUE(r.Changed());
1070   EXPECT_THAT(
1071       r.replacement(),
1072       IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
1073 }
1074
1075
1076 // -----------------------------------------------------------------------------
1077 // Uint32Div
1078
1079
1080 TEST_F(MachineOperatorReducerTest, Uint32DivWithConstant) {
1081   Node* const p0 = Parameter(0);
1082   {
1083     Reduction const r = Reduce(graph()->NewNode(
1084         machine()->Uint32Div(), Int32Constant(0), p0, graph()->start()));
1085     ASSERT_TRUE(r.Changed());
1086     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1087   }
1088   {
1089     Reduction const r = Reduce(graph()->NewNode(
1090         machine()->Uint32Div(), p0, Int32Constant(0), graph()->start()));
1091     ASSERT_TRUE(r.Changed());
1092     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1093   }
1094   {
1095     Reduction const r = Reduce(graph()->NewNode(
1096         machine()->Uint32Div(), p0, Int32Constant(1), graph()->start()));
1097     ASSERT_TRUE(r.Changed());
1098     EXPECT_EQ(r.replacement(), p0);
1099   }
1100   TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
1101     TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
1102       Reduction const r = Reduce(
1103           graph()->NewNode(machine()->Uint32Div(), Uint32Constant(dividend),
1104                            Uint32Constant(divisor), graph()->start()));
1105       ASSERT_TRUE(r.Changed());
1106       EXPECT_THAT(r.replacement(),
1107                   IsInt32Constant(bit_cast<int32_t>(
1108                       base::bits::UnsignedDiv32(dividend, divisor))));
1109     }
1110   }
1111   TRACED_FORRANGE(uint32_t, shift, 1, 31) {
1112     Reduction const r =
1113         Reduce(graph()->NewNode(machine()->Uint32Div(), p0,
1114                                 Uint32Constant(1u << shift), graph()->start()));
1115     ASSERT_TRUE(r.Changed());
1116     EXPECT_THAT(r.replacement(),
1117                 IsWord32Shr(p0, IsInt32Constant(bit_cast<int32_t>(shift))));
1118   }
1119 }
1120
1121
1122 TEST_F(MachineOperatorReducerTest, Uint32DivWithParameters) {
1123   Node* const p0 = Parameter(0);
1124   Reduction const r = Reduce(
1125       graph()->NewNode(machine()->Uint32Div(), p0, p0, graph()->start()));
1126   ASSERT_TRUE(r.Changed());
1127   EXPECT_THAT(
1128       r.replacement(),
1129       IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
1130 }
1131
1132
1133 // -----------------------------------------------------------------------------
1134 // Int32Mod
1135
1136
1137 TEST_F(MachineOperatorReducerTest, Int32ModWithConstant) {
1138   Node* const p0 = Parameter(0);
1139   {
1140     Reduction const r = Reduce(graph()->NewNode(
1141         machine()->Int32Mod(), Int32Constant(0), p0, graph()->start()));
1142     ASSERT_TRUE(r.Changed());
1143     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1144   }
1145   {
1146     Reduction const r = Reduce(graph()->NewNode(
1147         machine()->Int32Mod(), p0, Int32Constant(0), graph()->start()));
1148     ASSERT_TRUE(r.Changed());
1149     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1150   }
1151   {
1152     Reduction const r = Reduce(graph()->NewNode(
1153         machine()->Int32Mod(), p0, Int32Constant(1), graph()->start()));
1154     ASSERT_TRUE(r.Changed());
1155     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1156   }
1157   {
1158     Reduction const r = Reduce(graph()->NewNode(
1159         machine()->Int32Mod(), p0, Int32Constant(-1), graph()->start()));
1160     ASSERT_TRUE(r.Changed());
1161     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1162   }
1163   TRACED_FOREACH(int32_t, dividend, kInt32Values) {
1164     TRACED_FOREACH(int32_t, divisor, kInt32Values) {
1165       Reduction const r = Reduce(
1166           graph()->NewNode(machine()->Int32Mod(), Int32Constant(dividend),
1167                            Int32Constant(divisor), graph()->start()));
1168       ASSERT_TRUE(r.Changed());
1169       EXPECT_THAT(r.replacement(),
1170                   IsInt32Constant(base::bits::SignedMod32(dividend, divisor)));
1171     }
1172   }
1173   TRACED_FORRANGE(int32_t, shift, 1, 30) {
1174     Reduction const r =
1175         Reduce(graph()->NewNode(machine()->Int32Mod(), p0,
1176                                 Int32Constant(1 << shift), graph()->start()));
1177     int32_t const mask = (1 << shift) - 1;
1178     ASSERT_TRUE(r.Changed());
1179     EXPECT_THAT(
1180         r.replacement(),
1181         IsSelect(kMachInt32, IsInt32LessThan(p0, IsInt32Constant(0)),
1182                  IsInt32Sub(IsInt32Constant(0),
1183                             IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
1184                                         IsInt32Constant(mask))),
1185                  IsWord32And(p0, IsInt32Constant(mask))));
1186   }
1187   TRACED_FORRANGE(int32_t, shift, 1, 31) {
1188     Reduction const r = Reduce(graph()->NewNode(
1189         machine()->Int32Mod(), p0,
1190         Uint32Constant(bit_cast<uint32_t, int32_t>(-1) << shift),
1191         graph()->start()));
1192     int32_t const mask = bit_cast<int32_t, uint32_t>((1U << shift) - 1);
1193     ASSERT_TRUE(r.Changed());
1194     EXPECT_THAT(
1195         r.replacement(),
1196         IsSelect(kMachInt32, IsInt32LessThan(p0, IsInt32Constant(0)),
1197                  IsInt32Sub(IsInt32Constant(0),
1198                             IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
1199                                         IsInt32Constant(mask))),
1200                  IsWord32And(p0, IsInt32Constant(mask))));
1201   }
1202   TRACED_FOREACH(int32_t, divisor, kInt32Values) {
1203     if (divisor == 0 || base::bits::IsPowerOfTwo32(Abs(divisor))) continue;
1204     Reduction const r = Reduce(graph()->NewNode(
1205         machine()->Int32Mod(), p0, Int32Constant(divisor), graph()->start()));
1206     ASSERT_TRUE(r.Changed());
1207     EXPECT_THAT(r.replacement(),
1208                 IsInt32Sub(p0, IsInt32Mul(IsTruncatingDiv(p0, Abs(divisor)),
1209                                           IsInt32Constant(Abs(divisor)))));
1210   }
1211 }
1212
1213
1214 TEST_F(MachineOperatorReducerTest, Int32ModWithParameters) {
1215   Node* const p0 = Parameter(0);
1216   Reduction const r =
1217       Reduce(graph()->NewNode(machine()->Int32Mod(), p0, p0, graph()->start()));
1218   ASSERT_TRUE(r.Changed());
1219   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1220 }
1221
1222
1223 // -----------------------------------------------------------------------------
1224 // Uint32Mod
1225
1226
1227 TEST_F(MachineOperatorReducerTest, Uint32ModWithConstant) {
1228   Node* const p0 = Parameter(0);
1229   {
1230     Reduction const r = Reduce(graph()->NewNode(
1231         machine()->Uint32Mod(), p0, Int32Constant(0), graph()->start()));
1232     ASSERT_TRUE(r.Changed());
1233     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1234   }
1235   {
1236     Reduction const r = Reduce(graph()->NewNode(
1237         machine()->Uint32Mod(), Int32Constant(0), p0, graph()->start()));
1238     ASSERT_TRUE(r.Changed());
1239     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1240   }
1241   {
1242     Reduction const r = Reduce(graph()->NewNode(
1243         machine()->Uint32Mod(), p0, Int32Constant(1), graph()->start()));
1244     ASSERT_TRUE(r.Changed());
1245     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1246   }
1247   TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
1248     TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
1249       Reduction const r = Reduce(
1250           graph()->NewNode(machine()->Uint32Mod(), Uint32Constant(dividend),
1251                            Uint32Constant(divisor), graph()->start()));
1252       ASSERT_TRUE(r.Changed());
1253       EXPECT_THAT(r.replacement(),
1254                   IsInt32Constant(bit_cast<int32_t>(
1255                       base::bits::UnsignedMod32(dividend, divisor))));
1256     }
1257   }
1258   TRACED_FORRANGE(uint32_t, shift, 1, 31) {
1259     Reduction const r =
1260         Reduce(graph()->NewNode(machine()->Uint32Mod(), p0,
1261                                 Uint32Constant(1u << shift), graph()->start()));
1262     ASSERT_TRUE(r.Changed());
1263     EXPECT_THAT(r.replacement(),
1264                 IsWord32And(p0, IsInt32Constant(
1265                                     bit_cast<int32_t>((1u << shift) - 1u))));
1266   }
1267 }
1268
1269
1270 TEST_F(MachineOperatorReducerTest, Uint32ModWithParameters) {
1271   Node* const p0 = Parameter(0);
1272   Reduction const r = Reduce(
1273       graph()->NewNode(machine()->Uint32Mod(), p0, p0, graph()->start()));
1274   ASSERT_TRUE(r.Changed());
1275   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1276 }
1277
1278
1279 // -----------------------------------------------------------------------------
1280 // Int32Add
1281
1282
1283 TEST_F(MachineOperatorReducerTest, Int32AddWithInt32SubWithConstantZero) {
1284   Node* const p0 = Parameter(0);
1285   Node* const p1 = Parameter(1);
1286
1287   Reduction const r1 = Reduce(graph()->NewNode(
1288       machine()->Int32Add(),
1289       graph()->NewNode(machine()->Int32Sub(), Int32Constant(0), p0), p1));
1290   ASSERT_TRUE(r1.Changed());
1291   EXPECT_THAT(r1.replacement(), IsInt32Sub(p1, p0));
1292
1293   Reduction const r2 = Reduce(graph()->NewNode(
1294       machine()->Int32Add(), p0,
1295       graph()->NewNode(machine()->Int32Sub(), Int32Constant(0), p1)));
1296   ASSERT_TRUE(r2.Changed());
1297   EXPECT_THAT(r2.replacement(), IsInt32Sub(p0, p1));
1298 }
1299
1300
1301 // -----------------------------------------------------------------------------
1302 // Int32AddWithOverflow
1303
1304
1305 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
1306   Node* p0 = Parameter(0);
1307   {
1308     Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
1309                                  Int32Constant(0), p0);
1310
1311     Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1312     ASSERT_TRUE(r.Changed());
1313     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1314
1315     r = Reduce(graph()->NewNode(common()->Projection(0), add));
1316     ASSERT_TRUE(r.Changed());
1317     EXPECT_EQ(p0, r.replacement());
1318   }
1319   {
1320     Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
1321                                  Int32Constant(0));
1322
1323     Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1324     ASSERT_TRUE(r.Changed());
1325     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1326
1327     r = Reduce(graph()->NewNode(common()->Projection(0), add));
1328     ASSERT_TRUE(r.Changed());
1329     EXPECT_EQ(p0, r.replacement());
1330   }
1331 }
1332
1333
1334 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
1335   TRACED_FOREACH(int32_t, x, kInt32Values) {
1336     TRACED_FOREACH(int32_t, y, kInt32Values) {
1337       int32_t z;
1338       Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
1339                                    Int32Constant(x), Int32Constant(y));
1340
1341       Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1342       ASSERT_TRUE(r.Changed());
1343       EXPECT_THAT(r.replacement(),
1344                   IsInt32Constant(base::bits::SignedAddOverflow32(x, y, &z)));
1345
1346       r = Reduce(graph()->NewNode(common()->Projection(0), add));
1347       ASSERT_TRUE(r.Changed());
1348       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
1349     }
1350   }
1351 }
1352
1353
1354 // -----------------------------------------------------------------------------
1355 // Int32SubWithOverflow
1356
1357
1358 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
1359   Node* p0 = Parameter(0);
1360   Node* add =
1361       graph()->NewNode(machine()->Int32SubWithOverflow(), p0, Int32Constant(0));
1362
1363   Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1364   ASSERT_TRUE(r.Changed());
1365   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1366
1367   r = Reduce(graph()->NewNode(common()->Projection(0), add));
1368   ASSERT_TRUE(r.Changed());
1369   EXPECT_EQ(p0, r.replacement());
1370 }
1371
1372
1373 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
1374   TRACED_FOREACH(int32_t, x, kInt32Values) {
1375     TRACED_FOREACH(int32_t, y, kInt32Values) {
1376       int32_t z;
1377       Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
1378                                    Int32Constant(x), Int32Constant(y));
1379
1380       Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1381       ASSERT_TRUE(r.Changed());
1382       EXPECT_THAT(r.replacement(),
1383                   IsInt32Constant(base::bits::SignedSubOverflow32(x, y, &z)));
1384
1385       r = Reduce(graph()->NewNode(common()->Projection(0), add));
1386       ASSERT_TRUE(r.Changed());
1387       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
1388     }
1389   }
1390 }
1391
1392
1393 // -----------------------------------------------------------------------------
1394 // Uint32LessThan
1395
1396
1397 TEST_F(MachineOperatorReducerTest, Uint32LessThanWithWord32Sar) {
1398   Node* const p0 = Parameter(0);
1399   TRACED_FORRANGE(uint32_t, shift, 1, 3) {
1400     const uint32_t limit = (kMaxInt >> shift) - 1;
1401     Node* const node = graph()->NewNode(
1402         machine()->Uint32LessThan(),
1403         graph()->NewNode(machine()->Word32Sar(), p0, Uint32Constant(shift)),
1404         Uint32Constant(limit));
1405
1406     Reduction r = Reduce(node);
1407     ASSERT_TRUE(r.Changed());
1408     EXPECT_THAT(r.replacement(),
1409                 IsUint32LessThan(
1410                     p0, IsInt32Constant(bit_cast<int32_t>(limit << shift))));
1411   }
1412 }
1413
1414
1415 // -----------------------------------------------------------------------------
1416 // Float64Mul
1417
1418
1419 TEST_F(MachineOperatorReducerTest, Float64MulWithMinusOne) {
1420   Node* const p0 = Parameter(0);
1421   {
1422     Reduction r = Reduce(
1423         graph()->NewNode(machine()->Float64Mul(), p0, Float64Constant(-1.0)));
1424     ASSERT_TRUE(r.Changed());
1425     EXPECT_THAT(r.replacement(),
1426                 IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
1427   }
1428   {
1429     Reduction r = Reduce(
1430         graph()->NewNode(machine()->Float64Mul(), Float64Constant(-1.0), p0));
1431     ASSERT_TRUE(r.Changed());
1432     EXPECT_THAT(r.replacement(),
1433                 IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
1434   }
1435 }
1436
1437
1438 // -----------------------------------------------------------------------------
1439 // Float64InsertLowWord32
1440
1441
1442 TEST_F(MachineOperatorReducerTest, Float64InsertLowWord32WithConstant) {
1443   TRACED_FOREACH(double, x, kFloat64Values) {
1444     TRACED_FOREACH(uint32_t, y, kUint32Values) {
1445       Reduction const r =
1446           Reduce(graph()->NewNode(machine()->Float64InsertLowWord32(),
1447                                   Float64Constant(x), Uint32Constant(y)));
1448       ASSERT_TRUE(r.Changed());
1449       EXPECT_THAT(
1450           r.replacement(),
1451           IsFloat64Constant(BitEq(bit_cast<double>(
1452               (bit_cast<uint64_t>(x) & V8_UINT64_C(0xFFFFFFFF00000000)) | y))));
1453     }
1454   }
1455 }
1456
1457
1458 // -----------------------------------------------------------------------------
1459 // Float64InsertHighWord32
1460
1461
1462 TEST_F(MachineOperatorReducerTest, Float64InsertHighWord32WithConstant) {
1463   TRACED_FOREACH(double, x, kFloat64Values) {
1464     TRACED_FOREACH(uint32_t, y, kUint32Values) {
1465       Reduction const r =
1466           Reduce(graph()->NewNode(machine()->Float64InsertHighWord32(),
1467                                   Float64Constant(x), Uint32Constant(y)));
1468       ASSERT_TRUE(r.Changed());
1469       EXPECT_THAT(r.replacement(),
1470                   IsFloat64Constant(BitEq(bit_cast<double>(
1471                       (bit_cast<uint64_t>(x) & V8_UINT64_C(0xFFFFFFFF)) |
1472                       (static_cast<uint64_t>(y) << 32)))));
1473     }
1474   }
1475 }
1476
1477
1478 // -----------------------------------------------------------------------------
1479 // Store
1480
1481
1482 TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32And) {
1483   const StoreRepresentation rep(kRepWord8, kNoWriteBarrier);
1484   Node* const base = Parameter(0);
1485   Node* const index = Parameter(1);
1486   Node* const value = Parameter(2);
1487   Node* const effect = graph()->start();
1488   Node* const control = graph()->start();
1489   TRACED_FOREACH(uint32_t, x, kUint32Values) {
1490     Node* const node =
1491         graph()->NewNode(machine()->Store(rep), base, index,
1492                          graph()->NewNode(machine()->Word32And(), value,
1493                                           Uint32Constant(x | 0xffu)),
1494                          effect, control);
1495
1496     Reduction r = Reduce(node);
1497     ASSERT_TRUE(r.Changed());
1498     EXPECT_THAT(r.replacement(),
1499                 IsStore(rep, base, index, value, effect, control));
1500   }
1501 }
1502
1503
1504 TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32SarAndWord32Shl) {
1505   const StoreRepresentation rep(kRepWord8, kNoWriteBarrier);
1506   Node* const base = Parameter(0);
1507   Node* const index = Parameter(1);
1508   Node* const value = Parameter(2);
1509   Node* const effect = graph()->start();
1510   Node* const control = graph()->start();
1511   TRACED_FORRANGE(int32_t, x, 1, 24) {
1512     Node* const node = graph()->NewNode(
1513         machine()->Store(rep), base, index,
1514         graph()->NewNode(
1515             machine()->Word32Sar(),
1516             graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
1517             Int32Constant(x)),
1518         effect, control);
1519
1520     Reduction r = Reduce(node);
1521     ASSERT_TRUE(r.Changed());
1522     EXPECT_THAT(r.replacement(),
1523                 IsStore(rep, base, index, value, effect, control));
1524   }
1525 }
1526
1527
1528 TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32And) {
1529   const StoreRepresentation rep(kRepWord16, kNoWriteBarrier);
1530   Node* const base = Parameter(0);
1531   Node* const index = Parameter(1);
1532   Node* const value = Parameter(2);
1533   Node* const effect = graph()->start();
1534   Node* const control = graph()->start();
1535   TRACED_FOREACH(uint32_t, x, kUint32Values) {
1536     Node* const node =
1537         graph()->NewNode(machine()->Store(rep), base, index,
1538                          graph()->NewNode(machine()->Word32And(), value,
1539                                           Uint32Constant(x | 0xffffu)),
1540                          effect, control);
1541
1542     Reduction r = Reduce(node);
1543     ASSERT_TRUE(r.Changed());
1544     EXPECT_THAT(r.replacement(),
1545                 IsStore(rep, base, index, value, effect, control));
1546   }
1547 }
1548
1549
1550 TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32SarAndWord32Shl) {
1551   const StoreRepresentation rep(kRepWord16, kNoWriteBarrier);
1552   Node* const base = Parameter(0);
1553   Node* const index = Parameter(1);
1554   Node* const value = Parameter(2);
1555   Node* const effect = graph()->start();
1556   Node* const control = graph()->start();
1557   TRACED_FORRANGE(int32_t, x, 1, 16) {
1558     Node* const node = graph()->NewNode(
1559         machine()->Store(rep), base, index,
1560         graph()->NewNode(
1561             machine()->Word32Sar(),
1562             graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
1563             Int32Constant(x)),
1564         effect, control);
1565
1566     Reduction r = Reduce(node);
1567     ASSERT_TRUE(r.Changed());
1568     EXPECT_THAT(r.replacement(),
1569                 IsStore(rep, base, index, value, effect, control));
1570   }
1571 }
1572
1573 }  // namespace compiler
1574 }  // namespace internal
1575 }  // namespace v8