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