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.
5 #include "src/base/bits.h"
6 #include "src/compiler/graph-unittest.h"
7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/machine-operator-reducer.h"
9 #include "src/compiler/typer.h"
15 class MachineOperatorReducerTest : public GraphTest {
17 explicit MachineOperatorReducerTest(int num_parameters = 2)
18 : GraphTest(num_parameters) {}
21 Reduction Reduce(Node* node) {
23 JSOperatorBuilder javascript(zone());
24 JSGraph jsgraph(graph(), common(), &javascript, &typer, &machine_);
25 MachineOperatorReducer reducer(&jsgraph);
26 return reducer.Reduce(node);
29 MachineOperatorBuilder* machine() { return &machine_; }
32 MachineOperatorBuilder machine_;
37 class MachineOperatorReducerTestWithParam
38 : public MachineOperatorReducerTest,
39 public ::testing::WithParamInterface<T> {
41 explicit MachineOperatorReducerTestWithParam(int num_parameters = 2)
42 : MachineOperatorReducerTest(num_parameters) {}
43 virtual ~MachineOperatorReducerTestWithParam() {}
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()};
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};
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,
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};
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)};
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};
198 // -----------------------------------------------------------------------------
204 struct UnaryOperator {
205 const Operator* (MachineOperatorBuilder::*constructor)();
206 const char* constructor_name;
210 std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
211 return os << unop.constructor_name;
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"}};
228 typedef MachineOperatorReducerTestWithParam<UnaryOperator>
229 MachineUnaryOperatorReducerTest;
232 TEST_P(MachineUnaryOperatorReducerTest, Parameter) {
233 const UnaryOperator unop = GetParam();
234 Reduction reduction =
235 Reduce(graph()->NewNode((machine()->*unop.constructor)(), Parameter(0)));
236 EXPECT_FALSE(reduction.Changed());
240 INSTANTIATE_TEST_CASE_P(MachineOperatorReducerTest,
241 MachineUnaryOperatorReducerTest,
242 ::testing::ValuesIn(kUnaryOperators));
245 // -----------------------------------------------------------------------------
246 // ChangeFloat64ToFloat32
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));
259 // -----------------------------------------------------------------------------
260 // ChangeFloat64ToInt32
263 TEST_F(MachineOperatorReducerTest,
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());
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));
284 // -----------------------------------------------------------------------------
285 // ChangeFloat64ToUint32
288 TEST_F(MachineOperatorReducerTest,
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());
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)));
309 // -----------------------------------------------------------------------------
310 // ChangeInt32ToFloat64
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)));
323 // -----------------------------------------------------------------------------
324 // ChangeInt32ToInt64
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));
337 // -----------------------------------------------------------------------------
338 // ChangeUint32ToFloat64
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)));
352 // -----------------------------------------------------------------------------
353 // ChangeUint32ToUint64
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))));
368 // -----------------------------------------------------------------------------
369 // TruncateFloat64ToFloat32
372 TEST_F(MachineOperatorReducerTest,
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());
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)));
393 // -----------------------------------------------------------------------------
394 // TruncateFloat64ToInt32
397 TEST_F(MachineOperatorReducerTest,
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());
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)));
418 // -----------------------------------------------------------------------------
419 // TruncateInt64ToInt32
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());
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)))));
444 // -----------------------------------------------------------------------------
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));
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));
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));
472 TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
473 Node* value = Parameter(0);
474 TRACED_FORRANGE(int32_t, k, 0, 31) {
476 graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(k));
478 graph()->NewNode(machine()->Word32Shr(), value, Int32Constant(32 - k));
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)));
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)));
499 TEST_F(MachineOperatorReducerTest, Word32RorWithZeroShift) {
500 Node* value = Parameter(0);
502 graph()->NewNode(machine()->Word32Ror(), value, Int32Constant(0));
503 Reduction reduction = Reduce(node);
504 EXPECT_TRUE(reduction.Changed());
505 EXPECT_EQ(reduction.replacement(), value);
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),
514 Reduction reduction = Reduce(node);
515 EXPECT_TRUE(reduction.Changed());
516 EXPECT_THAT(reduction.replacement(),
517 IsInt32Constant(base::bits::RotateRight32(x, y)));
523 // -----------------------------------------------------------------------------
524 // Int32AddWithOverflow
527 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
528 Node* p0 = Parameter(0);
530 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
531 Int32Constant(0), p0);
533 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
534 ASSERT_TRUE(r.Changed());
535 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
537 r = Reduce(graph()->NewNode(common()->Projection(0), add));
538 ASSERT_TRUE(r.Changed());
539 EXPECT_EQ(p0, r.replacement());
542 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
545 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
546 ASSERT_TRUE(r.Changed());
547 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
549 r = Reduce(graph()->NewNode(common()->Projection(0), add));
550 ASSERT_TRUE(r.Changed());
551 EXPECT_EQ(p0, r.replacement());
556 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
557 TRACED_FOREACH(int32_t, x, kInt32Values) {
558 TRACED_FOREACH(int32_t, y, kInt32Values) {
560 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
561 Int32Constant(x), Int32Constant(y));
563 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
564 ASSERT_TRUE(r.Changed());
565 EXPECT_THAT(r.replacement(),
566 IsInt32Constant(base::bits::SignedAddOverflow32(x, y, &z)));
568 r = Reduce(graph()->NewNode(common()->Projection(0), add));
569 ASSERT_TRUE(r.Changed());
570 EXPECT_THAT(r.replacement(), IsInt32Constant(z));
576 // -----------------------------------------------------------------------------
577 // Int32SubWithOverflow
580 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
581 Node* p0 = Parameter(0);
583 graph()->NewNode(machine()->Int32SubWithOverflow(), p0, Int32Constant(0));
585 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
586 ASSERT_TRUE(r.Changed());
587 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
589 r = Reduce(graph()->NewNode(common()->Projection(0), add));
590 ASSERT_TRUE(r.Changed());
591 EXPECT_EQ(p0, r.replacement());
595 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
596 TRACED_FOREACH(int32_t, x, kInt32Values) {
597 TRACED_FOREACH(int32_t, y, kInt32Values) {
599 Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
600 Int32Constant(x), Int32Constant(y));
602 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
603 ASSERT_TRUE(r.Changed());
604 EXPECT_THAT(r.replacement(),
605 IsInt32Constant(base::bits::SignedSubOverflow32(x, y, &z)));
607 r = Reduce(graph()->NewNode(common()->Projection(0), add));
608 ASSERT_TRUE(r.Changed());
609 EXPECT_THAT(r.replacement(), IsInt32Constant(z));
614 } // namespace compiler
615 } // namespace internal