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/base/bits.h"
      6 #include "src/compiler/graph-unittest.h"
      7 #include "src/compiler/js-graph.h"
      8 #include "src/compiler/machine-operator-reducer.h"
      9 #include "src/compiler/typer.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 namespace compiler {
     14 
     15 class MachineOperatorReducerTest : public GraphTest {
     16  public:
     17   explicit MachineOperatorReducerTest(int num_parameters = 2)
     18       : GraphTest(num_parameters) {}
     19 
     20  protected:
     21   Reduction Reduce(Node* node) {
     22     Typer typer(zone());
     23     JSOperatorBuilder javascript(zone());
     24     JSGraph jsgraph(graph(), common(), &javascript, &typer, &machine_);
     25     MachineOperatorReducer reducer(&jsgraph);
     26     return reducer.Reduce(node);
     27   }
     28 
     29   MachineOperatorBuilder* machine() { return &machine_; }
     30 
     31  private:
     32   MachineOperatorBuilder machine_;
     33 };
     34 
     35 
     36 template <typename T>
     37 class MachineOperatorReducerTestWithParam
     38     : public MachineOperatorReducerTest,
     39       public ::testing::WithParamInterface<T> {
     40  public:
     41   explicit MachineOperatorReducerTestWithParam(int num_parameters = 2)
     42       : MachineOperatorReducerTest(num_parameters) {}
     43   virtual ~MachineOperatorReducerTestWithParam() {}
     44 };
     45 
     46 
     47 namespace {
     48 
     49 static const float kFloat32Values[] = {
     50     -std::numeric_limits<float>::infinity(), -2.70497e+38f, -1.4698e+37f,
     51     -1.22813e+35f,                           -1.20555e+35f, -1.34584e+34f,
     52     -1.0079e+32f,                            -6.49364e+26f, -3.06077e+25f,
     53     -1.46821e+25f,                           -1.17658e+23f, -1.9617e+22f,
     54     -2.7357e+20f,                            -1.48708e+13f, -1.89633e+12f,
     55     -4.66622e+11f,                           -2.22581e+11f, -1.45381e+10f,
     56     -1.3956e+09f,                            -1.32951e+09f, -1.30721e+09f,
     57     -1.19756e+09f,                           -9.26822e+08f, -6.35647e+08f,
     58     -4.00037e+08f,                           -1.81227e+08f, -5.09256e+07f,
     59     -964300.0f,                              -192446.0f,    -28455.0f,
     60     -27194.0f,                               -26401.0f,     -20575.0f,
     61     -17069.0f,                               -9167.0f,      -960.178f,
     62     -113.0f,                                 -62.0f,        -15.0f,
     63     -7.0f,                                   -0.0256635f,   -4.60374e-07f,
     64     -3.63759e-10f,                           -4.30175e-14f, -5.27385e-15f,
     65     -1.48084e-15f,                           -1.05755e-19f, -3.2995e-21f,
     66     -1.67354e-23f,                           -1.11885e-23f, -1.78506e-30f,
     67     -5.07594e-31f,                           -3.65799e-31f, -1.43718e-34f,
     68     -1.27126e-38f,                           -0.0f,         0.0f,
     69     1.17549e-38f,                            1.56657e-37f,  4.08512e-29f,
     70     3.31357e-28f,                            6.25073e-22f,  4.1723e-13f,
     71     1.44343e-09f,                            5.27004e-08f,  9.48298e-08f,
     72     5.57888e-07f,                            4.89988e-05f,  0.244326f,
     73     12.4895f,                                19.0f,         47.0f,
     74     106.0f,                                  538.324f,      564.536f,
     75     819.124f,                                7048.0f,       12611.0f,
     76     19878.0f,                                20309.0f,      797056.0f,
     77     1.77219e+09f,                            1.51116e+11f,  4.18193e+13f,
     78     3.59167e+16f,                            3.38211e+19f,  2.67488e+20f,
     79     1.78831e+21f,                            9.20914e+21f,  8.35654e+23f,
     80     1.4495e+24f,                             5.94015e+25f,  4.43608e+30f,
     81     2.44502e+33f,                            2.61152e+33f,  1.38178e+37f,
     82     1.71306e+37f,                            3.31899e+38f,  3.40282e+38f,
     83     std::numeric_limits<float>::infinity()};
     84 
     85 
     86 static const double kFloat64Values[] = {
     87     -V8_INFINITY,  -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212,
     88     -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100,
     89     -1.67813e+72,  -2.3382e+55,   -3.179e+30,    -1.441e+09,    -1.0647e+09,
     90     -7.99361e+08,  -5.77375e+08,  -2.20984e+08,  -32757,        -13171,
     91     -9970,         -3984,         -107,          -105,          -92,
     92     -77,           -61,           -0.000208163,  -1.86685e-06,  -1.17296e-10,
     93     -9.26358e-11,  -5.08004e-60,  -1.74753e-65,  -1.06561e-71,  -5.67879e-79,
     94     -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
     95     -4.40497e-267, -2.19666e-273, -4.9998e-276,  -5.59821e-278, -2.03855e-282,
     96     -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0,          0.0,
     97     2.22507e-308,  1.30127e-270,  7.62898e-260,  4.00313e-249,  3.16829e-233,
     98     1.85244e-228,  2.03544e-129,  1.35126e-110,  1.01182e-106,  5.26333e-94,
     99     1.35292e-90,   2.85394e-83,   1.78323e-77,   5.4967e-57,    1.03207e-25,
    100     4.57401e-25,   1.58738e-05,   2,             125,           2310,
    101     9636,          14802,         17168,         28945,         29305,
    102     4.81336e+07,   1.41207e+08,   4.65962e+08,   1.40499e+09,   2.12648e+09,
    103     8.80006e+30,   1.4446e+45,    1.12164e+54,   2.48188e+89,   6.71121e+102,
    104     3.074e+112,    4.9699e+152,   5.58383e+166,  4.30654e+172,  7.08824e+185,
    105     9.6586e+214,   2.028e+223,    6.63277e+243,  1.56192e+261,  1.23202e+269,
    106     5.72883e+289,  8.5798e+290,   1.40256e+294,  1.79769e+308,  V8_INFINITY};
    107 
    108 
    109 static const int32_t kInt32Values[] = {
    110     -2147483647 - 1, -1914954528, -1698749618, -1578693386, -1577976073,
    111     -1573998034,     -1529085059, -1499540537, -1299205097, -1090814845,
    112     -938186388,      -806828902,  -750927650,  -520676892,  -513661538,
    113     -453036354,      -433622833,  -282638793,  -28375,      -27788,
    114     -22770,          -18806,      -14173,      -11956,      -11200,
    115     -10212,          -8160,       -3751,       -2758,       -1522,
    116     -121,            -120,        -118,        -117,        -106,
    117     -84,             -80,         -74,         -59,         -52,
    118     -48,             -39,         -35,         -17,         -11,
    119     -10,             -9,          -7,          -5,          0,
    120     9,               12,          17,          23,          29,
    121     31,              33,          35,          40,          47,
    122     55,              56,          62,          64,          67,
    123     68,              69,          74,          79,          84,
    124     89,              90,          97,          104,         118,
    125     124,             126,         127,         7278,        17787,
    126     24136,           24202,       25570,       26680,       30242,
    127     32399,           420886487,   642166225,   821912648,   822577803,
    128     851385718,       1212241078,  1411419304,  1589626102,  1596437184,
    129     1876245816,      1954730266,  2008792749,  2045320228,  2147483647};
    130 
    131 
    132 static const int64_t kInt64Values[] = {
    133     V8_INT64_C(-9223372036854775807) - 1, V8_INT64_C(-8974392461363618006),
    134     V8_INT64_C(-8874367046689588135),     V8_INT64_C(-8269197512118230839),
    135     V8_INT64_C(-8146091527100606733),     V8_INT64_C(-7550917981466150848),
    136     V8_INT64_C(-7216590251577894337),     V8_INT64_C(-6464086891160048440),
    137     V8_INT64_C(-6365616494908257190),     V8_INT64_C(-6305630541365849726),
    138     V8_INT64_C(-5982222642272245453),     V8_INT64_C(-5510103099058504169),
    139     V8_INT64_C(-5496838675802432701),     V8_INT64_C(-4047626578868642657),
    140     V8_INT64_C(-4033755046900164544),     V8_INT64_C(-3554299241457877041),
    141     V8_INT64_C(-2482258764588614470),     V8_INT64_C(-1688515425526875335),
    142     V8_INT64_C(-924784137176548532),      V8_INT64_C(-725316567157391307),
    143     V8_INT64_C(-439022654781092241),      V8_INT64_C(-105545757668917080),
    144     V8_INT64_C(-2088319373),              V8_INT64_C(-2073699916),
    145     V8_INT64_C(-1844949911),              V8_INT64_C(-1831090548),
    146     V8_INT64_C(-1756711933),              V8_INT64_C(-1559409497),
    147     V8_INT64_C(-1281179700),              V8_INT64_C(-1211513985),
    148     V8_INT64_C(-1182371520),              V8_INT64_C(-785934753),
    149     V8_INT64_C(-767480697),               V8_INT64_C(-705745662),
    150     V8_INT64_C(-514362436),               V8_INT64_C(-459916580),
    151     V8_INT64_C(-312328082),               V8_INT64_C(-302949707),
    152     V8_INT64_C(-285499304),               V8_INT64_C(-125701262),
    153     V8_INT64_C(-95139843),                V8_INT64_C(-32768),
    154     V8_INT64_C(-27542),                   V8_INT64_C(-23600),
    155     V8_INT64_C(-18582),                   V8_INT64_C(-17770),
    156     V8_INT64_C(-9086),                    V8_INT64_C(-9010),
    157     V8_INT64_C(-8244),                    V8_INT64_C(-2890),
    158     V8_INT64_C(-103),                     V8_INT64_C(-34),
    159     V8_INT64_C(-27),                      V8_INT64_C(-25),
    160     V8_INT64_C(-9),                       V8_INT64_C(-7),
    161     V8_INT64_C(0),                        V8_INT64_C(2),
    162     V8_INT64_C(38),                       V8_INT64_C(58),
    163     V8_INT64_C(65),                       V8_INT64_C(93),
    164     V8_INT64_C(111),                      V8_INT64_C(1003),
    165     V8_INT64_C(1267),                     V8_INT64_C(12797),
    166     V8_INT64_C(23122),                    V8_INT64_C(28200),
    167     V8_INT64_C(30888),                    V8_INT64_C(42648848),
    168     V8_INT64_C(116836693),                V8_INT64_C(263003643),
    169     V8_INT64_C(571039860),                V8_INT64_C(1079398689),
    170     V8_INT64_C(1145196402),               V8_INT64_C(1184846321),
    171     V8_INT64_C(1758281648),               V8_INT64_C(1859991374),
    172     V8_INT64_C(1960251588),               V8_INT64_C(2042443199),
    173     V8_INT64_C(296220586027987448),       V8_INT64_C(1015494173071134726),
    174     V8_INT64_C(1151237951914455318),      V8_INT64_C(1331941174616854174),
    175     V8_INT64_C(2022020418667972654),      V8_INT64_C(2450251424374977035),
    176     V8_INT64_C(3668393562685561486),      V8_INT64_C(4858229301215502171),
    177     V8_INT64_C(4919426235170669383),      V8_INT64_C(5034286595330341762),
    178     V8_INT64_C(5055797915536941182),      V8_INT64_C(6072389716149252074),
    179     V8_INT64_C(6185309910199801210),      V8_INT64_C(6297328311011094138),
    180     V8_INT64_C(6932372858072165827),      V8_INT64_C(8483640924987737210),
    181     V8_INT64_C(8663764179455849203),      V8_INT64_C(8877197042645298254),
    182     V8_INT64_C(8901543506779157333),      V8_INT64_C(9223372036854775807)};
    183 
    184 
    185 static const uint32_t kUint32Values[] = {
    186     0x00000000, 0x00000001, 0xffffffff, 0x1b09788b, 0x04c5fce8, 0xcc0de5bf,
    187     0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
    188     0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
    189     0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
    190     0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000,
    191     0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
    192     0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff,
    193     0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff};
    194 
    195 }  // namespace
    196 
    197 
    198 // -----------------------------------------------------------------------------
    199 // Unary operators
    200 
    201 
    202 namespace {
    203 
    204 struct UnaryOperator {
    205   const Operator* (MachineOperatorBuilder::*constructor)();
    206   const char* constructor_name;
    207 };
    208 
    209 
    210 std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
    211   return os << unop.constructor_name;
    212 }
    213 
    214 
    215 static const UnaryOperator kUnaryOperators[] = {
    216     {&MachineOperatorBuilder::ChangeInt32ToFloat64, "ChangeInt32ToFloat64"},
    217     {&MachineOperatorBuilder::ChangeUint32ToFloat64, "ChangeUint32ToFloat64"},
    218     {&MachineOperatorBuilder::ChangeFloat64ToInt32, "ChangeFloat64ToInt32"},
    219     {&MachineOperatorBuilder::ChangeFloat64ToUint32, "ChangeFloat64ToUint32"},
    220     {&MachineOperatorBuilder::ChangeInt32ToInt64, "ChangeInt32ToInt64"},
    221     {&MachineOperatorBuilder::ChangeUint32ToUint64, "ChangeUint32ToUint64"},
    222     {&MachineOperatorBuilder::TruncateFloat64ToInt32, "TruncateFloat64ToInt32"},
    223     {&MachineOperatorBuilder::TruncateInt64ToInt32, "TruncateInt64ToInt32"}};
    224 
    225 }  // namespace
    226 
    227 
    228 typedef MachineOperatorReducerTestWithParam<UnaryOperator>
    229     MachineUnaryOperatorReducerTest;
    230 
    231 
    232 TEST_P(MachineUnaryOperatorReducerTest, Parameter) {
    233   const UnaryOperator unop = GetParam();
    234   Reduction reduction =
    235       Reduce(graph()->NewNode((machine()->*unop.constructor)(), Parameter(0)));
    236   EXPECT_FALSE(reduction.Changed());
    237 }
    238 
    239 
    240 INSTANTIATE_TEST_CASE_P(MachineOperatorReducerTest,
    241                         MachineUnaryOperatorReducerTest,
    242                         ::testing::ValuesIn(kUnaryOperators));
    243 
    244 
    245 // -----------------------------------------------------------------------------
    246 // ChangeFloat64ToFloat32
    247 
    248 
    249 TEST_F(MachineOperatorReducerTest, ChangeFloat64ToFloat32WithConstant) {
    250   TRACED_FOREACH(float, x, kFloat32Values) {
    251     Reduction reduction = Reduce(graph()->NewNode(
    252         machine()->ChangeFloat32ToFloat64(), Float32Constant(x)));
    253     ASSERT_TRUE(reduction.Changed());
    254     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(x));
    255   }
    256 }
    257 
    258 
    259 // -----------------------------------------------------------------------------
    260 // ChangeFloat64ToInt32
    261 
    262 
    263 TEST_F(MachineOperatorReducerTest,
    264        ChangeFloat64ToInt32WithChangeInt32ToFloat64) {
    265   Node* value = Parameter(0);
    266   Reduction reduction = Reduce(graph()->NewNode(
    267       machine()->ChangeFloat64ToInt32(),
    268       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
    269   ASSERT_TRUE(reduction.Changed());
    270   EXPECT_EQ(value, reduction.replacement());
    271 }
    272 
    273 
    274 TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt32WithConstant) {
    275   TRACED_FOREACH(int32_t, x, kInt32Values) {
    276     Reduction reduction = Reduce(graph()->NewNode(
    277         machine()->ChangeFloat64ToInt32(), Float64Constant(FastI2D(x))));
    278     ASSERT_TRUE(reduction.Changed());
    279     EXPECT_THAT(reduction.replacement(), IsInt32Constant(x));
    280   }
    281 }
    282 
    283 
    284 // -----------------------------------------------------------------------------
    285 // ChangeFloat64ToUint32
    286 
    287 
    288 TEST_F(MachineOperatorReducerTest,
    289        ChangeFloat64ToUint32WithChangeUint32ToFloat64) {
    290   Node* value = Parameter(0);
    291   Reduction reduction = Reduce(graph()->NewNode(
    292       machine()->ChangeFloat64ToUint32(),
    293       graph()->NewNode(machine()->ChangeUint32ToFloat64(), value)));
    294   ASSERT_TRUE(reduction.Changed());
    295   EXPECT_EQ(value, reduction.replacement());
    296 }
    297 
    298 
    299 TEST_F(MachineOperatorReducerTest, ChangeFloat64ToUint32WithConstant) {
    300   TRACED_FOREACH(uint32_t, x, kUint32Values) {
    301     Reduction reduction = Reduce(graph()->NewNode(
    302         machine()->ChangeFloat64ToUint32(), Float64Constant(FastUI2D(x))));
    303     ASSERT_TRUE(reduction.Changed());
    304     EXPECT_THAT(reduction.replacement(), IsInt32Constant(bit_cast<int32_t>(x)));
    305   }
    306 }
    307 
    308 
    309 // -----------------------------------------------------------------------------
    310 // ChangeInt32ToFloat64
    311 
    312 
    313 TEST_F(MachineOperatorReducerTest, ChangeInt32ToFloat64WithConstant) {
    314   TRACED_FOREACH(int32_t, x, kInt32Values) {
    315     Reduction reduction = Reduce(
    316         graph()->NewNode(machine()->ChangeInt32ToFloat64(), Int32Constant(x)));
    317     ASSERT_TRUE(reduction.Changed());
    318     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(FastI2D(x)));
    319   }
    320 }
    321 
    322 
    323 // -----------------------------------------------------------------------------
    324 // ChangeInt32ToInt64
    325 
    326 
    327 TEST_F(MachineOperatorReducerTest, ChangeInt32ToInt64WithConstant) {
    328   TRACED_FOREACH(int32_t, x, kInt32Values) {
    329     Reduction reduction = Reduce(
    330         graph()->NewNode(machine()->ChangeInt32ToInt64(), Int32Constant(x)));
    331     ASSERT_TRUE(reduction.Changed());
    332     EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
    333   }
    334 }
    335 
    336 
    337 // -----------------------------------------------------------------------------
    338 // ChangeUint32ToFloat64
    339 
    340 
    341 TEST_F(MachineOperatorReducerTest, ChangeUint32ToFloat64WithConstant) {
    342   TRACED_FOREACH(uint32_t, x, kUint32Values) {
    343     Reduction reduction =
    344         Reduce(graph()->NewNode(machine()->ChangeUint32ToFloat64(),
    345                                 Int32Constant(bit_cast<int32_t>(x))));
    346     ASSERT_TRUE(reduction.Changed());
    347     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(FastUI2D(x)));
    348   }
    349 }
    350 
    351 
    352 // -----------------------------------------------------------------------------
    353 // ChangeUint32ToUint64
    354 
    355 
    356 TEST_F(MachineOperatorReducerTest, ChangeUint32ToUint64WithConstant) {
    357   TRACED_FOREACH(uint32_t, x, kUint32Values) {
    358     Reduction reduction =
    359         Reduce(graph()->NewNode(machine()->ChangeUint32ToUint64(),
    360                                 Int32Constant(bit_cast<int32_t>(x))));
    361     ASSERT_TRUE(reduction.Changed());
    362     EXPECT_THAT(reduction.replacement(),
    363                 IsInt64Constant(bit_cast<int64_t>(static_cast<uint64_t>(x))));
    364   }
    365 }
    366 
    367 
    368 // -----------------------------------------------------------------------------
    369 // TruncateFloat64ToFloat32
    370 
    371 
    372 TEST_F(MachineOperatorReducerTest,
    373        TruncateFloat64ToFloat32WithChangeFloat32ToFloat64) {
    374   Node* value = Parameter(0);
    375   Reduction reduction = Reduce(graph()->NewNode(
    376       machine()->TruncateFloat64ToFloat32(),
    377       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), value)));
    378   ASSERT_TRUE(reduction.Changed());
    379   EXPECT_EQ(value, reduction.replacement());
    380 }
    381 
    382 
    383 TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
    384   TRACED_FOREACH(double, x, kFloat64Values) {
    385     Reduction reduction = Reduce(graph()->NewNode(
    386         machine()->TruncateFloat64ToFloat32(), Float64Constant(x)));
    387     ASSERT_TRUE(reduction.Changed());
    388     EXPECT_THAT(reduction.replacement(), IsFloat32Constant(DoubleToFloat32(x)));
    389   }
    390 }
    391 
    392 
    393 // -----------------------------------------------------------------------------
    394 // TruncateFloat64ToInt32
    395 
    396 
    397 TEST_F(MachineOperatorReducerTest,
    398        TruncateFloat64ToInt32WithChangeInt32ToFloat64) {
    399   Node* value = Parameter(0);
    400   Reduction reduction = Reduce(graph()->NewNode(
    401       machine()->TruncateFloat64ToInt32(),
    402       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
    403   ASSERT_TRUE(reduction.Changed());
    404   EXPECT_EQ(value, reduction.replacement());
    405 }
    406 
    407 
    408 TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithConstant) {
    409   TRACED_FOREACH(double, x, kFloat64Values) {
    410     Reduction reduction = Reduce(graph()->NewNode(
    411         machine()->TruncateFloat64ToInt32(), Float64Constant(x)));
    412     ASSERT_TRUE(reduction.Changed());
    413     EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
    414   }
    415 }
    416 
    417 
    418 // -----------------------------------------------------------------------------
    419 // TruncateInt64ToInt32
    420 
    421 
    422 TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithChangeInt32ToInt64) {
    423   Node* value = Parameter(0);
    424   Reduction reduction = Reduce(graph()->NewNode(
    425       machine()->TruncateInt64ToInt32(),
    426       graph()->NewNode(machine()->ChangeInt32ToInt64(), value)));
    427   ASSERT_TRUE(reduction.Changed());
    428   EXPECT_EQ(value, reduction.replacement());
    429 }
    430 
    431 
    432 TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithConstant) {
    433   TRACED_FOREACH(int64_t, x, kInt64Values) {
    434     Reduction reduction = Reduce(
    435         graph()->NewNode(machine()->TruncateInt64ToInt32(), Int64Constant(x)));
    436     ASSERT_TRUE(reduction.Changed());
    437     EXPECT_THAT(reduction.replacement(),
    438                 IsInt32Constant(bit_cast<int32_t>(
    439                     static_cast<uint32_t>(bit_cast<uint64_t>(x)))));
    440   }
    441 }
    442 
    443 
    444 // -----------------------------------------------------------------------------
    445 // Word32Ror
    446 
    447 
    448 TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
    449   Node* value = Parameter(0);
    450   Node* shift = Parameter(1);
    451   Node* shl = graph()->NewNode(machine()->Word32Shl(), value, shift);
    452   Node* shr = graph()->NewNode(
    453       machine()->Word32Shr(), value,
    454       graph()->NewNode(machine()->Int32Sub(), Int32Constant(32), shift));
    455 
    456   // (x << y) | (x >> (32 - y)) => x ror y
    457   Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
    458   Reduction reduction1 = Reduce(node1);
    459   EXPECT_TRUE(reduction1.Changed());
    460   EXPECT_EQ(reduction1.replacement(), node1);
    461   EXPECT_THAT(reduction1.replacement(), IsWord32Ror(value, shift));
    462 
    463   // (x >> (32 - y)) | (x << y) => x ror y
    464   Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
    465   Reduction reduction2 = Reduce(node2);
    466   EXPECT_TRUE(reduction2.Changed());
    467   EXPECT_EQ(reduction2.replacement(), node2);
    468   EXPECT_THAT(reduction2.replacement(), IsWord32Ror(value, shift));
    469 }
    470 
    471 
    472 TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
    473   Node* value = Parameter(0);
    474   TRACED_FORRANGE(int32_t, k, 0, 31) {
    475     Node* shl =
    476         graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(k));
    477     Node* shr =
    478         graph()->NewNode(machine()->Word32Shr(), value, Int32Constant(32 - k));
    479 
    480     // (x << K) | (x >> ((32 - K) - y)) => x ror K
    481     Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
    482     Reduction reduction1 = Reduce(node1);
    483     EXPECT_TRUE(reduction1.Changed());
    484     EXPECT_EQ(reduction1.replacement(), node1);
    485     EXPECT_THAT(reduction1.replacement(),
    486                 IsWord32Ror(value, IsInt32Constant(k)));
    487 
    488     // (x >> (32 - K)) | (x << K) => x ror K
    489     Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
    490     Reduction reduction2 = Reduce(node2);
    491     EXPECT_TRUE(reduction2.Changed());
    492     EXPECT_EQ(reduction2.replacement(), node2);
    493     EXPECT_THAT(reduction2.replacement(),
    494                 IsWord32Ror(value, IsInt32Constant(k)));
    495   }
    496 }
    497 
    498 
    499 TEST_F(MachineOperatorReducerTest, Word32RorWithZeroShift) {
    500   Node* value = Parameter(0);
    501   Node* node =
    502       graph()->NewNode(machine()->Word32Ror(), value, Int32Constant(0));
    503   Reduction reduction = Reduce(node);
    504   EXPECT_TRUE(reduction.Changed());
    505   EXPECT_EQ(reduction.replacement(), value);
    506 }
    507 
    508 
    509 TEST_F(MachineOperatorReducerTest, Word32RorWithConstants) {
    510   TRACED_FOREACH(int32_t, x, kUint32Values) {
    511     TRACED_FORRANGE(int32_t, y, 0, 31) {
    512       Node* node = graph()->NewNode(machine()->Word32Ror(), Int32Constant(x),
    513                                     Int32Constant(y));
    514       Reduction reduction = Reduce(node);
    515       EXPECT_TRUE(reduction.Changed());
    516       EXPECT_THAT(reduction.replacement(),
    517                   IsInt32Constant(base::bits::RotateRight32(x, y)));
    518     }
    519   }
    520 }
    521 
    522 
    523 // -----------------------------------------------------------------------------
    524 // Int32AddWithOverflow
    525 
    526 
    527 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
    528   Node* p0 = Parameter(0);
    529   {
    530     Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
    531                                  Int32Constant(0), p0);
    532 
    533     Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
    534     ASSERT_TRUE(r.Changed());
    535     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    536 
    537     r = Reduce(graph()->NewNode(common()->Projection(0), add));
    538     ASSERT_TRUE(r.Changed());
    539     EXPECT_EQ(p0, r.replacement());
    540   }
    541   {
    542     Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
    543                                  Int32Constant(0));
    544 
    545     Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
    546     ASSERT_TRUE(r.Changed());
    547     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    548 
    549     r = Reduce(graph()->NewNode(common()->Projection(0), add));
    550     ASSERT_TRUE(r.Changed());
    551     EXPECT_EQ(p0, r.replacement());
    552   }
    553 }
    554 
    555 
    556 TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
    557   TRACED_FOREACH(int32_t, x, kInt32Values) {
    558     TRACED_FOREACH(int32_t, y, kInt32Values) {
    559       int32_t z;
    560       Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
    561                                    Int32Constant(x), Int32Constant(y));
    562 
    563       Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
    564       ASSERT_TRUE(r.Changed());
    565       EXPECT_THAT(r.replacement(),
    566                   IsInt32Constant(base::bits::SignedAddOverflow32(x, y, &z)));
    567 
    568       r = Reduce(graph()->NewNode(common()->Projection(0), add));
    569       ASSERT_TRUE(r.Changed());
    570       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
    571     }
    572   }
    573 }
    574 
    575 
    576 // -----------------------------------------------------------------------------
    577 // Int32SubWithOverflow
    578 
    579 
    580 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
    581   Node* p0 = Parameter(0);
    582   Node* add =
    583       graph()->NewNode(machine()->Int32SubWithOverflow(), p0, Int32Constant(0));
    584 
    585   Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
    586   ASSERT_TRUE(r.Changed());
    587   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    588 
    589   r = Reduce(graph()->NewNode(common()->Projection(0), add));
    590   ASSERT_TRUE(r.Changed());
    591   EXPECT_EQ(p0, r.replacement());
    592 }
    593 
    594 
    595 TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
    596   TRACED_FOREACH(int32_t, x, kInt32Values) {
    597     TRACED_FOREACH(int32_t, y, kInt32Values) {
    598       int32_t z;
    599       Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
    600                                    Int32Constant(x), Int32Constant(y));
    601 
    602       Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
    603       ASSERT_TRUE(r.Changed());
    604       EXPECT_THAT(r.replacement(),
    605                   IsInt32Constant(base::bits::SignedSubOverflow32(x, y, &z)));
    606 
    607       r = Reduce(graph()->NewNode(common()->Projection(0), add));
    608       ASSERT_TRUE(r.Changed());
    609       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
    610     }
    611   }
    612 }
    613 
    614 }  // namespace compiler
    615 }  // namespace internal
    616 }  // namespace v8
    617