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