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/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"
10
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14
15 class MachineOperatorReducerTest : public GraphTest {
16 public:
MachineOperatorReducerTest(int num_parameters=2)17 explicit MachineOperatorReducerTest(int num_parameters = 2)
18 : GraphTest(num_parameters) {}
19
20 protected:
Reduce(Node * node)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
machine()29 MachineOperatorBuilder* machine() { return &machine_; }
30
31 private:
32 MachineOperatorBuilder machine_;
33 };
34
35
36 template <typename T>
37 class MachineOperatorReducerTestWithParam
38 : public MachineOperatorReducerTest,
39 public ::testing::WithParamInterface<T> {
40 public:
MachineOperatorReducerTestWithParam(int num_parameters=2)41 explicit MachineOperatorReducerTestWithParam(int num_parameters = 2)
42 : MachineOperatorReducerTest(num_parameters) {}
~MachineOperatorReducerTestWithParam()43 virtual ~MachineOperatorReducerTestWithParam() {}
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
204 struct UnaryOperator {
205 const Operator* (MachineOperatorBuilder::*constructor)();
206 const char* constructor_name;
207 };
208
209
operator <<(std::ostream & os,const UnaryOperator & unop)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>
229 MachineUnaryOperatorReducerTest;
230
231
TEST_P(MachineUnaryOperatorReducerTest,Parameter)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());
237 }
238
239
240 INSTANTIATE_TEST_CASE_P(MachineOperatorReducerTest,
241 MachineUnaryOperatorReducerTest,
242 ::testing::ValuesIn(kUnaryOperators));
243
244
245 // -----------------------------------------------------------------------------
246 // ChangeFloat64ToFloat32
247
248
TEST_F(MachineOperatorReducerTest,ChangeFloat64ToFloat32WithConstant)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
TEST_F(MachineOperatorReducerTest,ChangeFloat64ToInt32WithChangeInt32ToFloat64)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());
271 }
272
273
TEST_F(MachineOperatorReducerTest,ChangeFloat64ToInt32WithConstant)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
TEST_F(MachineOperatorReducerTest,ChangeFloat64ToUint32WithChangeUint32ToFloat64)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());
296 }
297
298
TEST_F(MachineOperatorReducerTest,ChangeFloat64ToUint32WithConstant)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
TEST_F(MachineOperatorReducerTest,ChangeInt32ToFloat64WithConstant)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
TEST_F(MachineOperatorReducerTest,ChangeInt32ToInt64WithConstant)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
TEST_F(MachineOperatorReducerTest,ChangeUint32ToFloat64WithConstant)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
TEST_F(MachineOperatorReducerTest,ChangeUint32ToUint64WithConstant)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
TEST_F(MachineOperatorReducerTest,TruncateFloat64ToFloat32WithChangeFloat32ToFloat64)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());
380 }
381
382
TEST_F(MachineOperatorReducerTest,TruncateFloat64ToFloat32WithConstant)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
TEST_F(MachineOperatorReducerTest,TruncateFloat64ToInt32WithChangeInt32ToFloat64)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());
405 }
406
407
TEST_F(MachineOperatorReducerTest,TruncateFloat64ToInt32WithConstant)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
TEST_F(MachineOperatorReducerTest,TruncateInt64ToInt32WithChangeInt32ToInt64)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
TEST_F(MachineOperatorReducerTest,TruncateInt64ToInt32WithConstant)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
TEST_F(MachineOperatorReducerTest,ReduceToWord32RorWithParameters)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
TEST_F(MachineOperatorReducerTest,ReduceToWord32RorWithConstant)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
TEST_F(MachineOperatorReducerTest,Word32RorWithZeroShift)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
TEST_F(MachineOperatorReducerTest,Word32RorWithConstants)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(),
517 IsInt32Constant(base::bits::RotateRight32(x, y)));
518 }
519 }
520 }
521
522
523 // -----------------------------------------------------------------------------
524 // Int32AddWithOverflow
525
526
TEST_F(MachineOperatorReducerTest,Int32AddWithOverflowWithZero)527 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
528 Node* p0 = Parameter(0);
529 {
530 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
531 Int32Constant(0), p0);
532
533 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
534 ASSERT_TRUE(r.Changed());
535 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
536
537 r = Reduce(graph()->NewNode(common()->Projection(0), add));
538 ASSERT_TRUE(r.Changed());
539 EXPECT_EQ(p0, r.replacement());
540 }
541 {
542 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
543 Int32Constant(0));
544
545 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
546 ASSERT_TRUE(r.Changed());
547 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
548
549 r = Reduce(graph()->NewNode(common()->Projection(0), add));
550 ASSERT_TRUE(r.Changed());
551 EXPECT_EQ(p0, r.replacement());
552 }
553 }
554
555
TEST_F(MachineOperatorReducerTest,Int32AddWithOverflowWithConstant)556 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
557 TRACED_FOREACH(int32_t, x, kInt32Values) {
558 TRACED_FOREACH(int32_t, y, kInt32Values) {
559 int32_t z;
560 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
561 Int32Constant(x), Int32Constant(y));
562
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)));
567
568 r = Reduce(graph()->NewNode(common()->Projection(0), add));
569 ASSERT_TRUE(r.Changed());
570 EXPECT_THAT(r.replacement(), IsInt32Constant(z));
571 }
572 }
573 }
574
575
576 // -----------------------------------------------------------------------------
577 // Int32SubWithOverflow
578
579
TEST_F(MachineOperatorReducerTest,Int32SubWithOverflowWithZero)580 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
581 Node* p0 = Parameter(0);
582 Node* add =
583 graph()->NewNode(machine()->Int32SubWithOverflow(), p0, Int32Constant(0));
584
585 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
586 ASSERT_TRUE(r.Changed());
587 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
588
589 r = Reduce(graph()->NewNode(common()->Projection(0), add));
590 ASSERT_TRUE(r.Changed());
591 EXPECT_EQ(p0, r.replacement());
592 }
593
594
TEST_F(MachineOperatorReducerTest,Int32SubWithOverflowWithConstant)595 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
596 TRACED_FOREACH(int32_t, x, kInt32Values) {
597 TRACED_FOREACH(int32_t, y, kInt32Values) {
598 int32_t z;
599 Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
600 Int32Constant(x), Int32Constant(y));
601
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)));
606
607 r = Reduce(graph()->NewNode(common()->Projection(0), add));
608 ASSERT_TRUE(r.Changed());
609 EXPECT_THAT(r.replacement(), IsInt32Constant(z));
610 }
611 }
612 }
613
614 } // namespace compiler
615 } // namespace internal
616 } // namespace v8
617