blob: 2feba2ef7f56f7f699e386b340d25dec2376a2a5 [file] [log] [blame]
Emily Bernierd0a1eb72015-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 Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/conversions-inl.h"
Emily Bernierd0a1eb72015-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 Murdoch4a90d5f2016-03-22 12:00:34 +000032 JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
33 &machine_);
Emily Bernierd0a1eb72015-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 Murdoch4a90d5f2016-03-22 12:00:34 +000072 ~MachineOperatorReducerTestWithParam() override {}
Emily Bernierd0a1eb72015-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 Murdoch4a90d5f2016-03-22 12:00:34 +0000238
239const TruncationMode kTruncationModes[] = {TruncationMode::kJavaScript,
240 TruncationMode::kRoundToZero};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400241
242
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000243struct ComparisonBinaryOperator {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400244 const Operator* (MachineOperatorBuilder::*constructor)();
245 const char* constructor_name;
246};
247
248
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000249std::ostream& operator<<(std::ostream& os,
250 ComparisonBinaryOperator const& cbop) {
251 return os << cbop.constructor_name;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400252}
253
254
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000255const ComparisonBinaryOperator kComparisonBinaryOperators[] = {
256#define OPCODE(Opcode) \
257 { &MachineOperatorBuilder::Opcode, #Opcode } \
258 ,
259 MACHINE_COMPARE_BINOP_LIST(OPCODE)
260#undef OPCODE
261};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400262
263} // namespace
264
265
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400266// -----------------------------------------------------------------------------
267// ChangeFloat64ToFloat32
268
269
270TEST_F(MachineOperatorReducerTest, ChangeFloat64ToFloat32WithConstant) {
271 TRACED_FOREACH(float, x, kFloat32Values) {
272 Reduction reduction = Reduce(graph()->NewNode(
273 machine()->ChangeFloat32ToFloat64(), Float32Constant(x)));
274 ASSERT_TRUE(reduction.Changed());
275 EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq<double>(x)));
276 }
277}
278
279
280// -----------------------------------------------------------------------------
281// ChangeFloat64ToInt32
282
283
284TEST_F(MachineOperatorReducerTest,
285 ChangeFloat64ToInt32WithChangeInt32ToFloat64) {
286 Node* value = Parameter(0);
287 Reduction reduction = Reduce(graph()->NewNode(
288 machine()->ChangeFloat64ToInt32(),
289 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
290 ASSERT_TRUE(reduction.Changed());
291 EXPECT_EQ(value, reduction.replacement());
292}
293
294
295TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt32WithConstant) {
296 TRACED_FOREACH(int32_t, x, kInt32Values) {
297 Reduction reduction = Reduce(graph()->NewNode(
298 machine()->ChangeFloat64ToInt32(), Float64Constant(FastI2D(x))));
299 ASSERT_TRUE(reduction.Changed());
300 EXPECT_THAT(reduction.replacement(), IsInt32Constant(x));
301 }
302}
303
304
305// -----------------------------------------------------------------------------
306// ChangeFloat64ToUint32
307
308
309TEST_F(MachineOperatorReducerTest,
310 ChangeFloat64ToUint32WithChangeUint32ToFloat64) {
311 Node* value = Parameter(0);
312 Reduction reduction = Reduce(graph()->NewNode(
313 machine()->ChangeFloat64ToUint32(),
314 graph()->NewNode(machine()->ChangeUint32ToFloat64(), value)));
315 ASSERT_TRUE(reduction.Changed());
316 EXPECT_EQ(value, reduction.replacement());
317}
318
319
320TEST_F(MachineOperatorReducerTest, ChangeFloat64ToUint32WithConstant) {
321 TRACED_FOREACH(uint32_t, x, kUint32Values) {
322 Reduction reduction = Reduce(graph()->NewNode(
323 machine()->ChangeFloat64ToUint32(), Float64Constant(FastUI2D(x))));
324 ASSERT_TRUE(reduction.Changed());
325 EXPECT_THAT(reduction.replacement(), IsInt32Constant(bit_cast<int32_t>(x)));
326 }
327}
328
329
330// -----------------------------------------------------------------------------
331// ChangeInt32ToFloat64
332
333
334TEST_F(MachineOperatorReducerTest, ChangeInt32ToFloat64WithConstant) {
335 TRACED_FOREACH(int32_t, x, kInt32Values) {
336 Reduction reduction = Reduce(
337 graph()->NewNode(machine()->ChangeInt32ToFloat64(), Int32Constant(x)));
338 ASSERT_TRUE(reduction.Changed());
339 EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastI2D(x))));
340 }
341}
342
343
344// -----------------------------------------------------------------------------
345// ChangeInt32ToInt64
346
347
348TEST_F(MachineOperatorReducerTest, ChangeInt32ToInt64WithConstant) {
349 TRACED_FOREACH(int32_t, x, kInt32Values) {
350 Reduction reduction = Reduce(
351 graph()->NewNode(machine()->ChangeInt32ToInt64(), Int32Constant(x)));
352 ASSERT_TRUE(reduction.Changed());
353 EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
354 }
355}
356
357
358// -----------------------------------------------------------------------------
359// ChangeUint32ToFloat64
360
361
362TEST_F(MachineOperatorReducerTest, ChangeUint32ToFloat64WithConstant) {
363 TRACED_FOREACH(uint32_t, x, kUint32Values) {
364 Reduction reduction =
365 Reduce(graph()->NewNode(machine()->ChangeUint32ToFloat64(),
366 Int32Constant(bit_cast<int32_t>(x))));
367 ASSERT_TRUE(reduction.Changed());
368 EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastUI2D(x))));
369 }
370}
371
372
373// -----------------------------------------------------------------------------
374// ChangeUint32ToUint64
375
376
377TEST_F(MachineOperatorReducerTest, ChangeUint32ToUint64WithConstant) {
378 TRACED_FOREACH(uint32_t, x, kUint32Values) {
379 Reduction reduction =
380 Reduce(graph()->NewNode(machine()->ChangeUint32ToUint64(),
381 Int32Constant(bit_cast<int32_t>(x))));
382 ASSERT_TRUE(reduction.Changed());
383 EXPECT_THAT(reduction.replacement(),
384 IsInt64Constant(bit_cast<int64_t>(static_cast<uint64_t>(x))));
385 }
386}
387
388
389// -----------------------------------------------------------------------------
390// TruncateFloat64ToFloat32
391
392
393TEST_F(MachineOperatorReducerTest,
394 TruncateFloat64ToFloat32WithChangeFloat32ToFloat64) {
395 Node* value = Parameter(0);
396 Reduction reduction = Reduce(graph()->NewNode(
397 machine()->TruncateFloat64ToFloat32(),
398 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), value)));
399 ASSERT_TRUE(reduction.Changed());
400 EXPECT_EQ(value, reduction.replacement());
401}
402
403
404TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
405 TRACED_FOREACH(double, x, kFloat64Values) {
406 Reduction reduction = Reduce(graph()->NewNode(
407 machine()->TruncateFloat64ToFloat32(), Float64Constant(x)));
408 ASSERT_TRUE(reduction.Changed());
409 EXPECT_THAT(reduction.replacement(),
410 IsFloat32Constant(BitEq(DoubleToFloat32(x))));
411 }
412}
413
414
415// -----------------------------------------------------------------------------
416// TruncateFloat64ToInt32
417
418
419TEST_F(MachineOperatorReducerTest,
420 TruncateFloat64ToInt32WithChangeInt32ToFloat64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000421 TRACED_FOREACH(TruncationMode, mode, kTruncationModes) {
422 Node* value = Parameter(0);
423 Reduction reduction = Reduce(graph()->NewNode(
424 machine()->TruncateFloat64ToInt32(mode),
425 graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
426 ASSERT_TRUE(reduction.Changed());
427 EXPECT_EQ(value, reduction.replacement());
428 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400429}
430
431
432TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithConstant) {
433 TRACED_FOREACH(double, x, kFloat64Values) {
434 Reduction reduction = Reduce(graph()->NewNode(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000435 machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript),
436 Float64Constant(x)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400437 ASSERT_TRUE(reduction.Changed());
438 EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
439 }
440}
441
442
443TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithPhi) {
444 Node* const p0 = Parameter(0);
445 Node* const p1 = Parameter(1);
446 Node* const merge = graph()->start();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000447 TRACED_FOREACH(TruncationMode, mode, kTruncationModes) {
448 Reduction reduction = Reduce(graph()->NewNode(
449 machine()->TruncateFloat64ToInt32(mode),
450 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), p0,
451 p1, merge)));
452 ASSERT_TRUE(reduction.Changed());
453 EXPECT_THAT(
454 reduction.replacement(),
455 IsPhi(MachineRepresentation::kWord32, IsTruncateFloat64ToInt32(p0),
456 IsTruncateFloat64ToInt32(p1), merge));
457 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400458}
459
460
461// -----------------------------------------------------------------------------
462// TruncateInt64ToInt32
463
464
465TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithChangeInt32ToInt64) {
466 Node* value = Parameter(0);
467 Reduction reduction = Reduce(graph()->NewNode(
468 machine()->TruncateInt64ToInt32(),
469 graph()->NewNode(machine()->ChangeInt32ToInt64(), value)));
470 ASSERT_TRUE(reduction.Changed());
471 EXPECT_EQ(value, reduction.replacement());
472}
473
474
475TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithConstant) {
476 TRACED_FOREACH(int64_t, x, kInt64Values) {
477 Reduction reduction = Reduce(
478 graph()->NewNode(machine()->TruncateInt64ToInt32(), Int64Constant(x)));
479 ASSERT_TRUE(reduction.Changed());
480 EXPECT_THAT(reduction.replacement(),
481 IsInt32Constant(bit_cast<int32_t>(
482 static_cast<uint32_t>(bit_cast<uint64_t>(x)))));
483 }
484}
485
486
487// -----------------------------------------------------------------------------
488// Word32And
489
490
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000491TEST_F(MachineOperatorReducerTest, Word32AndWithWord32ShlWithConstant) {
492 Node* const p0 = Parameter(0);
493
494 TRACED_FORRANGE(int32_t, l, 1, 31) {
495 TRACED_FORRANGE(int32_t, k, 1, l) {
496 // (x << L) & (-1 << K) => x << L
497 Reduction const r1 = Reduce(graph()->NewNode(
498 machine()->Word32And(),
499 graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(l)),
500 Int32Constant(-1 << k)));
501 ASSERT_TRUE(r1.Changed());
502 EXPECT_THAT(r1.replacement(), IsWord32Shl(p0, IsInt32Constant(l)));
503
504 // (-1 << K) & (x << L) => x << L
505 Reduction const r2 = Reduce(graph()->NewNode(
506 machine()->Word32And(), Int32Constant(-1 << k),
507 graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(l))));
508 ASSERT_TRUE(r2.Changed());
509 EXPECT_THAT(r2.replacement(), IsWord32Shl(p0, IsInt32Constant(l)));
510 }
511 }
512}
513
514
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400515TEST_F(MachineOperatorReducerTest, Word32AndWithWord32AndWithConstant) {
516 Node* const p0 = Parameter(0);
517
518 TRACED_FOREACH(int32_t, k, kInt32Values) {
519 TRACED_FOREACH(int32_t, l, kInt32Values) {
520 if (k == 0 || k == -1 || l == 0 || l == -1) continue;
521
522 // (x & K) & L => x & (K & L)
523 Reduction const r1 = Reduce(graph()->NewNode(
524 machine()->Word32And(),
525 graph()->NewNode(machine()->Word32And(), p0, Int32Constant(k)),
526 Int32Constant(l)));
527 ASSERT_TRUE(r1.Changed());
528 EXPECT_THAT(r1.replacement(),
529 (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
530 : IsInt32Constant(0));
531
532 // (K & x) & L => x & (K & L)
533 Reduction const r2 = Reduce(graph()->NewNode(
534 machine()->Word32And(),
535 graph()->NewNode(machine()->Word32And(), Int32Constant(k), p0),
536 Int32Constant(l)));
537 ASSERT_TRUE(r2.Changed());
538 EXPECT_THAT(r2.replacement(),
539 (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
540 : IsInt32Constant(0));
541 }
542 }
543}
544
545
546TEST_F(MachineOperatorReducerTest, Word32AndWithInt32AddAndConstant) {
547 Node* const p0 = Parameter(0);
548 Node* const p1 = Parameter(1);
549
550 TRACED_FORRANGE(int32_t, l, 1, 31) {
551 TRACED_FOREACH(int32_t, k, kInt32Values) {
552 if ((k << l) == 0) continue;
553 // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
554 Reduction const r = Reduce(graph()->NewNode(
555 machine()->Word32And(),
556 graph()->NewNode(machine()->Int32Add(), p0, Int32Constant(k << l)),
557 Int32Constant(-1 << l)));
558 ASSERT_TRUE(r.Changed());
559 EXPECT_THAT(r.replacement(),
560 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
561 IsInt32Constant(k << l)));
562 }
563
564 Node* s1 = graph()->NewNode(machine()->Word32Shl(), p1, Int32Constant(l));
565
566 // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
567 Reduction const r1 = Reduce(graph()->NewNode(
568 machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), s1, p0),
569 Int32Constant(-1 << l)));
570 ASSERT_TRUE(r1.Changed());
571 EXPECT_THAT(r1.replacement(),
572 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)), s1));
573
574 // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
575 Reduction const r2 = Reduce(graph()->NewNode(
576 machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), p0, s1),
577 Int32Constant(-1 << l)));
578 ASSERT_TRUE(r2.Changed());
579 EXPECT_THAT(r2.replacement(),
580 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)), s1));
581 }
582}
583
584
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000585TEST_F(MachineOperatorReducerTest, Word32AndWithInt32MulAndConstant) {
586 Node* const p0 = Parameter(0);
587
588 TRACED_FORRANGE(int32_t, l, 1, 31) {
589 TRACED_FOREACH(int32_t, k, kInt32Values) {
590 if ((k << l) == 0) continue;
591
592 // (x * (K << L)) & (-1 << L) => x * (K << L)
593 Reduction const r1 = Reduce(graph()->NewNode(
594 machine()->Word32And(),
595 graph()->NewNode(machine()->Int32Mul(), p0, Int32Constant(k << l)),
596 Int32Constant(-1 << l)));
597 ASSERT_TRUE(r1.Changed());
598 EXPECT_THAT(r1.replacement(), IsInt32Mul(p0, IsInt32Constant(k << l)));
599
600 // ((K << L) * x) & (-1 << L) => x * (K << L)
601 Reduction const r2 = Reduce(graph()->NewNode(
602 machine()->Word32And(),
603 graph()->NewNode(machine()->Int32Mul(), Int32Constant(k << l), p0),
604 Int32Constant(-1 << l)));
605 ASSERT_TRUE(r2.Changed());
606 EXPECT_THAT(r2.replacement(), IsInt32Mul(p0, IsInt32Constant(k << l)));
607 }
608 }
609}
610
611
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400612TEST_F(MachineOperatorReducerTest,
613 Word32AndWithInt32AddAndInt32MulAndConstant) {
614 Node* const p0 = Parameter(0);
615 Node* const p1 = Parameter(1);
616
617 TRACED_FORRANGE(int32_t, l, 1, 31) {
618 TRACED_FOREACH(int32_t, k, kInt32Values) {
619 if ((k << l) == 0) continue;
620 // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
621 Reduction const r1 = Reduce(graph()->NewNode(
622 machine()->Word32And(),
623 graph()->NewNode(machine()->Int32Add(),
624 graph()->NewNode(machine()->Int32Mul(), p1,
625 Int32Constant(k << l)),
626 p0),
627 Int32Constant(-1 << l)));
628 ASSERT_TRUE(r1.Changed());
629 EXPECT_THAT(r1.replacement(),
630 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
631 IsInt32Mul(p1, IsInt32Constant(k << l))));
632
633 // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
634 Reduction const r2 = Reduce(graph()->NewNode(
635 machine()->Word32And(),
636 graph()->NewNode(machine()->Int32Add(), p0,
637 graph()->NewNode(machine()->Int32Mul(), p1,
638 Int32Constant(k << l))),
639 Int32Constant(-1 << l)));
640 ASSERT_TRUE(r2.Changed());
641 EXPECT_THAT(r2.replacement(),
642 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
643 IsInt32Mul(p1, IsInt32Constant(k << l))));
644 }
645 }
646}
647
648
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000649TEST_F(MachineOperatorReducerTest, Word32AndWithComparisonAndConstantOne) {
650 Node* const p0 = Parameter(0);
651 Node* const p1 = Parameter(1);
652 TRACED_FOREACH(ComparisonBinaryOperator, cbop, kComparisonBinaryOperators) {
653 Node* cmp = graph()->NewNode((machine()->*cbop.constructor)(), p0, p1);
654
655 // cmp & 1 => cmp
656 Reduction const r1 =
657 Reduce(graph()->NewNode(machine()->Word32And(), cmp, Int32Constant(1)));
658 ASSERT_TRUE(r1.Changed());
659 EXPECT_EQ(cmp, r1.replacement());
660
661 // 1 & cmp => cmp
662 Reduction const r2 =
663 Reduce(graph()->NewNode(machine()->Word32And(), Int32Constant(1), cmp));
664 ASSERT_TRUE(r2.Changed());
665 EXPECT_EQ(cmp, r2.replacement());
666 }
667}
668
669
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400670// -----------------------------------------------------------------------------
671// Word32Xor
672
673
674TEST_F(MachineOperatorReducerTest, Word32XorWithWord32XorAndMinusOne) {
675 Node* const p0 = Parameter(0);
676
677 // (x ^ -1) ^ -1 => x
678 Reduction r1 = Reduce(graph()->NewNode(
679 machine()->Word32Xor(),
680 graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1)),
681 Int32Constant(-1)));
682 ASSERT_TRUE(r1.Changed());
683 EXPECT_EQ(r1.replacement(), p0);
684
685 // -1 ^ (x ^ -1) => x
686 Reduction r2 = Reduce(graph()->NewNode(
687 machine()->Word32Xor(), Int32Constant(-1),
688 graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1))));
689 ASSERT_TRUE(r2.Changed());
690 EXPECT_EQ(r2.replacement(), p0);
691
692 // (-1 ^ x) ^ -1 => x
693 Reduction r3 = Reduce(graph()->NewNode(
694 machine()->Word32Xor(),
695 graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0),
696 Int32Constant(-1)));
697 ASSERT_TRUE(r3.Changed());
698 EXPECT_EQ(r3.replacement(), p0);
699
700 // -1 ^ (-1 ^ x) => x
701 Reduction r4 = Reduce(graph()->NewNode(
702 machine()->Word32Xor(), Int32Constant(-1),
703 graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0)));
704 ASSERT_TRUE(r4.Changed());
705 EXPECT_EQ(r4.replacement(), p0);
706}
707
708
709// -----------------------------------------------------------------------------
710// Word32Ror
711
712
713TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
714 Node* value = Parameter(0);
715 Node* shift = Parameter(1);
716 Node* sub = graph()->NewNode(machine()->Int32Sub(), Int32Constant(32), shift);
717
718 // Testing rotate left.
719 Node* shl_l = graph()->NewNode(machine()->Word32Shl(), value, shift);
720 Node* shr_l = graph()->NewNode(machine()->Word32Shr(), value, sub);
721
722 // (x << y) | (x >>> (32 - y)) => x ror (32 - y)
723 Node* node1 = graph()->NewNode(machine()->Word32Or(), shl_l, shr_l);
724 Reduction reduction1 = Reduce(node1);
725 EXPECT_TRUE(reduction1.Changed());
726 EXPECT_EQ(reduction1.replacement(), node1);
727 EXPECT_THAT(reduction1.replacement(), IsWord32Ror(value, sub));
728
729 // (x >>> (32 - y)) | (x << y) => x ror (32 - y)
730 Node* node2 = graph()->NewNode(machine()->Word32Or(), shr_l, shl_l);
731 Reduction reduction2 = Reduce(node2);
732 EXPECT_TRUE(reduction2.Changed());
733 EXPECT_EQ(reduction2.replacement(), node2);
734 EXPECT_THAT(reduction2.replacement(), IsWord32Ror(value, sub));
735
736 // Testing rotate right.
737 Node* shl_r = graph()->NewNode(machine()->Word32Shl(), value, sub);
738 Node* shr_r = graph()->NewNode(machine()->Word32Shr(), value, shift);
739
740 // (x << (32 - y)) | (x >>> y) => x ror y
741 Node* node3 = graph()->NewNode(machine()->Word32Or(), shl_r, shr_r);
742 Reduction reduction3 = Reduce(node3);
743 EXPECT_TRUE(reduction3.Changed());
744 EXPECT_EQ(reduction3.replacement(), node3);
745 EXPECT_THAT(reduction3.replacement(), IsWord32Ror(value, shift));
746
747 // (x >>> y) | (x << (32 - y)) => x ror y
748 Node* node4 = graph()->NewNode(machine()->Word32Or(), shr_r, shl_r);
749 Reduction reduction4 = Reduce(node4);
750 EXPECT_TRUE(reduction4.Changed());
751 EXPECT_EQ(reduction4.replacement(), node4);
752 EXPECT_THAT(reduction4.replacement(), IsWord32Ror(value, shift));
753}
754
755
756TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
757 Node* value = Parameter(0);
758 TRACED_FORRANGE(int32_t, k, 0, 31) {
759 Node* shl =
760 graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(k));
761 Node* shr =
762 graph()->NewNode(machine()->Word32Shr(), value, Int32Constant(32 - k));
763
764 // (x << K) | (x >>> ((32 - K) - y)) => x ror (32 - K)
765 Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
766 Reduction reduction1 = Reduce(node1);
767 EXPECT_TRUE(reduction1.Changed());
768 EXPECT_EQ(reduction1.replacement(), node1);
769 EXPECT_THAT(reduction1.replacement(),
770 IsWord32Ror(value, IsInt32Constant(32 - k)));
771
772 // (x >>> (32 - K)) | (x << K) => x ror (32 - K)
773 Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
774 Reduction reduction2 = Reduce(node2);
775 EXPECT_TRUE(reduction2.Changed());
776 EXPECT_EQ(reduction2.replacement(), node2);
777 EXPECT_THAT(reduction2.replacement(),
778 IsWord32Ror(value, IsInt32Constant(32 - k)));
779 }
780}
781
782
783TEST_F(MachineOperatorReducerTest, Word32RorWithZeroShift) {
784 Node* value = Parameter(0);
785 Node* node =
786 graph()->NewNode(machine()->Word32Ror(), value, Int32Constant(0));
787 Reduction reduction = Reduce(node);
788 EXPECT_TRUE(reduction.Changed());
789 EXPECT_EQ(reduction.replacement(), value);
790}
791
792
793TEST_F(MachineOperatorReducerTest, Word32RorWithConstants) {
794 TRACED_FOREACH(int32_t, x, kUint32Values) {
795 TRACED_FORRANGE(int32_t, y, 0, 31) {
796 Node* node = graph()->NewNode(machine()->Word32Ror(), Int32Constant(x),
797 Int32Constant(y));
798 Reduction reduction = Reduce(node);
799 EXPECT_TRUE(reduction.Changed());
800 EXPECT_THAT(reduction.replacement(),
801 IsInt32Constant(base::bits::RotateRight32(x, y)));
802 }
803 }
804}
805
806
807// -----------------------------------------------------------------------------
808// Word32Sar
809
810
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000811TEST_F(MachineOperatorReducerTest, Word32SarWithWord32ShlAndComparison) {
812 Node* const p0 = Parameter(0);
813 Node* const p1 = Parameter(1);
814
815 TRACED_FOREACH(ComparisonBinaryOperator, cbop, kComparisonBinaryOperators) {
816 Node* cmp = graph()->NewNode((machine()->*cbop.constructor)(), p0, p1);
817
818 // cmp << 31 >> 31 => 0 - cmp
819 Reduction const r = Reduce(graph()->NewNode(
820 machine()->Word32Sar(),
821 graph()->NewNode(machine()->Word32Shl(), cmp, Int32Constant(31)),
822 Int32Constant(31)));
823 ASSERT_TRUE(r.Changed());
824 EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0), cmp));
825 }
826}
827
828
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400829TEST_F(MachineOperatorReducerTest, Word32SarWithWord32ShlAndLoad) {
830 Node* const p0 = Parameter(0);
831 Node* const p1 = Parameter(1);
832 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000833 Node* const l = graph()->NewNode(machine()->Load(MachineType::Int8()), p0,
834 p1, graph()->start(), graph()->start());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400835 Reduction const r = Reduce(graph()->NewNode(
836 machine()->Word32Sar(),
837 graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(24)),
838 Int32Constant(24)));
839 ASSERT_TRUE(r.Changed());
840 EXPECT_EQ(l, r.replacement());
841 }
842 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000843 Node* const l = graph()->NewNode(machine()->Load(MachineType::Int16()), p0,
844 p1, graph()->start(), graph()->start());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400845 Reduction const r = Reduce(graph()->NewNode(
846 machine()->Word32Sar(),
847 graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(16)),
848 Int32Constant(16)));
849 ASSERT_TRUE(r.Changed());
850 EXPECT_EQ(l, r.replacement());
851 }
852}
853
854
855// -----------------------------------------------------------------------------
856// Word32Shl
857
858
859TEST_F(MachineOperatorReducerTest, Word32ShlWithZeroShift) {
860 Node* p0 = Parameter(0);
861 Node* node = graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(0));
862 Reduction r = Reduce(node);
863 ASSERT_TRUE(r.Changed());
864 EXPECT_EQ(p0, r.replacement());
865}
866
867
868TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Sar) {
869 Node* p0 = Parameter(0);
870 TRACED_FORRANGE(int32_t, x, 1, 31) {
871 Node* node = graph()->NewNode(
872 machine()->Word32Shl(),
873 graph()->NewNode(machine()->Word32Sar(), p0, Int32Constant(x)),
874 Int32Constant(x));
875 Reduction r = Reduce(node);
876 ASSERT_TRUE(r.Changed());
877 int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
878 EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
879 }
880}
881
882
883TEST_F(MachineOperatorReducerTest,
884 Word32ShlWithWord32SarAndInt32AddAndConstant) {
885 Node* const p0 = Parameter(0);
886 TRACED_FOREACH(int32_t, k, kInt32Values) {
887 TRACED_FORRANGE(int32_t, l, 1, 31) {
888 if ((k << l) == 0) continue;
889 // (x + (K << L)) >> L << L => (x & (-1 << L)) + (K << L)
890 Reduction const r = Reduce(graph()->NewNode(
891 machine()->Word32Shl(),
892 graph()->NewNode(machine()->Word32Sar(),
893 graph()->NewNode(machine()->Int32Add(), p0,
894 Int32Constant(k << l)),
895 Int32Constant(l)),
896 Int32Constant(l)));
897 ASSERT_TRUE(r.Changed());
898 EXPECT_THAT(r.replacement(),
899 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
900 IsInt32Constant(k << l)));
901 }
902 }
903}
904
905
906TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Shr) {
907 Node* p0 = Parameter(0);
908 TRACED_FORRANGE(int32_t, x, 1, 31) {
909 Node* node = graph()->NewNode(
910 machine()->Word32Shl(),
911 graph()->NewNode(machine()->Word32Shr(), p0, Int32Constant(x)),
912 Int32Constant(x));
913 Reduction r = Reduce(node);
914 ASSERT_TRUE(r.Changed());
915 int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
916 EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
917 }
918}
919
920
921// -----------------------------------------------------------------------------
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000922// Int32Sub
923
924
925TEST_F(MachineOperatorReducerTest, Int32SubWithConstant) {
926 Node* const p0 = Parameter(0);
927 TRACED_FOREACH(int32_t, k, kInt32Values) {
928 Reduction const r =
929 Reduce(graph()->NewNode(machine()->Int32Sub(), p0, Int32Constant(k)));
930 ASSERT_TRUE(r.Changed());
931 if (k == 0) {
932 EXPECT_EQ(p0, r.replacement());
933 } else {
934 EXPECT_THAT(r.replacement(), IsInt32Add(p0, IsInt32Constant(-k)));
935 }
936 }
937}
938
939
940// -----------------------------------------------------------------------------
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400941// Int32Div
942
943
944TEST_F(MachineOperatorReducerTest, Int32DivWithConstant) {
945 Node* const p0 = Parameter(0);
946 {
947 Reduction const r = Reduce(graph()->NewNode(
948 machine()->Int32Div(), p0, Int32Constant(0), graph()->start()));
949 ASSERT_TRUE(r.Changed());
950 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
951 }
952 {
953 Reduction const r = Reduce(graph()->NewNode(
954 machine()->Int32Div(), p0, Int32Constant(1), graph()->start()));
955 ASSERT_TRUE(r.Changed());
956 EXPECT_EQ(r.replacement(), p0);
957 }
958 {
959 Reduction const r = Reduce(graph()->NewNode(
960 machine()->Int32Div(), p0, Int32Constant(-1), graph()->start()));
961 ASSERT_TRUE(r.Changed());
962 EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0), p0));
963 }
964 {
965 Reduction const r = Reduce(graph()->NewNode(
966 machine()->Int32Div(), p0, Int32Constant(2), graph()->start()));
967 ASSERT_TRUE(r.Changed());
968 EXPECT_THAT(
969 r.replacement(),
970 IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
971 IsInt32Constant(1)));
972 }
973 {
974 Reduction const r = Reduce(graph()->NewNode(
975 machine()->Int32Div(), p0, Int32Constant(-2), graph()->start()));
976 ASSERT_TRUE(r.Changed());
977 EXPECT_THAT(
978 r.replacement(),
979 IsInt32Sub(
980 IsInt32Constant(0),
981 IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
982 IsInt32Constant(1))));
983 }
984 TRACED_FORRANGE(int32_t, shift, 2, 30) {
985 Reduction const r =
986 Reduce(graph()->NewNode(machine()->Int32Div(), p0,
987 Int32Constant(1 << shift), graph()->start()));
988 ASSERT_TRUE(r.Changed());
989 EXPECT_THAT(
990 r.replacement(),
991 IsWord32Sar(IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
992 IsInt32Constant(32 - shift)),
993 p0),
994 IsInt32Constant(shift)));
995 }
996 TRACED_FORRANGE(int32_t, shift, 2, 31) {
997 Reduction const r = Reduce(graph()->NewNode(
998 machine()->Int32Div(), p0,
999 Uint32Constant(bit_cast<uint32_t, int32_t>(-1) << shift),
1000 graph()->start()));
1001 ASSERT_TRUE(r.Changed());
1002 EXPECT_THAT(
1003 r.replacement(),
1004 IsInt32Sub(
1005 IsInt32Constant(0),
1006 IsWord32Sar(
1007 IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
1008 IsInt32Constant(32 - shift)),
1009 p0),
1010 IsInt32Constant(shift))));
1011 }
1012 TRACED_FOREACH(int32_t, divisor, kInt32Values) {
1013 if (divisor < 0) {
1014 if (base::bits::IsPowerOfTwo32(-divisor)) continue;
1015 Reduction const r = Reduce(graph()->NewNode(
1016 machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
1017 ASSERT_TRUE(r.Changed());
1018 EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0),
1019 IsTruncatingDiv(p0, -divisor)));
1020 } else if (divisor > 0) {
1021 if (base::bits::IsPowerOfTwo32(divisor)) continue;
1022 Reduction const r = Reduce(graph()->NewNode(
1023 machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
1024 ASSERT_TRUE(r.Changed());
1025 EXPECT_THAT(r.replacement(), IsTruncatingDiv(p0, divisor));
1026 }
1027 }
1028}
1029
1030
1031TEST_F(MachineOperatorReducerTest, Int32DivWithParameters) {
1032 Node* const p0 = Parameter(0);
1033 Reduction const r =
1034 Reduce(graph()->NewNode(machine()->Int32Div(), p0, p0, graph()->start()));
1035 ASSERT_TRUE(r.Changed());
1036 EXPECT_THAT(
1037 r.replacement(),
1038 IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
1039}
1040
1041
1042// -----------------------------------------------------------------------------
1043// Uint32Div
1044
1045
1046TEST_F(MachineOperatorReducerTest, Uint32DivWithConstant) {
1047 Node* const p0 = Parameter(0);
1048 {
1049 Reduction const r = Reduce(graph()->NewNode(
1050 machine()->Uint32Div(), Int32Constant(0), p0, graph()->start()));
1051 ASSERT_TRUE(r.Changed());
1052 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1053 }
1054 {
1055 Reduction const r = Reduce(graph()->NewNode(
1056 machine()->Uint32Div(), p0, Int32Constant(0), graph()->start()));
1057 ASSERT_TRUE(r.Changed());
1058 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1059 }
1060 {
1061 Reduction const r = Reduce(graph()->NewNode(
1062 machine()->Uint32Div(), p0, Int32Constant(1), graph()->start()));
1063 ASSERT_TRUE(r.Changed());
1064 EXPECT_EQ(r.replacement(), p0);
1065 }
1066 TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
1067 TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
1068 Reduction const r = Reduce(
1069 graph()->NewNode(machine()->Uint32Div(), Uint32Constant(dividend),
1070 Uint32Constant(divisor), graph()->start()));
1071 ASSERT_TRUE(r.Changed());
1072 EXPECT_THAT(r.replacement(),
1073 IsInt32Constant(bit_cast<int32_t>(
1074 base::bits::UnsignedDiv32(dividend, divisor))));
1075 }
1076 }
1077 TRACED_FORRANGE(uint32_t, shift, 1, 31) {
1078 Reduction const r =
1079 Reduce(graph()->NewNode(machine()->Uint32Div(), p0,
1080 Uint32Constant(1u << shift), graph()->start()));
1081 ASSERT_TRUE(r.Changed());
1082 EXPECT_THAT(r.replacement(),
1083 IsWord32Shr(p0, IsInt32Constant(bit_cast<int32_t>(shift))));
1084 }
1085}
1086
1087
1088TEST_F(MachineOperatorReducerTest, Uint32DivWithParameters) {
1089 Node* const p0 = Parameter(0);
1090 Reduction const r = Reduce(
1091 graph()->NewNode(machine()->Uint32Div(), p0, p0, graph()->start()));
1092 ASSERT_TRUE(r.Changed());
1093 EXPECT_THAT(
1094 r.replacement(),
1095 IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
1096}
1097
1098
1099// -----------------------------------------------------------------------------
1100// Int32Mod
1101
1102
1103TEST_F(MachineOperatorReducerTest, Int32ModWithConstant) {
1104 Node* const p0 = Parameter(0);
1105 {
1106 Reduction const r = Reduce(graph()->NewNode(
1107 machine()->Int32Mod(), Int32Constant(0), p0, graph()->start()));
1108 ASSERT_TRUE(r.Changed());
1109 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1110 }
1111 {
1112 Reduction const r = Reduce(graph()->NewNode(
1113 machine()->Int32Mod(), p0, Int32Constant(0), graph()->start()));
1114 ASSERT_TRUE(r.Changed());
1115 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1116 }
1117 {
1118 Reduction const r = Reduce(graph()->NewNode(
1119 machine()->Int32Mod(), p0, Int32Constant(1), graph()->start()));
1120 ASSERT_TRUE(r.Changed());
1121 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1122 }
1123 {
1124 Reduction const r = Reduce(graph()->NewNode(
1125 machine()->Int32Mod(), p0, Int32Constant(-1), graph()->start()));
1126 ASSERT_TRUE(r.Changed());
1127 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1128 }
1129 TRACED_FOREACH(int32_t, dividend, kInt32Values) {
1130 TRACED_FOREACH(int32_t, divisor, kInt32Values) {
1131 Reduction const r = Reduce(
1132 graph()->NewNode(machine()->Int32Mod(), Int32Constant(dividend),
1133 Int32Constant(divisor), graph()->start()));
1134 ASSERT_TRUE(r.Changed());
1135 EXPECT_THAT(r.replacement(),
1136 IsInt32Constant(base::bits::SignedMod32(dividend, divisor)));
1137 }
1138 }
1139 TRACED_FORRANGE(int32_t, shift, 1, 30) {
1140 Reduction const r =
1141 Reduce(graph()->NewNode(machine()->Int32Mod(), p0,
1142 Int32Constant(1 << shift), graph()->start()));
1143 int32_t const mask = (1 << shift) - 1;
1144 ASSERT_TRUE(r.Changed());
1145 EXPECT_THAT(
1146 r.replacement(),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001147 IsSelect(MachineRepresentation::kWord32,
1148 IsInt32LessThan(p0, IsInt32Constant(0)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001149 IsInt32Sub(IsInt32Constant(0),
1150 IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
1151 IsInt32Constant(mask))),
1152 IsWord32And(p0, IsInt32Constant(mask))));
1153 }
1154 TRACED_FORRANGE(int32_t, shift, 1, 31) {
1155 Reduction const r = Reduce(graph()->NewNode(
1156 machine()->Int32Mod(), p0,
1157 Uint32Constant(bit_cast<uint32_t, int32_t>(-1) << shift),
1158 graph()->start()));
1159 int32_t const mask = bit_cast<int32_t, uint32_t>((1U << shift) - 1);
1160 ASSERT_TRUE(r.Changed());
1161 EXPECT_THAT(
1162 r.replacement(),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001163 IsSelect(MachineRepresentation::kWord32,
1164 IsInt32LessThan(p0, IsInt32Constant(0)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001165 IsInt32Sub(IsInt32Constant(0),
1166 IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
1167 IsInt32Constant(mask))),
1168 IsWord32And(p0, IsInt32Constant(mask))));
1169 }
1170 TRACED_FOREACH(int32_t, divisor, kInt32Values) {
1171 if (divisor == 0 || base::bits::IsPowerOfTwo32(Abs(divisor))) continue;
1172 Reduction const r = Reduce(graph()->NewNode(
1173 machine()->Int32Mod(), p0, Int32Constant(divisor), graph()->start()));
1174 ASSERT_TRUE(r.Changed());
1175 EXPECT_THAT(r.replacement(),
1176 IsInt32Sub(p0, IsInt32Mul(IsTruncatingDiv(p0, Abs(divisor)),
1177 IsInt32Constant(Abs(divisor)))));
1178 }
1179}
1180
1181
1182TEST_F(MachineOperatorReducerTest, Int32ModWithParameters) {
1183 Node* const p0 = Parameter(0);
1184 Reduction const r =
1185 Reduce(graph()->NewNode(machine()->Int32Mod(), p0, p0, graph()->start()));
1186 ASSERT_TRUE(r.Changed());
1187 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1188}
1189
1190
1191// -----------------------------------------------------------------------------
1192// Uint32Mod
1193
1194
1195TEST_F(MachineOperatorReducerTest, Uint32ModWithConstant) {
1196 Node* const p0 = Parameter(0);
1197 {
1198 Reduction const r = Reduce(graph()->NewNode(
1199 machine()->Uint32Mod(), p0, Int32Constant(0), graph()->start()));
1200 ASSERT_TRUE(r.Changed());
1201 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1202 }
1203 {
1204 Reduction const r = Reduce(graph()->NewNode(
1205 machine()->Uint32Mod(), Int32Constant(0), p0, graph()->start()));
1206 ASSERT_TRUE(r.Changed());
1207 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1208 }
1209 {
1210 Reduction const r = Reduce(graph()->NewNode(
1211 machine()->Uint32Mod(), p0, Int32Constant(1), graph()->start()));
1212 ASSERT_TRUE(r.Changed());
1213 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1214 }
1215 TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
1216 TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
1217 Reduction const r = Reduce(
1218 graph()->NewNode(machine()->Uint32Mod(), Uint32Constant(dividend),
1219 Uint32Constant(divisor), graph()->start()));
1220 ASSERT_TRUE(r.Changed());
1221 EXPECT_THAT(r.replacement(),
1222 IsInt32Constant(bit_cast<int32_t>(
1223 base::bits::UnsignedMod32(dividend, divisor))));
1224 }
1225 }
1226 TRACED_FORRANGE(uint32_t, shift, 1, 31) {
1227 Reduction const r =
1228 Reduce(graph()->NewNode(machine()->Uint32Mod(), p0,
1229 Uint32Constant(1u << shift), graph()->start()));
1230 ASSERT_TRUE(r.Changed());
1231 EXPECT_THAT(r.replacement(),
1232 IsWord32And(p0, IsInt32Constant(
1233 bit_cast<int32_t>((1u << shift) - 1u))));
1234 }
1235}
1236
1237
1238TEST_F(MachineOperatorReducerTest, Uint32ModWithParameters) {
1239 Node* const p0 = Parameter(0);
1240 Reduction const r = Reduce(
1241 graph()->NewNode(machine()->Uint32Mod(), p0, p0, graph()->start()));
1242 ASSERT_TRUE(r.Changed());
1243 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1244}
1245
1246
1247// -----------------------------------------------------------------------------
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001248// Int32Add
1249
1250
1251TEST_F(MachineOperatorReducerTest, Int32AddWithInt32SubWithConstantZero) {
1252 Node* const p0 = Parameter(0);
1253 Node* const p1 = Parameter(1);
1254
1255 Reduction const r1 = Reduce(graph()->NewNode(
1256 machine()->Int32Add(),
1257 graph()->NewNode(machine()->Int32Sub(), Int32Constant(0), p0), p1));
1258 ASSERT_TRUE(r1.Changed());
1259 EXPECT_THAT(r1.replacement(), IsInt32Sub(p1, p0));
1260
1261 Reduction const r2 = Reduce(graph()->NewNode(
1262 machine()->Int32Add(), p0,
1263 graph()->NewNode(machine()->Int32Sub(), Int32Constant(0), p1)));
1264 ASSERT_TRUE(r2.Changed());
1265 EXPECT_THAT(r2.replacement(), IsInt32Sub(p0, p1));
1266}
1267
1268
1269// -----------------------------------------------------------------------------
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001270// Int32AddWithOverflow
1271
1272
1273TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
1274 Node* p0 = Parameter(0);
1275 {
1276 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
1277 Int32Constant(0), p0);
1278
1279 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1280 ASSERT_TRUE(r.Changed());
1281 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1282
1283 r = Reduce(graph()->NewNode(common()->Projection(0), add));
1284 ASSERT_TRUE(r.Changed());
1285 EXPECT_EQ(p0, r.replacement());
1286 }
1287 {
1288 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
1289 Int32Constant(0));
1290
1291 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1292 ASSERT_TRUE(r.Changed());
1293 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1294
1295 r = Reduce(graph()->NewNode(common()->Projection(0), add));
1296 ASSERT_TRUE(r.Changed());
1297 EXPECT_EQ(p0, r.replacement());
1298 }
1299}
1300
1301
1302TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
1303 TRACED_FOREACH(int32_t, x, kInt32Values) {
1304 TRACED_FOREACH(int32_t, y, kInt32Values) {
1305 int32_t z;
1306 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
1307 Int32Constant(x), Int32Constant(y));
1308
1309 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1310 ASSERT_TRUE(r.Changed());
1311 EXPECT_THAT(r.replacement(),
1312 IsInt32Constant(base::bits::SignedAddOverflow32(x, y, &z)));
1313
1314 r = Reduce(graph()->NewNode(common()->Projection(0), add));
1315 ASSERT_TRUE(r.Changed());
1316 EXPECT_THAT(r.replacement(), IsInt32Constant(z));
1317 }
1318 }
1319}
1320
1321
1322// -----------------------------------------------------------------------------
1323// Int32SubWithOverflow
1324
1325
1326TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
1327 Node* p0 = Parameter(0);
1328 Node* add =
1329 graph()->NewNode(machine()->Int32SubWithOverflow(), p0, Int32Constant(0));
1330
1331 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1332 ASSERT_TRUE(r.Changed());
1333 EXPECT_THAT(r.replacement(), IsInt32Constant(0));
1334
1335 r = Reduce(graph()->NewNode(common()->Projection(0), add));
1336 ASSERT_TRUE(r.Changed());
1337 EXPECT_EQ(p0, r.replacement());
1338}
1339
1340
1341TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
1342 TRACED_FOREACH(int32_t, x, kInt32Values) {
1343 TRACED_FOREACH(int32_t, y, kInt32Values) {
1344 int32_t z;
1345 Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
1346 Int32Constant(x), Int32Constant(y));
1347
1348 Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
1349 ASSERT_TRUE(r.Changed());
1350 EXPECT_THAT(r.replacement(),
1351 IsInt32Constant(base::bits::SignedSubOverflow32(x, y, &z)));
1352
1353 r = Reduce(graph()->NewNode(common()->Projection(0), add));
1354 ASSERT_TRUE(r.Changed());
1355 EXPECT_THAT(r.replacement(), IsInt32Constant(z));
1356 }
1357 }
1358}
1359
1360
1361// -----------------------------------------------------------------------------
1362// Uint32LessThan
1363
1364
1365TEST_F(MachineOperatorReducerTest, Uint32LessThanWithWord32Sar) {
1366 Node* const p0 = Parameter(0);
1367 TRACED_FORRANGE(uint32_t, shift, 1, 3) {
1368 const uint32_t limit = (kMaxInt >> shift) - 1;
1369 Node* const node = graph()->NewNode(
1370 machine()->Uint32LessThan(),
1371 graph()->NewNode(machine()->Word32Sar(), p0, Uint32Constant(shift)),
1372 Uint32Constant(limit));
1373
1374 Reduction r = Reduce(node);
1375 ASSERT_TRUE(r.Changed());
1376 EXPECT_THAT(r.replacement(),
1377 IsUint32LessThan(
1378 p0, IsInt32Constant(bit_cast<int32_t>(limit << shift))));
1379 }
1380}
1381
1382
1383// -----------------------------------------------------------------------------
1384// Float64Mul
1385
1386
1387TEST_F(MachineOperatorReducerTest, Float64MulWithMinusOne) {
1388 Node* const p0 = Parameter(0);
1389 {
1390 Reduction r = Reduce(
1391 graph()->NewNode(machine()->Float64Mul(), p0, Float64Constant(-1.0)));
1392 ASSERT_TRUE(r.Changed());
1393 EXPECT_THAT(r.replacement(),
1394 IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
1395 }
1396 {
1397 Reduction r = Reduce(
1398 graph()->NewNode(machine()->Float64Mul(), Float64Constant(-1.0), p0));
1399 ASSERT_TRUE(r.Changed());
1400 EXPECT_THAT(r.replacement(),
1401 IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
1402 }
1403}
1404
1405
1406// -----------------------------------------------------------------------------
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001407// Float64InsertLowWord32
1408
1409
1410TEST_F(MachineOperatorReducerTest, Float64InsertLowWord32WithConstant) {
1411 TRACED_FOREACH(double, x, kFloat64Values) {
1412 TRACED_FOREACH(uint32_t, y, kUint32Values) {
1413 Reduction const r =
1414 Reduce(graph()->NewNode(machine()->Float64InsertLowWord32(),
1415 Float64Constant(x), Uint32Constant(y)));
1416 ASSERT_TRUE(r.Changed());
1417 EXPECT_THAT(
1418 r.replacement(),
1419 IsFloat64Constant(BitEq(bit_cast<double>(
1420 (bit_cast<uint64_t>(x) & V8_UINT64_C(0xFFFFFFFF00000000)) | y))));
1421 }
1422 }
1423}
1424
1425
1426// -----------------------------------------------------------------------------
1427// Float64InsertHighWord32
1428
1429
1430TEST_F(MachineOperatorReducerTest, Float64InsertHighWord32WithConstant) {
1431 TRACED_FOREACH(double, x, kFloat64Values) {
1432 TRACED_FOREACH(uint32_t, y, kUint32Values) {
1433 Reduction const r =
1434 Reduce(graph()->NewNode(machine()->Float64InsertHighWord32(),
1435 Float64Constant(x), Uint32Constant(y)));
1436 ASSERT_TRUE(r.Changed());
1437 EXPECT_THAT(r.replacement(),
1438 IsFloat64Constant(BitEq(bit_cast<double>(
1439 (bit_cast<uint64_t>(x) & V8_UINT64_C(0xFFFFFFFF)) |
1440 (static_cast<uint64_t>(y) << 32)))));
1441 }
1442 }
1443}
1444
1445
1446// -----------------------------------------------------------------------------
1447// Float64Equal
1448
1449
1450TEST_F(MachineOperatorReducerTest, Float64EqualWithFloat32Conversions) {
1451 Node* const p0 = Parameter(0);
1452 Node* const p1 = Parameter(1);
1453 Reduction const r = Reduce(graph()->NewNode(
1454 machine()->Float64Equal(),
1455 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
1456 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
1457 ASSERT_TRUE(r.Changed());
1458 EXPECT_THAT(r.replacement(), IsFloat32Equal(p0, p1));
1459}
1460
1461
1462TEST_F(MachineOperatorReducerTest, Float64EqualWithFloat32Constant) {
1463 Node* const p0 = Parameter(0);
1464 TRACED_FOREACH(float, x, kFloat32Values) {
1465 Reduction r = Reduce(graph()->NewNode(
1466 machine()->Float64Equal(),
1467 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
1468 Float64Constant(x)));
1469 ASSERT_TRUE(r.Changed());
1470 EXPECT_THAT(r.replacement(), IsFloat32Equal(p0, IsFloat32Constant(x)));
1471 }
1472}
1473
1474
1475// -----------------------------------------------------------------------------
1476// Float64LessThan
1477
1478
1479TEST_F(MachineOperatorReducerTest, Float64LessThanWithFloat32Conversions) {
1480 Node* const p0 = Parameter(0);
1481 Node* const p1 = Parameter(1);
1482 Reduction const r = Reduce(graph()->NewNode(
1483 machine()->Float64LessThan(),
1484 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
1485 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
1486 ASSERT_TRUE(r.Changed());
1487 EXPECT_THAT(r.replacement(), IsFloat32LessThan(p0, p1));
1488}
1489
1490
1491TEST_F(MachineOperatorReducerTest, Float64LessThanWithFloat32Constant) {
1492 Node* const p0 = Parameter(0);
1493 {
1494 TRACED_FOREACH(float, x, kFloat32Values) {
1495 Reduction r = Reduce(graph()->NewNode(
1496 machine()->Float64LessThan(),
1497 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
1498 Float64Constant(x)));
1499 ASSERT_TRUE(r.Changed());
1500 EXPECT_THAT(r.replacement(), IsFloat32LessThan(p0, IsFloat32Constant(x)));
1501 }
1502 }
1503 {
1504 TRACED_FOREACH(float, x, kFloat32Values) {
1505 Reduction r = Reduce(graph()->NewNode(
1506 machine()->Float64LessThan(), Float64Constant(x),
1507 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0)));
1508 ASSERT_TRUE(r.Changed());
1509 EXPECT_THAT(r.replacement(), IsFloat32LessThan(IsFloat32Constant(x), p0));
1510 }
1511 }
1512}
1513
1514
1515// -----------------------------------------------------------------------------
1516// Float64LessThanOrEqual
1517
1518
1519TEST_F(MachineOperatorReducerTest,
1520 Float64LessThanOrEqualWithFloat32Conversions) {
1521 Node* const p0 = Parameter(0);
1522 Node* const p1 = Parameter(1);
1523 Reduction const r = Reduce(graph()->NewNode(
1524 machine()->Float64LessThanOrEqual(),
1525 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
1526 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
1527 ASSERT_TRUE(r.Changed());
1528 EXPECT_THAT(r.replacement(), IsFloat32LessThanOrEqual(p0, p1));
1529}
1530
1531
1532TEST_F(MachineOperatorReducerTest, Float64LessThanOrEqualWithFloat32Constant) {
1533 Node* const p0 = Parameter(0);
1534 {
1535 TRACED_FOREACH(float, x, kFloat32Values) {
1536 Reduction r = Reduce(graph()->NewNode(
1537 machine()->Float64LessThanOrEqual(),
1538 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
1539 Float64Constant(x)));
1540 ASSERT_TRUE(r.Changed());
1541 EXPECT_THAT(r.replacement(),
1542 IsFloat32LessThanOrEqual(p0, IsFloat32Constant(x)));
1543 }
1544 }
1545 {
1546 TRACED_FOREACH(float, x, kFloat32Values) {
1547 Reduction r = Reduce(graph()->NewNode(
1548 machine()->Float64LessThanOrEqual(), Float64Constant(x),
1549 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0)));
1550 ASSERT_TRUE(r.Changed());
1551 EXPECT_THAT(r.replacement(),
1552 IsFloat32LessThanOrEqual(IsFloat32Constant(x), p0));
1553 }
1554 }
1555}
1556
1557
1558// -----------------------------------------------------------------------------
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001559// Store
1560
1561
1562TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32And) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001563 const StoreRepresentation rep(MachineRepresentation::kWord8, kNoWriteBarrier);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001564 Node* const base = Parameter(0);
1565 Node* const index = Parameter(1);
1566 Node* const value = Parameter(2);
1567 Node* const effect = graph()->start();
1568 Node* const control = graph()->start();
1569 TRACED_FOREACH(uint32_t, x, kUint32Values) {
1570 Node* const node =
1571 graph()->NewNode(machine()->Store(rep), base, index,
1572 graph()->NewNode(machine()->Word32And(), value,
1573 Uint32Constant(x | 0xffu)),
1574 effect, control);
1575
1576 Reduction r = Reduce(node);
1577 ASSERT_TRUE(r.Changed());
1578 EXPECT_THAT(r.replacement(),
1579 IsStore(rep, base, index, value, effect, control));
1580 }
1581}
1582
1583
1584TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32SarAndWord32Shl) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001585 const StoreRepresentation rep(MachineRepresentation::kWord8, kNoWriteBarrier);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001586 Node* const base = Parameter(0);
1587 Node* const index = Parameter(1);
1588 Node* const value = Parameter(2);
1589 Node* const effect = graph()->start();
1590 Node* const control = graph()->start();
1591 TRACED_FORRANGE(int32_t, x, 1, 24) {
1592 Node* const node = graph()->NewNode(
1593 machine()->Store(rep), base, index,
1594 graph()->NewNode(
1595 machine()->Word32Sar(),
1596 graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
1597 Int32Constant(x)),
1598 effect, control);
1599
1600 Reduction r = Reduce(node);
1601 ASSERT_TRUE(r.Changed());
1602 EXPECT_THAT(r.replacement(),
1603 IsStore(rep, base, index, value, effect, control));
1604 }
1605}
1606
1607
1608TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32And) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001609 const StoreRepresentation rep(MachineRepresentation::kWord16,
1610 kNoWriteBarrier);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001611 Node* const base = Parameter(0);
1612 Node* const index = Parameter(1);
1613 Node* const value = Parameter(2);
1614 Node* const effect = graph()->start();
1615 Node* const control = graph()->start();
1616 TRACED_FOREACH(uint32_t, x, kUint32Values) {
1617 Node* const node =
1618 graph()->NewNode(machine()->Store(rep), base, index,
1619 graph()->NewNode(machine()->Word32And(), value,
1620 Uint32Constant(x | 0xffffu)),
1621 effect, control);
1622
1623 Reduction r = Reduce(node);
1624 ASSERT_TRUE(r.Changed());
1625 EXPECT_THAT(r.replacement(),
1626 IsStore(rep, base, index, value, effect, control));
1627 }
1628}
1629
1630
1631TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32SarAndWord32Shl) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001632 const StoreRepresentation rep(MachineRepresentation::kWord16,
1633 kNoWriteBarrier);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001634 Node* const base = Parameter(0);
1635 Node* const index = Parameter(1);
1636 Node* const value = Parameter(2);
1637 Node* const effect = graph()->start();
1638 Node* const control = graph()->start();
1639 TRACED_FORRANGE(int32_t, x, 1, 16) {
1640 Node* const node = graph()->NewNode(
1641 machine()->Store(rep), base, index,
1642 graph()->NewNode(
1643 machine()->Word32Sar(),
1644 graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
1645 Int32Constant(x)),
1646 effect, control);
1647
1648 Reduction r = Reduce(node);
1649 ASSERT_TRUE(r.Changed());
1650 EXPECT_THAT(r.replacement(),
1651 IsStore(rep, base, index, value, effect, control));
1652 }
1653}
1654
1655} // namespace compiler
1656} // namespace internal
1657} // namespace v8