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