Home | History | Annotate | Download | only in compiler
      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:
     25   explicit SimplifiedOperatorReducerTest(int num_parameters = 1)
     26       : TypedGraphTest(num_parameters), simplified_(zone()) {}
     27   ~SimplifiedOperatorReducerTest() override {}
     28 
     29  protected:
     30   Reduction Reduce(Node* node) {
     31     MachineOperatorBuilder machine(zone());
     32     JSOperatorBuilder javascript(zone());
     33     JSGraph jsgraph(isolate(), graph(), common(), &javascript, simplified(),
     34                     &machine);
     35     GraphReducer graph_reducer(zone(), graph());
     36     SimplifiedOperatorReducer reducer(&graph_reducer, &jsgraph);
     37     return reducer.Reduce(node);
     38   }
     39 
     40   SimplifiedOperatorBuilder* simplified() { return &simplified_; }
     41 
     42  private:
     43   SimplifiedOperatorBuilder simplified_;
     44 };
     45 
     46 
     47 template <typename T>
     48 class SimplifiedOperatorReducerTestWithParam
     49     : public SimplifiedOperatorReducerTest,
     50       public ::testing::WithParamInterface<T> {
     51  public:
     52   explicit SimplifiedOperatorReducerTestWithParam(int num_parameters = 1)
     53       : SimplifiedOperatorReducerTest(num_parameters) {}
     54   ~SimplifiedOperatorReducerTestWithParam() override {}
     55 };
     56 
     57 
     58 namespace {
     59 
     60 const double kFloat64Values[] = {
     61     -V8_INFINITY, -6.52696e+290, -1.05768e+290, -5.34203e+268, -1.01997e+268,
     62     -8.22758e+266, -1.58402e+261, -5.15246e+241, -5.92107e+226, -1.21477e+226,
     63     -1.67913e+188, -1.6257e+184, -2.60043e+170, -2.52941e+168, -3.06033e+116,
     64     -4.56201e+52, -3.56788e+50, -9.9066e+38, -3.07261e+31, -2.1271e+09,
     65     -1.91489e+09, -1.73053e+09, -9.30675e+08, -26030, -20453, -15790, -11699,
     66     -111, -97, -78, -63, -58, -1.53858e-06, -2.98914e-12, -1.14741e-39,
     67     -8.20347e-57, -1.48932e-59, -3.17692e-66, -8.93103e-81, -3.91337e-83,
     68     -6.0489e-92, -8.83291e-113, -4.28266e-117, -1.92058e-178, -2.0567e-192,
     69     -1.68167e-194, -1.51841e-214, -3.98738e-234, -7.31851e-242, -2.21875e-253,
     70     -1.11612e-293, -0.0, 0.0, 2.22507e-308, 1.06526e-307, 4.16643e-227,
     71     6.76624e-223, 2.0432e-197, 3.16254e-184, 1.37315e-173, 2.88603e-172,
     72     1.54155e-99, 4.42923e-81, 1.40539e-73, 5.4462e-73, 1.24064e-58, 3.11167e-58,
     73     2.75826e-39, 0.143815, 58, 67, 601, 7941, 11644, 13697, 25680, 29882,
     74     1.32165e+08, 1.62439e+08, 4.16837e+08, 9.59097e+08, 1.32491e+09, 1.8728e+09,
     75     1.0672e+17, 2.69606e+46, 1.98285e+79, 1.0098e+82, 7.93064e+88, 3.67444e+121,
     76     9.36506e+123, 7.27954e+162, 3.05316e+168, 1.16171e+175, 1.64771e+189,
     77     1.1622e+202, 2.00748e+239, 2.51778e+244, 3.90282e+306, 1.79769e+308,
     78     V8_INFINITY};
     79 
     80 
     81 const int32_t kInt32Values[] = {
     82     -2147483647 - 1, -2104508227, -2103151830, -1435284490, -1378926425,
     83     -1318814539, -1289388009, -1287537572, -1279026536, -1241605942,
     84     -1226046939, -941837148, -779818051, -413830641, -245798087, -184657557,
     85     -127145950, -105483328, -32325, -26653, -23858, -23834, -22363, -19858,
     86     -19044, -18744, -15528, -5309, -3372, -2093, -104, -98, -97, -93, -84, -80,
     87     -78, -76, -72, -58, -57, -56, -55, -45, -40, -34, -32, -25, -24, -5, -2, 0,
     88     3, 10, 24, 34, 42, 46, 47, 48, 52, 56, 64, 65, 71, 76, 79, 81, 82, 97, 102,
     89     103, 104, 106, 107, 109, 116, 122, 3653, 4485, 12405, 16504, 26262, 28704,
     90     29755, 30554, 16476817, 605431957, 832401070, 873617242, 914205764,
     91     1062628108, 1087581664, 1488498068, 1534668023, 1661587028, 1696896187,
     92     1866841746, 2032089723, 2147483647};
     93 
     94 
     95 const double kNaNs[] = {-std::numeric_limits<double>::quiet_NaN(),
     96                         std::numeric_limits<double>::quiet_NaN(),
     97                         bit_cast<double>(V8_UINT64_C(0x7FFFFFFFFFFFFFFF)),
     98                         bit_cast<double>(V8_UINT64_C(0xFFFFFFFFFFFFFFFF))};
     99 
    100 }  // namespace
    101 
    102 
    103 // -----------------------------------------------------------------------------
    104 // BooleanNot
    105 
    106 
    107 TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithBooleanNot) {
    108   Node* param0 = Parameter(0);
    109   Reduction reduction = Reduce(
    110       graph()->NewNode(simplified()->BooleanNot(),
    111                        graph()->NewNode(simplified()->BooleanNot(), param0)));
    112   ASSERT_TRUE(reduction.Changed());
    113   EXPECT_EQ(param0, reduction.replacement());
    114 }
    115 
    116 
    117 TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithFalseConstant) {
    118   Reduction reduction0 =
    119       Reduce(graph()->NewNode(simplified()->BooleanNot(), FalseConstant()));
    120   ASSERT_TRUE(reduction0.Changed());
    121   EXPECT_THAT(reduction0.replacement(), IsTrueConstant());
    122 }
    123 
    124 
    125 TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithTrueConstant) {
    126   Reduction reduction1 =
    127       Reduce(graph()->NewNode(simplified()->BooleanNot(), TrueConstant()));
    128   ASSERT_TRUE(reduction1.Changed());
    129   EXPECT_THAT(reduction1.replacement(), IsFalseConstant());
    130 }
    131 
    132 
    133 // -----------------------------------------------------------------------------
    134 // ChangeTaggedToBit
    135 
    136 TEST_F(SimplifiedOperatorReducerTest, ChangeBitToTaggedWithChangeTaggedToBit) {
    137   Node* param0 = Parameter(0);
    138   Reduction reduction = Reduce(graph()->NewNode(
    139       simplified()->ChangeBitToTagged(),
    140       graph()->NewNode(simplified()->ChangeTaggedToBit(), param0)));
    141   ASSERT_TRUE(reduction.Changed());
    142   EXPECT_EQ(param0, reduction.replacement());
    143 }
    144 
    145 TEST_F(SimplifiedOperatorReducerTest, ChangeBitToTaggedWithZeroConstant) {
    146   Reduction reduction = Reduce(
    147       graph()->NewNode(simplified()->ChangeBitToTagged(), Int32Constant(0)));
    148   ASSERT_TRUE(reduction.Changed());
    149   EXPECT_THAT(reduction.replacement(), IsFalseConstant());
    150 }
    151 
    152 TEST_F(SimplifiedOperatorReducerTest, ChangeBitToTaggedWithOneConstant) {
    153   Reduction reduction = Reduce(
    154       graph()->NewNode(simplified()->ChangeBitToTagged(), Int32Constant(1)));
    155   ASSERT_TRUE(reduction.Changed());
    156   EXPECT_THAT(reduction.replacement(), IsTrueConstant());
    157 }
    158 
    159 
    160 // -----------------------------------------------------------------------------
    161 // ChangeTaggedToBit
    162 
    163 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToBitWithFalseConstant) {
    164   Reduction reduction = Reduce(
    165       graph()->NewNode(simplified()->ChangeTaggedToBit(), FalseConstant()));
    166   ASSERT_TRUE(reduction.Changed());
    167   EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
    168 }
    169 
    170 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToBitWithTrueConstant) {
    171   Reduction reduction = Reduce(
    172       graph()->NewNode(simplified()->ChangeTaggedToBit(), TrueConstant()));
    173   ASSERT_TRUE(reduction.Changed());
    174   EXPECT_THAT(reduction.replacement(), IsInt32Constant(1));
    175 }
    176 
    177 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToBitWithChangeBitToTagged) {
    178   Node* param0 = Parameter(0);
    179   Reduction reduction = Reduce(graph()->NewNode(
    180       simplified()->ChangeTaggedToBit(),
    181       graph()->NewNode(simplified()->ChangeBitToTagged(), param0)));
    182   ASSERT_TRUE(reduction.Changed());
    183   EXPECT_EQ(param0, reduction.replacement());
    184 }
    185 
    186 
    187 // -----------------------------------------------------------------------------
    188 // ChangeFloat64ToTagged
    189 
    190 
    191 TEST_F(SimplifiedOperatorReducerTest, ChangeFloat64ToTaggedWithConstant) {
    192   TRACED_FOREACH(double, n, kFloat64Values) {
    193     Reduction reduction = Reduce(graph()->NewNode(
    194         simplified()->ChangeFloat64ToTagged(), Float64Constant(n)));
    195     ASSERT_TRUE(reduction.Changed());
    196     EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(n)));
    197   }
    198 }
    199 
    200 
    201 // -----------------------------------------------------------------------------
    202 // ChangeInt32ToTagged
    203 
    204 
    205 TEST_F(SimplifiedOperatorReducerTest, ChangeInt32ToTaggedWithConstant) {
    206   TRACED_FOREACH(int32_t, n, kInt32Values) {
    207     Reduction reduction = Reduce(graph()->NewNode(
    208         simplified()->ChangeInt32ToTagged(), Int32Constant(n)));
    209     ASSERT_TRUE(reduction.Changed());
    210     EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(FastI2D(n))));
    211   }
    212 }
    213 
    214 
    215 // -----------------------------------------------------------------------------
    216 // ChangeTaggedToFloat64
    217 
    218 
    219 TEST_F(SimplifiedOperatorReducerTest,
    220        ChangeTaggedToFloat64WithChangeFloat64ToTagged) {
    221   Node* param0 = Parameter(0);
    222   Reduction reduction = Reduce(graph()->NewNode(
    223       simplified()->ChangeTaggedToFloat64(),
    224       graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
    225   ASSERT_TRUE(reduction.Changed());
    226   EXPECT_EQ(param0, reduction.replacement());
    227 }
    228 
    229 
    230 TEST_F(SimplifiedOperatorReducerTest,
    231        ChangeTaggedToFloat64WithChangeInt32ToTagged) {
    232   Node* param0 = Parameter(0);
    233   Reduction reduction = Reduce(graph()->NewNode(
    234       simplified()->ChangeTaggedToFloat64(),
    235       graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
    236   ASSERT_TRUE(reduction.Changed());
    237   EXPECT_THAT(reduction.replacement(), IsChangeInt32ToFloat64(param0));
    238 }
    239 
    240 
    241 TEST_F(SimplifiedOperatorReducerTest,
    242        ChangeTaggedToFloat64WithChangeUint32ToTagged) {
    243   Node* param0 = Parameter(0);
    244   Reduction reduction = Reduce(graph()->NewNode(
    245       simplified()->ChangeTaggedToFloat64(),
    246       graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
    247   ASSERT_TRUE(reduction.Changed());
    248   EXPECT_THAT(reduction.replacement(), IsChangeUint32ToFloat64(param0));
    249 }
    250 
    251 
    252 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithConstant) {
    253   TRACED_FOREACH(double, n, kFloat64Values) {
    254     Reduction reduction = Reduce(graph()->NewNode(
    255         simplified()->ChangeTaggedToFloat64(), NumberConstant(n)));
    256     ASSERT_TRUE(reduction.Changed());
    257     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(n)));
    258   }
    259 }
    260 
    261 
    262 TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant) {
    263   TRACED_FOREACH(double, nan, kNaNs) {
    264     Reduction reduction = Reduce(graph()->NewNode(
    265         simplified()->ChangeTaggedToFloat64(), NumberConstant(nan)));
    266     ASSERT_TRUE(reduction.Changed());
    267     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(nan)));
    268   }
    269 }
    270 
    271 
    272 // -----------------------------------------------------------------------------
    273 // ChangeTaggedToInt32
    274 
    275 
    276 TEST_F(SimplifiedOperatorReducerTest,
    277        ChangeTaggedToInt32WithChangeFloat64ToTagged) {
    278   Node* param0 = Parameter(0);
    279   Reduction reduction = Reduce(graph()->NewNode(
    280       simplified()->ChangeTaggedToInt32(),
    281       graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
    282   ASSERT_TRUE(reduction.Changed());
    283   EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToInt32(param0));
    284 }
    285 
    286 
    287 TEST_F(SimplifiedOperatorReducerTest,
    288        ChangeTaggedToInt32WithChangeInt32ToTagged) {
    289   Node* param0 = Parameter(0);
    290   Reduction reduction = Reduce(graph()->NewNode(
    291       simplified()->ChangeTaggedToInt32(),
    292       graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
    293   ASSERT_TRUE(reduction.Changed());
    294   EXPECT_EQ(param0, reduction.replacement());
    295 }
    296 
    297 
    298 // -----------------------------------------------------------------------------
    299 // ChangeTaggedToUint32
    300 
    301 
    302 TEST_F(SimplifiedOperatorReducerTest,
    303        ChangeTaggedToUint32WithChangeFloat64ToTagged) {
    304   Node* param0 = Parameter(0);
    305   Reduction reduction = Reduce(graph()->NewNode(
    306       simplified()->ChangeTaggedToUint32(),
    307       graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
    308   ASSERT_TRUE(reduction.Changed());
    309   EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToUint32(param0));
    310 }
    311 
    312 
    313 TEST_F(SimplifiedOperatorReducerTest,
    314        ChangeTaggedToUint32WithChangeUint32ToTagged) {
    315   Node* param0 = Parameter(0);
    316   Reduction reduction = Reduce(graph()->NewNode(
    317       simplified()->ChangeTaggedToUint32(),
    318       graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
    319   ASSERT_TRUE(reduction.Changed());
    320   EXPECT_EQ(param0, reduction.replacement());
    321 }
    322 
    323 
    324 // -----------------------------------------------------------------------------
    325 // TruncateTaggedToWord32
    326 
    327 TEST_F(SimplifiedOperatorReducerTest,
    328        TruncateTaggedToWord3WithChangeFloat64ToTagged) {
    329   Node* param0 = Parameter(0);
    330   Reduction reduction = Reduce(graph()->NewNode(
    331       simplified()->TruncateTaggedToWord32(),
    332       graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
    333   ASSERT_TRUE(reduction.Changed());
    334   EXPECT_THAT(reduction.replacement(), IsTruncateFloat64ToWord32(param0));
    335 }
    336 
    337 TEST_F(SimplifiedOperatorReducerTest, TruncateTaggedToWord32WithConstant) {
    338   TRACED_FOREACH(double, n, kFloat64Values) {
    339     Reduction reduction = Reduce(graph()->NewNode(
    340         simplified()->TruncateTaggedToWord32(), NumberConstant(n)));
    341     ASSERT_TRUE(reduction.Changed());
    342     EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(n)));
    343   }
    344 }
    345 
    346 // -----------------------------------------------------------------------------
    347 // CheckTaggedPointer
    348 
    349 TEST_F(SimplifiedOperatorReducerTest, CheckTaggedPointerWithChangeBitToTagged) {
    350   Node* param0 = Parameter(0);
    351   Node* effect = graph()->start();
    352   Node* control = graph()->start();
    353   Node* value = graph()->NewNode(simplified()->ChangeBitToTagged(), param0);
    354   Reduction reduction = Reduce(graph()->NewNode(
    355       simplified()->CheckTaggedPointer(), value, effect, control));
    356   ASSERT_TRUE(reduction.Changed());
    357   EXPECT_EQ(value, reduction.replacement());
    358 }
    359 
    360 TEST_F(SimplifiedOperatorReducerTest, CheckTaggedPointerWithHeapConstant) {
    361   Node* effect = graph()->start();
    362   Node* control = graph()->start();
    363   Handle<HeapObject> kHeapObjects[] = {
    364       factory()->empty_string(), factory()->null_value(),
    365       factory()->species_symbol(), factory()->undefined_value()};
    366   TRACED_FOREACH(Handle<HeapObject>, object, kHeapObjects) {
    367     Node* value = HeapConstant(object);
    368     Reduction reduction = Reduce(graph()->NewNode(
    369         simplified()->CheckTaggedPointer(), value, effect, control));
    370     ASSERT_TRUE(reduction.Changed());
    371     EXPECT_EQ(value, reduction.replacement());
    372   }
    373 }
    374 
    375 // -----------------------------------------------------------------------------
    376 // CheckTaggedSigned
    377 
    378 TEST_F(SimplifiedOperatorReducerTest,
    379        CheckTaggedSignedWithChangeInt31ToTaggedSigned) {
    380   Node* param0 = Parameter(0);
    381   Node* effect = graph()->start();
    382   Node* control = graph()->start();
    383   Node* value =
    384       graph()->NewNode(simplified()->ChangeInt31ToTaggedSigned(), param0);
    385   Reduction reduction = Reduce(graph()->NewNode(
    386       simplified()->CheckTaggedSigned(), value, effect, control));
    387   ASSERT_TRUE(reduction.Changed());
    388   EXPECT_EQ(value, reduction.replacement());
    389 }
    390 
    391 TEST_F(SimplifiedOperatorReducerTest, CheckTaggedSignedWithNumberConstant) {
    392   Node* effect = graph()->start();
    393   Node* control = graph()->start();
    394   Node* value = NumberConstant(1.0);
    395   Reduction reduction = Reduce(graph()->NewNode(
    396       simplified()->CheckTaggedSigned(), value, effect, control));
    397   ASSERT_TRUE(reduction.Changed());
    398   EXPECT_EQ(value, reduction.replacement());
    399 }
    400 
    401 // -----------------------------------------------------------------------------
    402 // NumberAbs
    403 
    404 TEST_F(SimplifiedOperatorReducerTest, NumberAbsWithNumberConstant) {
    405   TRACED_FOREACH(double, n, kFloat64Values) {
    406     Reduction reduction =
    407         Reduce(graph()->NewNode(simplified()->NumberAbs(), NumberConstant(n)));
    408     ASSERT_TRUE(reduction.Changed());
    409     EXPECT_THAT(reduction.replacement(), IsNumberConstant(std::fabs(n)));
    410   }
    411 }
    412 
    413 // -----------------------------------------------------------------------------
    414 // ObjectIsSmi
    415 
    416 TEST_F(SimplifiedOperatorReducerTest, ObjectIsSmiWithChangeBitToTagged) {
    417   Node* param0 = Parameter(0);
    418   Reduction reduction = Reduce(graph()->NewNode(
    419       simplified()->ObjectIsSmi(),
    420       graph()->NewNode(simplified()->ChangeBitToTagged(), param0)));
    421   ASSERT_TRUE(reduction.Changed());
    422   EXPECT_THAT(reduction.replacement(), IsFalseConstant());
    423 }
    424 
    425 TEST_F(SimplifiedOperatorReducerTest,
    426        ObjectIsSmiWithChangeInt31ToTaggedSigned) {
    427   Node* param0 = Parameter(0);
    428   Reduction reduction = Reduce(graph()->NewNode(
    429       simplified()->ObjectIsSmi(),
    430       graph()->NewNode(simplified()->ChangeInt31ToTaggedSigned(), param0)));
    431   ASSERT_TRUE(reduction.Changed());
    432   EXPECT_THAT(reduction.replacement(), IsTrueConstant());
    433 }
    434 
    435 TEST_F(SimplifiedOperatorReducerTest, ObjectIsSmiWithHeapConstant) {
    436   Handle<HeapObject> kHeapObjects[] = {
    437       factory()->empty_string(), factory()->null_value(),
    438       factory()->species_symbol(), factory()->undefined_value()};
    439   TRACED_FOREACH(Handle<HeapObject>, o, kHeapObjects) {
    440     Reduction reduction =
    441         Reduce(graph()->NewNode(simplified()->ObjectIsSmi(), HeapConstant(o)));
    442     ASSERT_TRUE(reduction.Changed());
    443     EXPECT_THAT(reduction.replacement(), IsFalseConstant());
    444   }
    445 }
    446 
    447 TEST_F(SimplifiedOperatorReducerTest, ObjectIsSmiWithNumberConstant) {
    448   TRACED_FOREACH(double, n, kFloat64Values) {
    449     Reduction reduction = Reduce(
    450         graph()->NewNode(simplified()->ObjectIsSmi(), NumberConstant(n)));
    451     ASSERT_TRUE(reduction.Changed());
    452     EXPECT_THAT(reduction.replacement(), IsBooleanConstant(IsSmiDouble(n)));
    453   }
    454 }
    455 
    456 }  // namespace compiler
    457 }  // namespace internal
    458 }  // namespace v8
    459