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