1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "src/compiler/access-builder.h"
6 #include "src/compiler/js-graph.h"
7 #include "src/compiler/node-properties.h"
8 #include "src/compiler/simplified-operator.h"
9 #include "src/compiler/simplified-operator-reducer.h"
10 #include "src/conversions.h"
11 #include "src/types.h"
12 #include "test/unittests/compiler/graph-unittest.h"
13 #include "test/unittests/compiler/node-test-utils.h"
14 #include "testing/gmock-support.h"
23 class SimplifiedOperatorReducerTest : public TypedGraphTest {
25 explicit SimplifiedOperatorReducerTest(int num_parameters = 1)
26 : TypedGraphTest(num_parameters), simplified_(zone()) {}
27 ~SimplifiedOperatorReducerTest() OVERRIDE {}
30 Reduction Reduce(Node* node) {
31 MachineOperatorBuilder machine(zone());
32 JSOperatorBuilder javascript(zone());
33 JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine);
34 SimplifiedOperatorReducer reducer(&jsgraph);
35 return reducer.Reduce(node);
38 SimplifiedOperatorBuilder* simplified() { return &simplified_; }
41 SimplifiedOperatorBuilder simplified_;
46 class SimplifiedOperatorReducerTestWithParam
47 : public SimplifiedOperatorReducerTest,
48 public ::testing::WithParamInterface<T> {
50 explicit SimplifiedOperatorReducerTestWithParam(int num_parameters = 1)
51 : SimplifiedOperatorReducerTest(num_parameters) {}
52 ~SimplifiedOperatorReducerTestWithParam() OVERRIDE {}
58 const double kFloat64Values[] = {
59 -V8_INFINITY, -6.52696e+290, -1.05768e+290, -5.34203e+268, -1.01997e+268,
60 -8.22758e+266, -1.58402e+261, -5.15246e+241, -5.92107e+226, -1.21477e+226,
61 -1.67913e+188, -1.6257e+184, -2.60043e+170, -2.52941e+168, -3.06033e+116,
62 -4.56201e+52, -3.56788e+50, -9.9066e+38, -3.07261e+31, -2.1271e+09,
63 -1.91489e+09, -1.73053e+09, -9.30675e+08, -26030, -20453, -15790, -11699,
64 -111, -97, -78, -63, -58, -1.53858e-06, -2.98914e-12, -1.14741e-39,
65 -8.20347e-57, -1.48932e-59, -3.17692e-66, -8.93103e-81, -3.91337e-83,
66 -6.0489e-92, -8.83291e-113, -4.28266e-117, -1.92058e-178, -2.0567e-192,
67 -1.68167e-194, -1.51841e-214, -3.98738e-234, -7.31851e-242, -2.21875e-253,
68 -1.11612e-293, -0.0, 0.0, 2.22507e-308, 1.06526e-307, 4.16643e-227,
69 6.76624e-223, 2.0432e-197, 3.16254e-184, 1.37315e-173, 2.88603e-172,
70 1.54155e-99, 4.42923e-81, 1.40539e-73, 5.4462e-73, 1.24064e-58, 3.11167e-58,
71 2.75826e-39, 0.143815, 58, 67, 601, 7941, 11644, 13697, 25680, 29882,
72 1.32165e+08, 1.62439e+08, 4.16837e+08, 9.59097e+08, 1.32491e+09, 1.8728e+09,
73 1.0672e+17, 2.69606e+46, 1.98285e+79, 1.0098e+82, 7.93064e+88, 3.67444e+121,
74 9.36506e+123, 7.27954e+162, 3.05316e+168, 1.16171e+175, 1.64771e+189,
75 1.1622e+202, 2.00748e+239, 2.51778e+244, 3.90282e+306, 1.79769e+308,
79 const int32_t kInt32Values[] = {
80 -2147483647 - 1, -2104508227, -2103151830, -1435284490, -1378926425,
81 -1318814539, -1289388009, -1287537572, -1279026536, -1241605942,
82 -1226046939, -941837148, -779818051, -413830641, -245798087, -184657557,
83 -127145950, -105483328, -32325, -26653, -23858, -23834, -22363, -19858,
84 -19044, -18744, -15528, -5309, -3372, -2093, -104, -98, -97, -93, -84, -80,
85 -78, -76, -72, -58, -57, -56, -55, -45, -40, -34, -32, -25, -24, -5, -2, 0,
86 3, 10, 24, 34, 42, 46, 47, 48, 52, 56, 64, 65, 71, 76, 79, 81, 82, 97, 102,
87 103, 104, 106, 107, 109, 116, 122, 3653, 4485, 12405, 16504, 26262, 28704,
88 29755, 30554, 16476817, 605431957, 832401070, 873617242, 914205764,
89 1062628108, 1087581664, 1488498068, 1534668023, 1661587028, 1696896187,
90 1866841746, 2032089723, 2147483647};
93 const uint32_t kUint32Values[] = {
94 0x0, 0x5, 0x8, 0xc, 0xd, 0x26,
95 0x28, 0x29, 0x30, 0x34, 0x3e, 0x42,
96 0x50, 0x5b, 0x63, 0x71, 0x77, 0x7c,
97 0x83, 0x88, 0x96, 0x9c, 0xa3, 0xfa,
98 0x7a7, 0x165d, 0x234d, 0x3acb, 0x43a5, 0x4573,
99 0x5b4f, 0x5f14, 0x6996, 0x6c6e, 0x7289, 0x7b9a,
100 0x7bc9, 0x86bb, 0xa839, 0xaa41, 0xb03b, 0xc942,
101 0xce68, 0xcf4c, 0xd3ad, 0xdea3, 0xe90c, 0xed86,
102 0xfba5, 0x172dcc6, 0x114d8fc1, 0x182d6c9d, 0x1b1e3fad, 0x1db033bf,
103 0x1e1de755, 0x1f625c80, 0x28f6cf00, 0x2acb6a94, 0x2c20240e, 0x2f0fe54e,
104 0x31863a7c, 0x33325474, 0x3532fae3, 0x3bab82ea, 0x4c4b83a2, 0x4cd93d1e,
105 0x4f7331d4, 0x5491b09b, 0x57cc6ff9, 0x60d3b4dc, 0x653f5904, 0x690ae256,
106 0x69fe3276, 0x6bebf0ba, 0x6e2c69a3, 0x73b84ff7, 0x7b3a1924, 0x7ed032d9,
107 0x84dd734b, 0x8552ea53, 0x8680754f, 0x8e9660eb, 0x94fe2b9c, 0x972d30cf,
108 0x9b98c482, 0xb158667e, 0xb432932c, 0xb5b70989, 0xb669971a, 0xb7c359d1,
109 0xbeb15c0d, 0xc171c53d, 0xc743dd38, 0xc8e2af50, 0xc98e2df0, 0xd9d1cdf9,
110 0xdcc91049, 0xe46f396d, 0xee991950, 0xef64e521, 0xf7aeefc9, 0xffffffff};
113 const double kNaNs[] = {-std::numeric_limits<double>::quiet_NaN(),
114 std::numeric_limits<double>::quiet_NaN(),
115 bit_cast<double>(V8_UINT64_C(0x7FFFFFFFFFFFFFFF)),
116 bit_cast<double>(V8_UINT64_C(0xFFFFFFFFFFFFFFFF))};
121 // -----------------------------------------------------------------------------
125 TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithBooleanNot) {
126 Node* param0 = Parameter(0);
127 Reduction reduction = Reduce(
128 graph()->NewNode(simplified()->BooleanNot(),
129 graph()->NewNode(simplified()->BooleanNot(), param0)));
130 ASSERT_TRUE(reduction.Changed());
131 EXPECT_EQ(param0, reduction.replacement());
135 TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithFalseConstant) {
136 Reduction reduction0 =
137 Reduce(graph()->NewNode(simplified()->BooleanNot(), FalseConstant()));
138 ASSERT_TRUE(reduction0.Changed());
139 EXPECT_THAT(reduction0.replacement(), IsTrueConstant());
143 TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithTrueConstant) {
144 Reduction reduction1 =
145 Reduce(graph()->NewNode(simplified()->BooleanNot(), TrueConstant()));
146 ASSERT_TRUE(reduction1.Changed());
147 EXPECT_THAT(reduction1.replacement(), IsFalseConstant());
151 // -----------------------------------------------------------------------------
155 TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithChangeBoolToBit) {
156 Node* param0 = Parameter(0);
157 Reduction reduction = Reduce(graph()->NewNode(
158 simplified()->ChangeBitToBool(),
159 graph()->NewNode(simplified()->ChangeBoolToBit(), param0)));
160 ASSERT_TRUE(reduction.Changed());
161 EXPECT_EQ(param0, reduction.replacement());
165 TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithZeroConstant) {
166 Reduction reduction = Reduce(
167 graph()->NewNode(simplified()->ChangeBitToBool(), Int32Constant(0)));
168 ASSERT_TRUE(reduction.Changed());
169 EXPECT_THAT(reduction.replacement(), IsFalseConstant());
173 TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithOneConstant) {
174 Reduction reduction = Reduce(
175 graph()->NewNode(simplified()->ChangeBitToBool(), Int32Constant(1)));
176 ASSERT_TRUE(reduction.Changed());
177 EXPECT_THAT(reduction.replacement(), IsTrueConstant());
181 // -----------------------------------------------------------------------------
185 TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithFalseConstant) {
186 Reduction reduction = Reduce(
187 graph()->NewNode(simplified()->ChangeBoolToBit(), FalseConstant()));
188 ASSERT_TRUE(reduction.Changed());
189 EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
193 TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithTrueConstant) {
194 Reduction reduction =
195 Reduce(graph()->NewNode(simplified()->ChangeBoolToBit(), TrueConstant()));
196 ASSERT_TRUE(reduction.Changed());
197 EXPECT_THAT(reduction.replacement(), IsInt32Constant(1));
201 TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithChangeBitToBool) {
202 Node* param0 = Parameter(0);
203 Reduction reduction = Reduce(graph()->NewNode(
204 simplified()->ChangeBoolToBit(),
205 graph()->NewNode(simplified()->ChangeBitToBool(), param0)));
206 ASSERT_TRUE(reduction.Changed());
207 EXPECT_EQ(param0, reduction.replacement());
211 // -----------------------------------------------------------------------------
212 // ChangeFloat64ToTagged
215 TEST_F(SimplifiedOperatorReducerTest, ChangeFloat64ToTaggedWithConstant) {
216 TRACED_FOREACH(double, n, kFloat64Values) {
217 Reduction reduction = Reduce(graph()->NewNode(
218 simplified()->ChangeFloat64ToTagged(), Float64Constant(n)));
219 ASSERT_TRUE(reduction.Changed());
220 EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(n)));
225 // -----------------------------------------------------------------------------
226 // ChangeInt32ToTagged
229 TEST_F(SimplifiedOperatorReducerTest, ChangeInt32ToTaggedWithConstant) {
230 TRACED_FOREACH(int32_t, n, kInt32Values) {
231 Reduction reduction = Reduce(graph()->NewNode(
232 simplified()->ChangeInt32ToTagged(), Int32Constant(n)));
233 ASSERT_TRUE(reduction.Changed());
234 EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(FastI2D(n))));
239 // -----------------------------------------------------------------------------
240 // ChangeTaggedToFloat64
243 TEST_F(SimplifiedOperatorReducerTest,
244 ChangeTaggedToFloat64WithChangeFloat64ToTagged) {
245 Node* param0 = Parameter(0);
246 Reduction reduction = Reduce(graph()->NewNode(
247 simplified()->ChangeTaggedToFloat64(),
248 graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
249 ASSERT_TRUE(reduction.Changed());
250 EXPECT_EQ(param0, reduction.replacement());
254 TEST_F(SimplifiedOperatorReducerTest,
255 ChangeTaggedToFloat64WithChangeInt32ToTagged) {
256 Node* param0 = Parameter(0);
257 Reduction reduction = Reduce(graph()->NewNode(
258 simplified()->ChangeTaggedToFloat64(),
259 graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
260 ASSERT_TRUE(reduction.Changed());
261 EXPECT_THAT(reduction.replacement(), IsChangeInt32ToFloat64(param0));
265 TEST_F(SimplifiedOperatorReducerTest,
266 ChangeTaggedToFloat64WithChangeUint32ToTagged) {
267 Node* param0 = Parameter(0);
268 Reduction reduction = Reduce(graph()->NewNode(
269 simplified()->ChangeTaggedToFloat64(),
270 graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
271 ASSERT_TRUE(reduction.Changed());
272 EXPECT_THAT(reduction.replacement(), IsChangeUint32ToFloat64(param0));
276 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithConstant) {
277 TRACED_FOREACH(double, n, kFloat64Values) {
278 Reduction reduction = Reduce(graph()->NewNode(
279 simplified()->ChangeTaggedToFloat64(), NumberConstant(n)));
280 ASSERT_TRUE(reduction.Changed());
281 EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(n)));
286 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant) {
287 TRACED_FOREACH(double, nan, kNaNs) {
288 Reduction reduction = Reduce(graph()->NewNode(
289 simplified()->ChangeTaggedToFloat64(), NumberConstant(nan)));
290 ASSERT_TRUE(reduction.Changed());
291 EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(nan)));
296 // -----------------------------------------------------------------------------
297 // ChangeTaggedToInt32
300 TEST_F(SimplifiedOperatorReducerTest,
301 ChangeTaggedToInt32WithChangeFloat64ToTagged) {
302 Node* param0 = Parameter(0);
303 Reduction reduction = Reduce(graph()->NewNode(
304 simplified()->ChangeTaggedToInt32(),
305 graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
306 ASSERT_TRUE(reduction.Changed());
307 EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToInt32(param0));
311 TEST_F(SimplifiedOperatorReducerTest,
312 ChangeTaggedToInt32WithChangeInt32ToTagged) {
313 Node* param0 = Parameter(0);
314 Reduction reduction = Reduce(graph()->NewNode(
315 simplified()->ChangeTaggedToInt32(),
316 graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
317 ASSERT_TRUE(reduction.Changed());
318 EXPECT_EQ(param0, reduction.replacement());
322 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithConstant) {
323 TRACED_FOREACH(double, n, kFloat64Values) {
324 Reduction reduction = Reduce(graph()->NewNode(
325 simplified()->ChangeTaggedToInt32(), NumberConstant(n)));
326 ASSERT_TRUE(reduction.Changed());
327 EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(n)));
332 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithNaNConstant) {
333 TRACED_FOREACH(double, nan, kNaNs) {
334 Reduction reduction = Reduce(graph()->NewNode(
335 simplified()->ChangeTaggedToInt32(), NumberConstant(nan)));
336 ASSERT_TRUE(reduction.Changed());
337 EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
342 // -----------------------------------------------------------------------------
343 // ChangeTaggedToUint32
346 TEST_F(SimplifiedOperatorReducerTest,
347 ChangeTaggedToUint32WithChangeFloat64ToTagged) {
348 Node* param0 = Parameter(0);
349 Reduction reduction = Reduce(graph()->NewNode(
350 simplified()->ChangeTaggedToUint32(),
351 graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
352 ASSERT_TRUE(reduction.Changed());
353 EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToUint32(param0));
357 TEST_F(SimplifiedOperatorReducerTest,
358 ChangeTaggedToUint32WithChangeUint32ToTagged) {
359 Node* param0 = Parameter(0);
360 Reduction reduction = Reduce(graph()->NewNode(
361 simplified()->ChangeTaggedToUint32(),
362 graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
363 ASSERT_TRUE(reduction.Changed());
364 EXPECT_EQ(param0, reduction.replacement());
368 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithConstant) {
369 TRACED_FOREACH(double, n, kFloat64Values) {
370 Reduction reduction = Reduce(graph()->NewNode(
371 simplified()->ChangeTaggedToUint32(), NumberConstant(n)));
372 ASSERT_TRUE(reduction.Changed());
373 EXPECT_THAT(reduction.replacement(),
374 IsInt32Constant(bit_cast<int32_t>(DoubleToUint32(n))));
379 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithNaNConstant) {
380 TRACED_FOREACH(double, nan, kNaNs) {
381 Reduction reduction = Reduce(graph()->NewNode(
382 simplified()->ChangeTaggedToUint32(), NumberConstant(nan)));
383 ASSERT_TRUE(reduction.Changed());
384 EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
389 // -----------------------------------------------------------------------------
390 // ChangeUint32ToTagged
393 TEST_F(SimplifiedOperatorReducerTest, ChangeUint32ToTagged) {
394 TRACED_FOREACH(uint32_t, n, kUint32Values) {
395 Reduction reduction =
396 Reduce(graph()->NewNode(simplified()->ChangeUint32ToTagged(),
397 Int32Constant(bit_cast<int32_t>(n))));
398 ASSERT_TRUE(reduction.Changed());
399 EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(FastUI2D(n))));
403 } // namespace compiler
404 } // namespace internal