LCOV - code coverage report
Current view: top level - test/unittests/compiler - machine-operator-reducer-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 875 940 93.1 %
Date: 2019-03-21 Functions: 207 308 67.2 %

          Line data    Source code
       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/machine-operator-reducer.h"
       6             : #include "src/base/bits.h"
       7             : #include "src/base/division-by-constant.h"
       8             : #include "src/base/ieee754.h"
       9             : #include "src/base/overflowing-math.h"
      10             : #include "src/compiler/js-graph.h"
      11             : #include "src/compiler/typer.h"
      12             : #include "src/conversions-inl.h"
      13             : #include "test/unittests/compiler/graph-unittest.h"
      14             : #include "test/unittests/compiler/node-test-utils.h"
      15             : #include "testing/gmock-support.h"
      16             : 
      17             : using testing::AllOf;
      18             : using testing::BitEq;
      19             : using testing::Capture;
      20             : using testing::CaptureEq;
      21             : using testing::NanSensitiveDoubleEq;
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : namespace compiler {
      26             : 
      27         101 : class MachineOperatorReducerTest : public GraphTest {
      28             :  public:
      29         101 :   explicit MachineOperatorReducerTest(int num_parameters = 2)
      30             :       : GraphTest(num_parameters),
      31             :         machine_(zone()),
      32             :         common_(zone()),
      33             :         javascript_(zone()),
      34             :         jsgraph_(isolate(), graph(), &common_, &javascript_, nullptr,
      35             :                  &machine_),
      36         303 :         graph_reducer_(zone(), graph(), jsgraph_.Dead()) {}
      37             : 
      38             :  protected:
      39      180224 :   Reduction Reduce(Node* node) {
      40      180224 :     JSOperatorBuilder javascript(zone());
      41             :     JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
      42      360448 :                     &machine_);
      43      360448 :     MachineOperatorReducer reducer(&graph_reducer_, &jsgraph);
      44      360448 :     return reducer.Reduce(node);
      45             :   }
      46             : 
      47         194 :   Matcher<Node*> IsTruncatingDiv(const Matcher<Node*>& dividend_matcher,
      48             :                                  const int32_t divisor) {
      49             :     base::MagicNumbersForDivision<uint32_t> const mag =
      50         194 :         base::SignedDivisionByConstant(bit_cast<uint32_t>(divisor));
      51             :     int32_t const multiplier = bit_cast<int32_t>(mag.multiplier);
      52             :     int32_t const shift = bit_cast<int32_t>(mag.shift);
      53             :     Matcher<Node*> quotient_matcher =
      54         582 :         IsInt32MulHigh(dividend_matcher, IsInt32Constant(multiplier));
      55         194 :     if (divisor > 0 && multiplier < 0) {
      56         136 :       quotient_matcher = IsInt32Add(quotient_matcher, dividend_matcher);
      57         126 :     } else if (divisor < 0 && multiplier > 0) {
      58           0 :       quotient_matcher = IsInt32Sub(quotient_matcher, dividend_matcher);
      59             :     }
      60         194 :     if (shift) {
      61         776 :       quotient_matcher = IsWord32Sar(quotient_matcher, IsInt32Constant(shift));
      62             :     }
      63             :     return IsInt32Add(quotient_matcher,
      64         970 :                       IsWord32Shr(dividend_matcher, IsInt32Constant(31)));
      65             :   }
      66             : 
      67      118979 :   MachineOperatorBuilder* machine() { return &machine_; }
      68             : 
      69             :  private:
      70             :   MachineOperatorBuilder machine_;
      71             :   CommonOperatorBuilder common_;
      72             :   JSOperatorBuilder javascript_;
      73             :   JSGraph jsgraph_;
      74             :   GraphReducer graph_reducer_;
      75             : };
      76             : 
      77             : 
      78             : template <typename T>
      79             : class MachineOperatorReducerTestWithParam
      80             :     : public MachineOperatorReducerTest,
      81             :       public ::testing::WithParamInterface<T> {
      82             :  public:
      83             :   explicit MachineOperatorReducerTestWithParam(int num_parameters = 2)
      84             :       : MachineOperatorReducerTest(num_parameters) {}
      85             :   ~MachineOperatorReducerTestWithParam() override = default;
      86             : };
      87             : 
      88             : 
      89             : namespace {
      90             : 
      91             : const float kFloat32Values[] = {
      92             :     -std::numeric_limits<float>::infinity(), -2.70497e+38f, -1.4698e+37f,
      93             :     -1.22813e+35f,                           -1.20555e+35f, -1.34584e+34f,
      94             :     -1.0079e+32f,                            -6.49364e+26f, -3.06077e+25f,
      95             :     -1.46821e+25f,                           -1.17658e+23f, -1.9617e+22f,
      96             :     -2.7357e+20f,                            -1.48708e+13f, -1.89633e+12f,
      97             :     -4.66622e+11f,                           -2.22581e+11f, -1.45381e+10f,
      98             :     -1.3956e+09f,                            -1.32951e+09f, -1.30721e+09f,
      99             :     -1.19756e+09f,                           -9.26822e+08f, -6.35647e+08f,
     100             :     -4.00037e+08f,                           -1.81227e+08f, -5.09256e+07f,
     101             :     -964300.0f,                              -192446.0f,    -28455.0f,
     102             :     -27194.0f,                               -26401.0f,     -20575.0f,
     103             :     -17069.0f,                               -9167.0f,      -960.178f,
     104             :     -113.0f,                                 -62.0f,        -15.0f,
     105             :     -7.0f,                                   -0.0256635f,   -4.60374e-07f,
     106             :     -3.63759e-10f,                           -4.30175e-14f, -5.27385e-15f,
     107             :     -1.48084e-15f,                           -1.05755e-19f, -3.2995e-21f,
     108             :     -1.67354e-23f,                           -1.11885e-23f, -1.78506e-30f,
     109             :     -5.07594e-31f,                           -3.65799e-31f, -1.43718e-34f,
     110             :     -1.27126e-38f,                           -0.0f,         0.0f,
     111             :     1.17549e-38f,                            1.56657e-37f,  4.08512e-29f,
     112             :     3.31357e-28f,                            6.25073e-22f,  4.1723e-13f,
     113             :     1.44343e-09f,                            5.27004e-08f,  9.48298e-08f,
     114             :     5.57888e-07f,                            4.89988e-05f,  0.244326f,
     115             :     12.4895f,                                19.0f,         47.0f,
     116             :     106.0f,                                  538.324f,      564.536f,
     117             :     819.124f,                                7048.0f,       12611.0f,
     118             :     19878.0f,                                20309.0f,      797056.0f,
     119             :     1.77219e+09f,                            1.51116e+11f,  4.18193e+13f,
     120             :     3.59167e+16f,                            3.38211e+19f,  2.67488e+20f,
     121             :     1.78831e+21f,                            9.20914e+21f,  8.35654e+23f,
     122             :     1.4495e+24f,                             5.94015e+25f,  4.43608e+30f,
     123             :     2.44502e+33f,                            2.61152e+33f,  1.38178e+37f,
     124             :     1.71306e+37f,                            3.31899e+38f,  3.40282e+38f,
     125             :     std::numeric_limits<float>::infinity()};
     126             : 
     127             : 
     128             : const double kFloat64Values[] = {
     129             :     -V8_INFINITY,  -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212,
     130             :     -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100,
     131             :     -1.67813e+72,  -2.3382e+55,   -3.179e+30,    -1.441e+09,    -1.0647e+09,
     132             :     -7.99361e+08,  -5.77375e+08,  -2.20984e+08,  -32757,        -13171,
     133             :     -9970,         -3984,         -107,          -105,          -92,
     134             :     -77,           -61,           -0.000208163,  -1.86685e-06,  -1.17296e-10,
     135             :     -9.26358e-11,  -5.08004e-60,  -1.74753e-65,  -1.06561e-71,  -5.67879e-79,
     136             :     -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
     137             :     -4.40497e-267, -2.19666e-273, -4.9998e-276,  -5.59821e-278, -2.03855e-282,
     138             :     -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0,          0.0,
     139             :     2.22507e-308,  1.30127e-270,  7.62898e-260,  4.00313e-249,  3.16829e-233,
     140             :     1.85244e-228,  2.03544e-129,  1.35126e-110,  1.01182e-106,  5.26333e-94,
     141             :     1.35292e-90,   2.85394e-83,   1.78323e-77,   5.4967e-57,    1.03207e-25,
     142             :     4.57401e-25,   1.58738e-05,   2,             125,           2310,
     143             :     9636,          14802,         17168,         28945,         29305,
     144             :     4.81336e+07,   1.41207e+08,   4.65962e+08,   1.40499e+09,   2.12648e+09,
     145             :     8.80006e+30,   1.4446e+45,    1.12164e+54,   2.48188e+89,   6.71121e+102,
     146             :     3.074e+112,    4.9699e+152,   5.58383e+166,  4.30654e+172,  7.08824e+185,
     147             :     9.6586e+214,   2.028e+223,    6.63277e+243,  1.56192e+261,  1.23202e+269,
     148             :     5.72883e+289,  8.5798e+290,   1.40256e+294,  1.79769e+308,  V8_INFINITY};
     149             : 
     150             : 
     151             : const int32_t kInt32Values[] = {
     152             :     std::numeric_limits<int32_t>::min(), -1914954528, -1698749618,
     153             :     -1578693386,                         -1577976073, -1573998034,
     154             :     -1529085059,                         -1499540537, -1299205097,
     155             :     -1090814845,                         -938186388,  -806828902,
     156             :     -750927650,                          -520676892,  -513661538,
     157             :     -453036354,                          -433622833,  -282638793,
     158             :     -28375,                              -27788,      -22770,
     159             :     -18806,                              -14173,      -11956,
     160             :     -11200,                              -10212,      -8160,
     161             :     -3751,                               -2758,       -1522,
     162             :     -121,                                -120,        -118,
     163             :     -117,                                -106,        -84,
     164             :     -80,                                 -74,         -59,
     165             :     -52,                                 -48,         -39,
     166             :     -35,                                 -17,         -11,
     167             :     -10,                                 -9,          -7,
     168             :     -5,                                  0,           9,
     169             :     12,                                  17,          23,
     170             :     29,                                  31,          33,
     171             :     35,                                  40,          47,
     172             :     55,                                  56,          62,
     173             :     64,                                  67,          68,
     174             :     69,                                  74,          79,
     175             :     84,                                  89,          90,
     176             :     97,                                  104,         118,
     177             :     124,                                 126,         127,
     178             :     7278,                                17787,       24136,
     179             :     24202,                               25570,       26680,
     180             :     30242,                               32399,       420886487,
     181             :     642166225,                           821912648,   822577803,
     182             :     851385718,                           1212241078,  1411419304,
     183             :     1589626102,                          1596437184,  1876245816,
     184             :     1954730266,                          2008792749,  2045320228,
     185             :     std::numeric_limits<int32_t>::max()};
     186             : 
     187             : const int64_t kInt64Values[] = {std::numeric_limits<int64_t>::min(),
     188             :                                 int64_t{-8974392461363618006},
     189             :                                 int64_t{-8874367046689588135},
     190             :                                 int64_t{-8269197512118230839},
     191             :                                 int64_t{-8146091527100606733},
     192             :                                 int64_t{-7550917981466150848},
     193             :                                 int64_t{-7216590251577894337},
     194             :                                 int64_t{-6464086891160048440},
     195             :                                 int64_t{-6365616494908257190},
     196             :                                 int64_t{-6305630541365849726},
     197             :                                 int64_t{-5982222642272245453},
     198             :                                 int64_t{-5510103099058504169},
     199             :                                 int64_t{-5496838675802432701},
     200             :                                 int64_t{-4047626578868642657},
     201             :                                 int64_t{-4033755046900164544},
     202             :                                 int64_t{-3554299241457877041},
     203             :                                 int64_t{-2482258764588614470},
     204             :                                 int64_t{-1688515425526875335},
     205             :                                 int64_t{-924784137176548532},
     206             :                                 int64_t{-725316567157391307},
     207             :                                 int64_t{-439022654781092241},
     208             :                                 int64_t{-105545757668917080},
     209             :                                 int64_t{-2088319373},
     210             :                                 int64_t{-2073699916},
     211             :                                 int64_t{-1844949911},
     212             :                                 int64_t{-1831090548},
     213             :                                 int64_t{-1756711933},
     214             :                                 int64_t{-1559409497},
     215             :                                 int64_t{-1281179700},
     216             :                                 int64_t{-1211513985},
     217             :                                 int64_t{-1182371520},
     218             :                                 int64_t{-785934753},
     219             :                                 int64_t{-767480697},
     220             :                                 int64_t{-705745662},
     221             :                                 int64_t{-514362436},
     222             :                                 int64_t{-459916580},
     223             :                                 int64_t{-312328082},
     224             :                                 int64_t{-302949707},
     225             :                                 int64_t{-285499304},
     226             :                                 int64_t{-125701262},
     227             :                                 int64_t{-95139843},
     228             :                                 int64_t{-32768},
     229             :                                 int64_t{-27542},
     230             :                                 int64_t{-23600},
     231             :                                 int64_t{-18582},
     232             :                                 int64_t{-17770},
     233             :                                 int64_t{-9086},
     234             :                                 int64_t{-9010},
     235             :                                 int64_t{-8244},
     236             :                                 int64_t{-2890},
     237             :                                 int64_t{-103},
     238             :                                 int64_t{-34},
     239             :                                 int64_t{-27},
     240             :                                 int64_t{-25},
     241             :                                 int64_t{-9},
     242             :                                 int64_t{-7},
     243             :                                 int64_t{0},
     244             :                                 int64_t{2},
     245             :                                 int64_t{38},
     246             :                                 int64_t{58},
     247             :                                 int64_t{65},
     248             :                                 int64_t{93},
     249             :                                 int64_t{111},
     250             :                                 int64_t{1003},
     251             :                                 int64_t{1267},
     252             :                                 int64_t{12797},
     253             :                                 int64_t{23122},
     254             :                                 int64_t{28200},
     255             :                                 int64_t{30888},
     256             :                                 int64_t{42648848},
     257             :                                 int64_t{116836693},
     258             :                                 int64_t{263003643},
     259             :                                 int64_t{571039860},
     260             :                                 int64_t{1079398689},
     261             :                                 int64_t{1145196402},
     262             :                                 int64_t{1184846321},
     263             :                                 int64_t{1758281648},
     264             :                                 int64_t{1859991374},
     265             :                                 int64_t{1960251588},
     266             :                                 int64_t{2042443199},
     267             :                                 int64_t{296220586027987448},
     268             :                                 int64_t{1015494173071134726},
     269             :                                 int64_t{1151237951914455318},
     270             :                                 int64_t{1331941174616854174},
     271             :                                 int64_t{2022020418667972654},
     272             :                                 int64_t{2450251424374977035},
     273             :                                 int64_t{3668393562685561486},
     274             :                                 int64_t{4858229301215502171},
     275             :                                 int64_t{4919426235170669383},
     276             :                                 int64_t{5034286595330341762},
     277             :                                 int64_t{5055797915536941182},
     278             :                                 int64_t{6072389716149252074},
     279             :                                 int64_t{6185309910199801210},
     280             :                                 int64_t{6297328311011094138},
     281             :                                 int64_t{6932372858072165827},
     282             :                                 int64_t{8483640924987737210},
     283             :                                 int64_t{8663764179455849203},
     284             :                                 int64_t{8877197042645298254},
     285             :                                 int64_t{8901543506779157333},
     286             :                                 std::numeric_limits<int64_t>::max()};
     287             : 
     288             : const uint32_t kUint32Values[] = {
     289             :     0x00000000, 0x00000001, 0xFFFFFFFF, 0x1B09788B, 0x04C5FCE8, 0xCC0DE5BF,
     290             :     0x273A798E, 0x187937A3, 0xECE3AF83, 0x5495A16B, 0x0B668ECC, 0x11223344,
     291             :     0x0000009E, 0x00000043, 0x0000AF73, 0x0000116B, 0x00658ECC, 0x002B3B4C,
     292             :     0x88776655, 0x70000000, 0x07200000, 0x7FFFFFFF, 0x56123761, 0x7FFFFF00,
     293             :     0x761C4761, 0x80000000, 0x88888888, 0xA0000000, 0xDDDDDDDD, 0xE0000000,
     294             :     0xEEEEEEEE, 0xFFFFFFFD, 0xF0000000, 0x007FFFFF, 0x003FFFFF, 0x001FFFFF,
     295             :     0x000FFFFF, 0x0007FFFF, 0x0003FFFF, 0x0001FFFF, 0x0000FFFF, 0x00007FFF,
     296             :     0x00003FFF, 0x00001FFF, 0x00000FFF, 0x000007FF, 0x000003FF, 0x000001FF};
     297             : 
     298             : struct ComparisonBinaryOperator {
     299             :   const Operator* (MachineOperatorBuilder::*constructor)();
     300             :   const char* constructor_name;
     301             : };
     302             : 
     303             : 
     304             : std::ostream& operator<<(std::ostream& os,
     305             :                          ComparisonBinaryOperator const& cbop) {
     306          32 :   return os << cbop.constructor_name;
     307             : }
     308             : 
     309             : 
     310             : const ComparisonBinaryOperator kComparisonBinaryOperators[] = {
     311             : #define OPCODE(Opcode)                         \
     312             :   { &MachineOperatorBuilder::Opcode, #Opcode } \
     313             :   ,
     314             :     MACHINE_COMPARE_BINOP_LIST(OPCODE)
     315             : #undef OPCODE
     316             : };
     317             : 
     318             : // Avoid undefined behavior on signed integer overflow.
     319       24680 : int32_t Shl(int32_t x, int32_t y) { return static_cast<uint32_t>(x) << y; }
     320             : 
     321             : }  // namespace
     322             : 
     323             : 
     324             : // -----------------------------------------------------------------------------
     325             : // ChangeFloat64ToFloat32
     326             : 
     327             : 
     328       15374 : TEST_F(MachineOperatorReducerTest, ChangeFloat64ToFloat32WithConstant) {
     329         401 :   TRACED_FOREACH(float, x, kFloat32Values) {
     330             :     Reduction reduction = Reduce(graph()->NewNode(
     331         300 :         machine()->ChangeFloat32ToFloat64(), Float32Constant(x)));
     332         100 :     ASSERT_TRUE(reduction.Changed());
     333         500 :     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq<double>(x)));
     334             :   }
     335             : }
     336             : 
     337             : 
     338             : // -----------------------------------------------------------------------------
     339             : // ChangeFloat64ToInt32
     340             : 
     341             : 
     342       15374 : TEST_F(MachineOperatorReducerTest,
     343             :        ChangeFloat64ToInt32WithChangeInt32ToFloat64) {
     344           1 :   Node* value = Parameter(0);
     345             :   Reduction reduction = Reduce(graph()->NewNode(
     346             :       machine()->ChangeFloat64ToInt32(),
     347           3 :       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
     348           1 :   ASSERT_TRUE(reduction.Changed());
     349           2 :   EXPECT_EQ(value, reduction.replacement());
     350             : }
     351             : 
     352       15374 : TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt32WithConstant) {
     353         401 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     354             :     Reduction reduction = Reduce(graph()->NewNode(
     355         300 :         machine()->ChangeFloat64ToInt32(), Float64Constant(FastI2D(x))));
     356         100 :     ASSERT_TRUE(reduction.Changed());
     357         500 :     EXPECT_THAT(reduction.replacement(), IsInt32Constant(x));
     358             :   }
     359             : }
     360             : 
     361             : // -----------------------------------------------------------------------------
     362             : // ChangeFloat64ToInt64
     363             : 
     364       15374 : TEST_F(MachineOperatorReducerTest,
     365             :        ChangeFloat64ToInt64WithChangeInt64ToFloat64) {
     366           1 :   Node* value = Parameter(0);
     367             :   Reduction reduction = Reduce(graph()->NewNode(
     368             :       machine()->ChangeFloat64ToInt64(),
     369           3 :       graph()->NewNode(machine()->ChangeInt64ToFloat64(), value)));
     370           1 :   ASSERT_TRUE(reduction.Changed());
     371           2 :   EXPECT_EQ(value, reduction.replacement());
     372             : }
     373             : 
     374       15374 : TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt64WithConstant) {
     375         401 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     376             :     Reduction reduction = Reduce(graph()->NewNode(
     377         300 :         machine()->ChangeFloat64ToInt64(), Float64Constant(FastI2D(x))));
     378         100 :     ASSERT_TRUE(reduction.Changed());
     379         500 :     EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
     380             :   }
     381             : }
     382             : 
     383             : // -----------------------------------------------------------------------------
     384             : // ChangeFloat64ToUint32
     385             : 
     386             : 
     387       15374 : TEST_F(MachineOperatorReducerTest,
     388             :        ChangeFloat64ToUint32WithChangeUint32ToFloat64) {
     389           1 :   Node* value = Parameter(0);
     390             :   Reduction reduction = Reduce(graph()->NewNode(
     391             :       machine()->ChangeFloat64ToUint32(),
     392           3 :       graph()->NewNode(machine()->ChangeUint32ToFloat64(), value)));
     393           1 :   ASSERT_TRUE(reduction.Changed());
     394           2 :   EXPECT_EQ(value, reduction.replacement());
     395             : }
     396             : 
     397             : 
     398       15374 : TEST_F(MachineOperatorReducerTest, ChangeFloat64ToUint32WithConstant) {
     399         193 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
     400             :     Reduction reduction = Reduce(graph()->NewNode(
     401         144 :         machine()->ChangeFloat64ToUint32(), Float64Constant(FastUI2D(x))));
     402          48 :     ASSERT_TRUE(reduction.Changed());
     403         240 :     EXPECT_THAT(reduction.replacement(), IsInt32Constant(bit_cast<int32_t>(x)));
     404             :   }
     405             : }
     406             : 
     407             : 
     408             : // -----------------------------------------------------------------------------
     409             : // ChangeInt32ToFloat64
     410             : 
     411             : 
     412       15374 : TEST_F(MachineOperatorReducerTest, ChangeInt32ToFloat64WithConstant) {
     413         401 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     414             :     Reduction reduction = Reduce(
     415         300 :         graph()->NewNode(machine()->ChangeInt32ToFloat64(), Int32Constant(x)));
     416         100 :     ASSERT_TRUE(reduction.Changed());
     417         600 :     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastI2D(x))));
     418             :   }
     419             : }
     420             : 
     421             : 
     422             : // -----------------------------------------------------------------------------
     423             : // ChangeInt32ToInt64
     424             : 
     425             : 
     426       15374 : TEST_F(MachineOperatorReducerTest, ChangeInt32ToInt64WithConstant) {
     427         401 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     428             :     Reduction reduction = Reduce(
     429         300 :         graph()->NewNode(machine()->ChangeInt32ToInt64(), Int32Constant(x)));
     430         100 :     ASSERT_TRUE(reduction.Changed());
     431         500 :     EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
     432             :   }
     433             : }
     434             : 
     435             : // -----------------------------------------------------------------------------
     436             : // ChangeInt64ToFloat64
     437             : 
     438       15374 : TEST_F(MachineOperatorReducerTest,
     439             :        ChangeInt64ToFloat64WithChangeFloat64ToInt64) {
     440           1 :   Node* value = Parameter(0);
     441             :   Reduction reduction = Reduce(graph()->NewNode(
     442             :       machine()->ChangeInt64ToFloat64(),
     443           3 :       graph()->NewNode(machine()->ChangeFloat64ToInt64(), value)));
     444           1 :   ASSERT_TRUE(reduction.Changed());
     445           2 :   EXPECT_EQ(value, reduction.replacement());
     446             : }
     447             : 
     448       15374 : TEST_F(MachineOperatorReducerTest, ChangeInt64ToFloat64WithConstant) {
     449         401 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     450             :     Reduction reduction = Reduce(
     451         300 :         graph()->NewNode(machine()->ChangeInt64ToFloat64(), Int64Constant(x)));
     452         100 :     ASSERT_TRUE(reduction.Changed());
     453         600 :     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastI2D(x))));
     454             :   }
     455             : }
     456             : 
     457             : // -----------------------------------------------------------------------------
     458             : // ChangeUint32ToFloat64
     459             : 
     460             : 
     461       15374 : TEST_F(MachineOperatorReducerTest, ChangeUint32ToFloat64WithConstant) {
     462         193 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
     463             :     Reduction reduction =
     464             :         Reduce(graph()->NewNode(machine()->ChangeUint32ToFloat64(),
     465         144 :                                 Int32Constant(bit_cast<int32_t>(x))));
     466          48 :     ASSERT_TRUE(reduction.Changed());
     467         288 :     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastUI2D(x))));
     468             :   }
     469             : }
     470             : 
     471             : 
     472             : // -----------------------------------------------------------------------------
     473             : // ChangeUint32ToUint64
     474             : 
     475             : 
     476       15374 : TEST_F(MachineOperatorReducerTest, ChangeUint32ToUint64WithConstant) {
     477         193 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
     478             :     Reduction reduction =
     479             :         Reduce(graph()->NewNode(machine()->ChangeUint32ToUint64(),
     480         144 :                                 Int32Constant(bit_cast<int32_t>(x))));
     481          48 :     ASSERT_TRUE(reduction.Changed());
     482         240 :     EXPECT_THAT(reduction.replacement(),
     483           0 :                 IsInt64Constant(bit_cast<int64_t>(static_cast<uint64_t>(x))));
     484             :   }
     485             : }
     486             : 
     487             : 
     488             : // -----------------------------------------------------------------------------
     489             : // TruncateFloat64ToFloat32
     490             : 
     491             : 
     492       15374 : TEST_F(MachineOperatorReducerTest,
     493             :        TruncateFloat64ToFloat32WithChangeFloat32ToFloat64) {
     494           1 :   Node* value = Parameter(0);
     495             :   Reduction reduction = Reduce(graph()->NewNode(
     496             :       machine()->TruncateFloat64ToFloat32(),
     497           3 :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), value)));
     498           1 :   ASSERT_TRUE(reduction.Changed());
     499           2 :   EXPECT_EQ(value, reduction.replacement());
     500             : }
     501             : 
     502             : 
     503       15374 : TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
     504         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
     505             :     Reduction reduction = Reduce(graph()->NewNode(
     506         300 :         machine()->TruncateFloat64ToFloat32(), Float64Constant(x)));
     507         100 :     ASSERT_TRUE(reduction.Changed());
     508         600 :     EXPECT_THAT(reduction.replacement(),
     509           0 :                 IsFloat32Constant(BitEq(DoubleToFloat32(x))));
     510             :   }
     511             : }
     512             : 
     513             : 
     514             : // -----------------------------------------------------------------------------
     515             : // TruncateFloat64ToWord32
     516             : 
     517       15374 : TEST_F(MachineOperatorReducerTest,
     518             :        TruncateFloat64ToWord32WithChangeInt32ToFloat64) {
     519           1 :   Node* value = Parameter(0);
     520             :   Reduction reduction = Reduce(graph()->NewNode(
     521             :       machine()->TruncateFloat64ToWord32(),
     522           3 :       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
     523           1 :   ASSERT_TRUE(reduction.Changed());
     524           2 :   EXPECT_EQ(value, reduction.replacement());
     525             : }
     526             : 
     527       15374 : TEST_F(MachineOperatorReducerTest, TruncateFloat64ToWord32WithConstant) {
     528         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
     529             :     Reduction reduction = Reduce(graph()->NewNode(
     530         300 :         machine()->TruncateFloat64ToWord32(), Float64Constant(x)));
     531         100 :     ASSERT_TRUE(reduction.Changed());
     532         500 :     EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
     533             :   }
     534             : }
     535             : 
     536             : 
     537             : // -----------------------------------------------------------------------------
     538             : // TruncateInt64ToInt32
     539             : 
     540             : 
     541       15374 : TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithChangeInt32ToInt64) {
     542           1 :   Node* value = Parameter(0);
     543             :   Reduction reduction = Reduce(graph()->NewNode(
     544             :       machine()->TruncateInt64ToInt32(),
     545           3 :       graph()->NewNode(machine()->ChangeInt32ToInt64(), value)));
     546           1 :   ASSERT_TRUE(reduction.Changed());
     547           2 :   EXPECT_EQ(value, reduction.replacement());
     548             : }
     549             : 
     550             : 
     551       15374 : TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithConstant) {
     552         401 :   TRACED_FOREACH(int64_t, x, kInt64Values) {
     553             :     Reduction reduction = Reduce(
     554         300 :         graph()->NewNode(machine()->TruncateInt64ToInt32(), Int64Constant(x)));
     555         100 :     ASSERT_TRUE(reduction.Changed());
     556         500 :     EXPECT_THAT(reduction.replacement(),
     557             :                 IsInt32Constant(bit_cast<int32_t>(
     558           0 :                     static_cast<uint32_t>(bit_cast<uint64_t>(x)))));
     559             :   }
     560             : }
     561             : 
     562             : 
     563             : // -----------------------------------------------------------------------------
     564             : // RoundFloat64ToInt32
     565             : 
     566       15374 : TEST_F(MachineOperatorReducerTest,
     567             :        RoundFloat64ToInt32WithChangeInt32ToFloat64) {
     568           1 :   Node* value = Parameter(0);
     569             :   Reduction reduction = Reduce(graph()->NewNode(
     570             :       machine()->RoundFloat64ToInt32(),
     571           3 :       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
     572           1 :   ASSERT_TRUE(reduction.Changed());
     573           2 :   EXPECT_EQ(value, reduction.replacement());
     574             : }
     575             : 
     576       15374 : TEST_F(MachineOperatorReducerTest, RoundFloat64ToInt32WithConstant) {
     577         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
     578             :     Reduction reduction = Reduce(
     579         300 :         graph()->NewNode(machine()->RoundFloat64ToInt32(), Float64Constant(x)));
     580         100 :     ASSERT_TRUE(reduction.Changed());
     581         500 :     EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
     582             :   }
     583             : }
     584             : 
     585             : // -----------------------------------------------------------------------------
     586             : // Word32And
     587             : 
     588       15374 : TEST_F(MachineOperatorReducerTest, Word32AndWithWord32ShlWithConstant) {
     589           1 :   Node* const p0 = Parameter(0);
     590             : 
     591         125 :   TRACED_FORRANGE(int32_t, l, 1, 31) {
     592        2015 :     TRACED_FORRANGE(int32_t, k, 1, l) {
     593             :       // (x << L) & (-1 << K) => x << L
     594             :       Reduction const r1 = Reduce(graph()->NewNode(
     595             :           machine()->Word32And(),
     596             :           graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(l)),
     597        1984 :           Int32Constant(Shl(-1, k))));
     598         496 :       ASSERT_TRUE(r1.Changed());
     599        3472 :       EXPECT_THAT(r1.replacement(), IsWord32Shl(p0, IsInt32Constant(l)));
     600             : 
     601             :       // (-1 << K) & (x << L) => x << L
     602             :       Reduction const r2 = Reduce(graph()->NewNode(
     603             :           machine()->Word32And(), Int32Constant(Shl(-1, k)),
     604        1488 :           graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(l))));
     605         496 :       ASSERT_TRUE(r2.Changed());
     606        3472 :       EXPECT_THAT(r2.replacement(), IsWord32Shl(p0, IsInt32Constant(l)));
     607             :     }
     608             :   }
     609             : }
     610             : 
     611             : 
     612       15374 : TEST_F(MachineOperatorReducerTest, Word32AndWithWord32AndWithConstant) {
     613           1 :   Node* const p0 = Parameter(0);
     614             : 
     615         401 :   TRACED_FOREACH(int32_t, k, kInt32Values) {
     616       40100 :     TRACED_FOREACH(int32_t, l, kInt32Values) {
     617       10000 :       if (k == 0 || k == -1 || l == 0 || l == -1) continue;
     618             : 
     619             :       // (x & K) & L => x & (K & L)
     620             :       Reduction const r1 = Reduce(graph()->NewNode(
     621             :           machine()->Word32And(),
     622             :           graph()->NewNode(machine()->Word32And(), p0, Int32Constant(k)),
     623       39204 :           Int32Constant(l)));
     624        9801 :       ASSERT_TRUE(r1.Changed());
     625       67287 :       EXPECT_THAT(r1.replacement(),
     626             :                   (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
     627           0 :                           : IsInt32Constant(0));
     628             : 
     629             :       // (K & x) & L => x & (K & L)
     630             :       Reduction const r2 = Reduce(graph()->NewNode(
     631             :           machine()->Word32And(),
     632             :           graph()->NewNode(machine()->Word32And(), Int32Constant(k), p0),
     633       29403 :           Int32Constant(l)));
     634        9801 :       ASSERT_TRUE(r2.Changed());
     635       67287 :       EXPECT_THAT(r2.replacement(),
     636             :                   (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
     637           0 :                           : IsInt32Constant(0));
     638             :     }
     639             :   }
     640             : }
     641             : 
     642             : 
     643       15374 : TEST_F(MachineOperatorReducerTest, Word32AndWithInt32AddAndConstant) {
     644           1 :   Node* const p0 = Parameter(0);
     645           1 :   Node* const p1 = Parameter(1);
     646             : 
     647         125 :   TRACED_FORRANGE(int32_t, l, 1, 31) {
     648       12431 :     TRACED_FOREACH(int32_t, k, kInt32Values) {
     649        3100 :       if (Shl(k, l) == 0) continue;
     650             :       // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
     651             :       Reduction const r = Reduce(graph()->NewNode(
     652             :           machine()->Word32And(),
     653             :           graph()->NewNode(machine()->Int32Add(), p0, Int32Constant(Shl(k, l))),
     654       11692 :           Int32Constant(Shl(-1, l))));
     655        2923 :       ASSERT_TRUE(r.Changed());
     656       29230 :       EXPECT_THAT(r.replacement(),
     657             :                   IsInt32Add(IsWord32And(p0, IsInt32Constant(Shl(-1, l))),
     658           0 :                              IsInt32Constant(Shl(k, l))));
     659             :     }
     660             : 
     661          62 :     Node* s1 = graph()->NewNode(machine()->Word32Shl(), p1, Int32Constant(l));
     662             : 
     663             :     // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
     664             :     Reduction const r1 = Reduce(graph()->NewNode(
     665             :         machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), s1, p0),
     666          93 :         Int32Constant(Shl(-1, l))));
     667          31 :     ASSERT_TRUE(r1.Changed());
     668         279 :     EXPECT_THAT(r1.replacement(),
     669           0 :                 IsInt32Add(IsWord32And(p0, IsInt32Constant(Shl(-1, l))), s1));
     670             : 
     671             :     // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
     672             :     Reduction const r2 = Reduce(graph()->NewNode(
     673             :         machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), p0, s1),
     674          93 :         Int32Constant(Shl(-1, l))));
     675          31 :     ASSERT_TRUE(r2.Changed());
     676         279 :     EXPECT_THAT(r2.replacement(),
     677           0 :                 IsInt32Add(IsWord32And(p0, IsInt32Constant(Shl(-1, l))), s1));
     678             :   }
     679             : }
     680             : 
     681             : 
     682       15374 : TEST_F(MachineOperatorReducerTest, Word32AndWithInt32MulAndConstant) {
     683           1 :   Node* const p0 = Parameter(0);
     684             : 
     685         125 :   TRACED_FORRANGE(int32_t, l, 1, 31) {
     686       12431 :     TRACED_FOREACH(int32_t, k, kInt32Values) {
     687        3100 :       if (Shl(k, l) == 0) continue;
     688             : 
     689             :       // (x * (K << L)) & (-1 << L) => x * (K << L)
     690             :       Reduction const r1 = Reduce(graph()->NewNode(
     691             :           machine()->Word32And(),
     692             :           graph()->NewNode(machine()->Int32Mul(), p0, Int32Constant(Shl(k, l))),
     693       11692 :           Int32Constant(Shl(-1, l))));
     694        2923 :       ASSERT_TRUE(r1.Changed());
     695       20461 :       EXPECT_THAT(r1.replacement(), IsInt32Mul(p0, IsInt32Constant(Shl(k, l))));
     696             : 
     697             :       // ((K << L) * x) & (-1 << L) => x * (K << L)
     698             :       Reduction const r2 = Reduce(graph()->NewNode(
     699             :           machine()->Word32And(),
     700             :           graph()->NewNode(machine()->Int32Mul(), Int32Constant(Shl(k, l)), p0),
     701        8769 :           Int32Constant(Shl(-1, l))));
     702        2923 :       ASSERT_TRUE(r2.Changed());
     703       20461 :       EXPECT_THAT(r2.replacement(), IsInt32Mul(p0, IsInt32Constant(Shl(k, l))));
     704             :     }
     705             :   }
     706             : }
     707             : 
     708             : 
     709       15374 : TEST_F(MachineOperatorReducerTest,
     710             :        Word32AndWithInt32AddAndInt32MulAndConstant) {
     711           1 :   Node* const p0 = Parameter(0);
     712           1 :   Node* const p1 = Parameter(1);
     713             : 
     714         125 :   TRACED_FORRANGE(int32_t, l, 1, 31) {
     715       12431 :     TRACED_FOREACH(int32_t, k, kInt32Values) {
     716        3100 :       if (Shl(k, l) == 0) continue;
     717             :       // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
     718             :       Reduction const r1 = Reduce(graph()->NewNode(
     719             :           machine()->Word32And(),
     720             :           graph()->NewNode(machine()->Int32Add(),
     721             :                            graph()->NewNode(machine()->Int32Mul(), p1,
     722             :                                             Int32Constant(Shl(k, l))),
     723             :                            p0),
     724       14615 :           Int32Constant(Shl(-1, l))));
     725        2923 :       ASSERT_TRUE(r1.Changed());
     726       35076 :       EXPECT_THAT(r1.replacement(),
     727             :                   IsInt32Add(IsWord32And(p0, IsInt32Constant(Shl(-1, l))),
     728           0 :                              IsInt32Mul(p1, IsInt32Constant(Shl(k, l)))));
     729             : 
     730             :       // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
     731             :       Reduction const r2 = Reduce(graph()->NewNode(
     732             :           machine()->Word32And(),
     733             :           graph()->NewNode(machine()->Int32Add(), p0,
     734             :                            graph()->NewNode(machine()->Int32Mul(), p1,
     735             :                                             Int32Constant(Shl(k, l)))),
     736       11692 :           Int32Constant(Shl(-1, l))));
     737        2923 :       ASSERT_TRUE(r2.Changed());
     738       35076 :       EXPECT_THAT(r2.replacement(),
     739             :                   IsInt32Add(IsWord32And(p0, IsInt32Constant(Shl(-1, l))),
     740           0 :                              IsInt32Mul(p1, IsInt32Constant(Shl(k, l)))));
     741             :     }
     742             :   }
     743             : }
     744             : 
     745             : 
     746       15374 : TEST_F(MachineOperatorReducerTest, Word32AndWithComparisonAndConstantOne) {
     747           1 :   Node* const p0 = Parameter(0);
     748           1 :   Node* const p1 = Parameter(1);
     749          65 :   TRACED_FOREACH(ComparisonBinaryOperator, cbop, kComparisonBinaryOperators) {
     750          32 :     Node* cmp = graph()->NewNode((machine()->*cbop.constructor)(), p0, p1);
     751             : 
     752             :     // cmp & 1 => cmp
     753             :     Reduction const r1 =
     754          32 :         Reduce(graph()->NewNode(machine()->Word32And(), cmp, Int32Constant(1)));
     755          16 :     ASSERT_TRUE(r1.Changed());
     756          32 :     EXPECT_EQ(cmp, r1.replacement());
     757             : 
     758             :     // 1 & cmp => cmp
     759             :     Reduction const r2 =
     760          32 :         Reduce(graph()->NewNode(machine()->Word32And(), Int32Constant(1), cmp));
     761          16 :     ASSERT_TRUE(r2.Changed());
     762          32 :     EXPECT_EQ(cmp, r2.replacement());
     763             :   }
     764             : }
     765             : 
     766             : 
     767             : // -----------------------------------------------------------------------------
     768             : // Word32Xor
     769             : 
     770             : 
     771       15374 : TEST_F(MachineOperatorReducerTest, Word32XorWithWord32XorAndMinusOne) {
     772           1 :   Node* const p0 = Parameter(0);
     773             : 
     774             :   // (x ^ -1) ^ -1 => x
     775             :   Reduction r1 = Reduce(graph()->NewNode(
     776             :       machine()->Word32Xor(),
     777             :       graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1)),
     778           4 :       Int32Constant(-1)));
     779           1 :   ASSERT_TRUE(r1.Changed());
     780           2 :   EXPECT_EQ(r1.replacement(), p0);
     781             : 
     782             :   // -1 ^ (x ^ -1) => x
     783             :   Reduction r2 = Reduce(graph()->NewNode(
     784             :       machine()->Word32Xor(), Int32Constant(-1),
     785           3 :       graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1))));
     786           1 :   ASSERT_TRUE(r2.Changed());
     787           2 :   EXPECT_EQ(r2.replacement(), p0);
     788             : 
     789             :   // (-1 ^ x) ^ -1 => x
     790             :   Reduction r3 = Reduce(graph()->NewNode(
     791             :       machine()->Word32Xor(),
     792             :       graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0),
     793           3 :       Int32Constant(-1)));
     794           1 :   ASSERT_TRUE(r3.Changed());
     795           2 :   EXPECT_EQ(r3.replacement(), p0);
     796             : 
     797             :   // -1 ^ (-1 ^ x) => x
     798             :   Reduction r4 = Reduce(graph()->NewNode(
     799             :       machine()->Word32Xor(), Int32Constant(-1),
     800           3 :       graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0)));
     801           1 :   ASSERT_TRUE(r4.Changed());
     802           2 :   EXPECT_EQ(r4.replacement(), p0);
     803             : }
     804             : 
     805             : 
     806             : // -----------------------------------------------------------------------------
     807             : // Word32Ror
     808             : 
     809             : 
     810       15374 : TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
     811           1 :   Node* value = Parameter(0);
     812           1 :   Node* shift = Parameter(1);
     813           2 :   Node* sub = graph()->NewNode(machine()->Int32Sub(), Int32Constant(32), shift);
     814             : 
     815             :   // Testing rotate left.
     816           1 :   Node* shl_l = graph()->NewNode(machine()->Word32Shl(), value, shift);
     817           1 :   Node* shr_l = graph()->NewNode(machine()->Word32Shr(), value, sub);
     818             : 
     819             :   // (x << y) | (x >>> (32 - y)) => x ror (32 - y)
     820           2 :   Node* node1 = graph()->NewNode(machine()->Word32Or(), shl_l, shr_l);
     821           1 :   Reduction reduction1 = Reduce(node1);
     822           1 :   EXPECT_TRUE(reduction1.Changed());
     823           2 :   EXPECT_EQ(reduction1.replacement(), node1);
     824           6 :   EXPECT_THAT(reduction1.replacement(), IsWord32Ror(value, sub));
     825             : 
     826             :   // (x >>> (32 - y)) | (x << y) => x ror (32 - y)
     827           2 :   Node* node2 = graph()->NewNode(machine()->Word32Or(), shr_l, shl_l);
     828           1 :   Reduction reduction2 = Reduce(node2);
     829           1 :   EXPECT_TRUE(reduction2.Changed());
     830           2 :   EXPECT_EQ(reduction2.replacement(), node2);
     831           6 :   EXPECT_THAT(reduction2.replacement(), IsWord32Ror(value, sub));
     832             : 
     833             :   // (x << y) ^ (x >>> (32 - y)) => x ror (32 - y)
     834           2 :   Node* node3 = graph()->NewNode(machine()->Word32Xor(), shl_l, shr_l);
     835           1 :   Reduction reduction3 = Reduce(node3);
     836           1 :   EXPECT_TRUE(reduction3.Changed());
     837           2 :   EXPECT_EQ(reduction3.replacement(), node3);
     838           6 :   EXPECT_THAT(reduction3.replacement(), IsWord32Ror(value, sub));
     839             : 
     840             :   // (x >>> (32 - y)) ^ (x << y) => x ror (32 - y)
     841           2 :   Node* node4 = graph()->NewNode(machine()->Word32Xor(), shr_l, shl_l);
     842           1 :   Reduction reduction4 = Reduce(node4);
     843           1 :   EXPECT_TRUE(reduction4.Changed());
     844           2 :   EXPECT_EQ(reduction4.replacement(), node4);
     845           6 :   EXPECT_THAT(reduction4.replacement(), IsWord32Ror(value, sub));
     846             : 
     847             :   // Testing rotate right.
     848           1 :   Node* shl_r = graph()->NewNode(machine()->Word32Shl(), value, sub);
     849           1 :   Node* shr_r = graph()->NewNode(machine()->Word32Shr(), value, shift);
     850             : 
     851             :   // (x << (32 - y)) | (x >>> y) => x ror y
     852           2 :   Node* node5 = graph()->NewNode(machine()->Word32Or(), shl_r, shr_r);
     853           1 :   Reduction reduction5 = Reduce(node5);
     854           1 :   EXPECT_TRUE(reduction5.Changed());
     855           2 :   EXPECT_EQ(reduction5.replacement(), node5);
     856           6 :   EXPECT_THAT(reduction5.replacement(), IsWord32Ror(value, shift));
     857             : 
     858             :   // (x >>> y) | (x << (32 - y)) => x ror y
     859           2 :   Node* node6 = graph()->NewNode(machine()->Word32Or(), shr_r, shl_r);
     860           1 :   Reduction reduction6 = Reduce(node6);
     861           1 :   EXPECT_TRUE(reduction6.Changed());
     862           2 :   EXPECT_EQ(reduction6.replacement(), node6);
     863           6 :   EXPECT_THAT(reduction6.replacement(), IsWord32Ror(value, shift));
     864             : 
     865             :   // (x << (32 - y)) ^ (x >>> y) => x ror y
     866           2 :   Node* node7 = graph()->NewNode(machine()->Word32Xor(), shl_r, shr_r);
     867           1 :   Reduction reduction7 = Reduce(node7);
     868           1 :   EXPECT_TRUE(reduction7.Changed());
     869           2 :   EXPECT_EQ(reduction7.replacement(), node7);
     870           6 :   EXPECT_THAT(reduction7.replacement(), IsWord32Ror(value, shift));
     871             : 
     872             :   // (x >>> y) ^ (x << (32 - y)) => x ror y
     873           2 :   Node* node8 = graph()->NewNode(machine()->Word32Xor(), shr_r, shl_r);
     874           1 :   Reduction reduction8 = Reduce(node8);
     875           1 :   EXPECT_TRUE(reduction8.Changed());
     876           2 :   EXPECT_EQ(reduction8.replacement(), node8);
     877           6 :   EXPECT_THAT(reduction8.replacement(), IsWord32Ror(value, shift));
     878           1 : }
     879             : 
     880       15374 : TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
     881           1 :   Node* value = Parameter(0);
     882         129 :   TRACED_FORRANGE(int32_t, k, 0, 31) {
     883             :     Node* shl =
     884          64 :         graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(k));
     885             :     Node* shr =
     886          32 :         graph()->NewNode(machine()->Word32Shr(), value, Int32Constant(32 - k));
     887             : 
     888             :     // (x << K) | (x >>> ((32 - K) - y)) => x ror (32 - K)
     889          64 :     Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
     890          32 :     Reduction reduction1 = Reduce(node1);
     891          32 :     EXPECT_TRUE(reduction1.Changed());
     892          64 :     EXPECT_EQ(reduction1.replacement(), node1);
     893         224 :     EXPECT_THAT(reduction1.replacement(),
     894           0 :                 IsWord32Ror(value, IsInt32Constant(32 - k)));
     895             : 
     896             :     // (x >>> (32 - K)) | (x << K) => x ror (32 - K)
     897          64 :     Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
     898          32 :     Reduction reduction2 = Reduce(node2);
     899          32 :     EXPECT_TRUE(reduction2.Changed());
     900          64 :     EXPECT_EQ(reduction2.replacement(), node2);
     901         224 :     EXPECT_THAT(reduction2.replacement(),
     902           0 :                 IsWord32Ror(value, IsInt32Constant(32 - k)));
     903             :   }
     904           1 : }
     905             : 
     906             : 
     907       15374 : TEST_F(MachineOperatorReducerTest, Word32RorWithZeroShift) {
     908           1 :   Node* value = Parameter(0);
     909             :   Node* node =
     910           2 :       graph()->NewNode(machine()->Word32Ror(), value, Int32Constant(0));
     911           1 :   Reduction reduction = Reduce(node);
     912           1 :   EXPECT_TRUE(reduction.Changed());
     913           2 :   EXPECT_EQ(reduction.replacement(), value);
     914           1 : }
     915             : 
     916             : 
     917       15374 : TEST_F(MachineOperatorReducerTest, Word32RorWithConstants) {
     918         193 :   TRACED_FOREACH(int32_t, x, kUint32Values) {
     919        6192 :     TRACED_FORRANGE(int32_t, y, 0, 31) {
     920        3072 :       Node* node = graph()->NewNode(machine()->Word32Ror(), Int32Constant(x),
     921             :                                     Int32Constant(y));
     922        1536 :       Reduction reduction = Reduce(node);
     923        1536 :       EXPECT_TRUE(reduction.Changed());
     924        9216 :       EXPECT_THAT(reduction.replacement(),
     925           0 :                   IsInt32Constant(base::bits::RotateRight32(x, y)));
     926             :     }
     927             :   }
     928           1 : }
     929             : 
     930             : 
     931             : // -----------------------------------------------------------------------------
     932             : // Word32Sar
     933             : 
     934             : 
     935       15374 : TEST_F(MachineOperatorReducerTest, Word32SarWithWord32ShlAndComparison) {
     936           1 :   Node* const p0 = Parameter(0);
     937           1 :   Node* const p1 = Parameter(1);
     938             : 
     939          65 :   TRACED_FOREACH(ComparisonBinaryOperator, cbop, kComparisonBinaryOperators) {
     940          16 :     Node* cmp = graph()->NewNode((machine()->*cbop.constructor)(), p0, p1);
     941             : 
     942             :     // cmp << 31 >> 31 => 0 - cmp
     943             :     Reduction const r = Reduce(graph()->NewNode(
     944             :         machine()->Word32Sar(),
     945             :         graph()->NewNode(machine()->Word32Shl(), cmp, Int32Constant(31)),
     946          48 :         Int32Constant(31)));
     947          16 :     ASSERT_TRUE(r.Changed());
     948         112 :     EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0), cmp));
     949             :   }
     950             : }
     951             : 
     952             : 
     953       15374 : TEST_F(MachineOperatorReducerTest, Word32SarWithWord32ShlAndLoad) {
     954           1 :   Node* const p0 = Parameter(0);
     955           1 :   Node* const p1 = Parameter(1);
     956             :   {
     957           1 :     Node* const l = graph()->NewNode(machine()->Load(MachineType::Int8()), p0,
     958           1 :                                      p1, graph()->start(), graph()->start());
     959             :     Reduction const r = Reduce(graph()->NewNode(
     960             :         machine()->Word32Sar(),
     961             :         graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(24)),
     962           3 :         Int32Constant(24)));
     963           1 :     ASSERT_TRUE(r.Changed());
     964           2 :     EXPECT_EQ(l, r.replacement());
     965             :   }
     966             :   {
     967           1 :     Node* const l = graph()->NewNode(machine()->Load(MachineType::Int16()), p0,
     968           1 :                                      p1, graph()->start(), graph()->start());
     969             :     Reduction const r = Reduce(graph()->NewNode(
     970             :         machine()->Word32Sar(),
     971             :         graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(16)),
     972           3 :         Int32Constant(16)));
     973           1 :     ASSERT_TRUE(r.Changed());
     974           2 :     EXPECT_EQ(l, r.replacement());
     975             :   }
     976             : }
     977             : 
     978             : 
     979             : // -----------------------------------------------------------------------------
     980             : // Word32Shr
     981             : 
     982       15374 : TEST_F(MachineOperatorReducerTest, Word32ShrWithWord32And) {
     983           1 :   Node* const p0 = Parameter(0);
     984         125 :   TRACED_FORRANGE(int32_t, shift, 1, 31) {
     985             :     uint32_t mask =
     986             :         base::SubWithWraparound(base::ShlWithWraparound(1, shift), 1);
     987          93 :     Node* node = graph()->NewNode(
     988             :         machine()->Word32Shr(),
     989             :         graph()->NewNode(machine()->Word32And(), p0, Int32Constant(mask)),
     990             :         Int32Constant(shift));
     991          31 :     Reduction r = Reduce(node);
     992          31 :     ASSERT_TRUE(r.Changed());
     993         155 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
     994             :   }
     995             : }
     996             : 
     997             : // -----------------------------------------------------------------------------
     998             : // Word32Shl
     999             : 
    1000       15374 : TEST_F(MachineOperatorReducerTest, Word32ShlWithZeroShift) {
    1001           1 :   Node* p0 = Parameter(0);
    1002           2 :   Node* node = graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(0));
    1003           1 :   Reduction r = Reduce(node);
    1004           1 :   ASSERT_TRUE(r.Changed());
    1005           2 :   EXPECT_EQ(p0, r.replacement());
    1006             : }
    1007             : 
    1008             : 
    1009       15374 : TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Sar) {
    1010           1 :   Node* p0 = Parameter(0);
    1011         125 :   TRACED_FORRANGE(int32_t, x, 1, 31) {
    1012          93 :     Node* node = graph()->NewNode(
    1013             :         machine()->Word32Shl(),
    1014             :         graph()->NewNode(machine()->Word32Sar(), p0, Int32Constant(x)),
    1015             :         Int32Constant(x));
    1016          31 :     Reduction r = Reduce(node);
    1017          31 :     ASSERT_TRUE(r.Changed());
    1018          31 :     int32_t m = static_cast<int32_t>(~((1U << x) - 1U));
    1019         217 :     EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
    1020             :   }
    1021             : }
    1022             : 
    1023             : 
    1024       15374 : TEST_F(MachineOperatorReducerTest,
    1025             :        Word32ShlWithWord32SarAndInt32AddAndConstant) {
    1026           1 :   Node* const p0 = Parameter(0);
    1027         401 :   TRACED_FOREACH(int32_t, k, kInt32Values) {
    1028       12500 :     TRACED_FORRANGE(int32_t, l, 1, 31) {
    1029        3100 :       if (Shl(k, l) == 0) continue;
    1030             :       // (x + (K << L)) >> L << L => (x & (-1 << L)) + (K << L)
    1031             :       Reduction const r = Reduce(graph()->NewNode(
    1032             :           machine()->Word32Shl(),
    1033             :           graph()->NewNode(machine()->Word32Sar(),
    1034             :                            graph()->NewNode(machine()->Int32Add(), p0,
    1035             :                                             Int32Constant(Shl(k, l))),
    1036             :                            Int32Constant(l)),
    1037       14615 :           Int32Constant(l)));
    1038        2923 :       ASSERT_TRUE(r.Changed());
    1039       32153 :       EXPECT_THAT(r.replacement(),
    1040             :                   IsInt32Add(IsWord32And(p0, IsInt32Constant(Shl(-1, l))),
    1041           0 :                              IsInt32Constant(Shl(k, l))));
    1042             :     }
    1043             :   }
    1044             : }
    1045             : 
    1046             : 
    1047       15374 : TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Shr) {
    1048           1 :   Node* p0 = Parameter(0);
    1049         125 :   TRACED_FORRANGE(int32_t, x, 1, 31) {
    1050          93 :     Node* node = graph()->NewNode(
    1051             :         machine()->Word32Shl(),
    1052             :         graph()->NewNode(machine()->Word32Shr(), p0, Int32Constant(x)),
    1053             :         Int32Constant(x));
    1054          31 :     Reduction r = Reduce(node);
    1055          31 :     ASSERT_TRUE(r.Changed());
    1056          31 :     int32_t m = static_cast<int32_t>(~((1U << x) - 1U));
    1057         217 :     EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
    1058             :   }
    1059             : }
    1060             : 
    1061             : 
    1062             : // -----------------------------------------------------------------------------
    1063             : // Int32Sub
    1064             : 
    1065             : 
    1066       15374 : TEST_F(MachineOperatorReducerTest, Int32SubWithConstant) {
    1067           1 :   Node* const p0 = Parameter(0);
    1068         401 :   TRACED_FOREACH(int32_t, k, kInt32Values) {
    1069             :     Reduction const r =
    1070         300 :         Reduce(graph()->NewNode(machine()->Int32Sub(), p0, Int32Constant(k)));
    1071         100 :     ASSERT_TRUE(r.Changed());
    1072         100 :     if (k == 0) {
    1073           2 :       EXPECT_EQ(p0, r.replacement());
    1074             :     } else {
    1075         792 :       EXPECT_THAT(
    1076             :           r.replacement(),
    1077           0 :           IsInt32Add(p0, IsInt32Constant(base::NegateWithWraparound(k))));
    1078             :     }
    1079             :   }
    1080             : }
    1081             : 
    1082             : 
    1083             : // -----------------------------------------------------------------------------
    1084             : // Int32Div
    1085             : 
    1086             : 
    1087       15374 : TEST_F(MachineOperatorReducerTest, Int32DivWithConstant) {
    1088           1 :   Node* const p0 = Parameter(0);
    1089             :   {
    1090             :     Reduction const r = Reduce(graph()->NewNode(
    1091           3 :         machine()->Int32Div(), p0, Int32Constant(0), graph()->start()));
    1092           1 :     ASSERT_TRUE(r.Changed());
    1093           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1094             :   }
    1095             :   {
    1096             :     Reduction const r = Reduce(graph()->NewNode(
    1097           2 :         machine()->Int32Div(), p0, Int32Constant(1), graph()->start()));
    1098           1 :     ASSERT_TRUE(r.Changed());
    1099           2 :     EXPECT_EQ(r.replacement(), p0);
    1100             :   }
    1101             :   {
    1102             :     Reduction const r = Reduce(graph()->NewNode(
    1103           2 :         machine()->Int32Div(), p0, Int32Constant(-1), graph()->start()));
    1104           1 :     ASSERT_TRUE(r.Changed());
    1105           7 :     EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0), p0));
    1106             :   }
    1107             :   {
    1108             :     Reduction const r = Reduce(graph()->NewNode(
    1109           2 :         machine()->Int32Div(), p0, Int32Constant(2), graph()->start()));
    1110           1 :     ASSERT_TRUE(r.Changed());
    1111          12 :     EXPECT_THAT(
    1112             :         r.replacement(),
    1113             :         IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
    1114           0 :                     IsInt32Constant(1)));
    1115             :   }
    1116             :   {
    1117             :     Reduction const r = Reduce(graph()->NewNode(
    1118           2 :         machine()->Int32Div(), p0, Int32Constant(-2), graph()->start()));
    1119           1 :     ASSERT_TRUE(r.Changed());
    1120          15 :     EXPECT_THAT(
    1121             :         r.replacement(),
    1122             :         IsInt32Sub(
    1123             :             IsInt32Constant(0),
    1124             :             IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
    1125           0 :                         IsInt32Constant(1))));
    1126             :   }
    1127         117 :   TRACED_FORRANGE(int32_t, shift, 2, 30) {
    1128             :     Reduction const r =
    1129             :         Reduce(graph()->NewNode(machine()->Int32Div(), p0,
    1130          58 :                                 Int32Constant(1 << shift), graph()->start()));
    1131          29 :     ASSERT_TRUE(r.Changed());
    1132         435 :     EXPECT_THAT(
    1133             :         r.replacement(),
    1134             :         IsWord32Sar(IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
    1135             :                                            IsInt32Constant(32 - shift)),
    1136             :                                p0),
    1137           0 :                     IsInt32Constant(shift)));
    1138             :   }
    1139         121 :   TRACED_FORRANGE(int32_t, shift, 2, 31) {
    1140             :     Reduction const r = Reduce(graph()->NewNode(machine()->Int32Div(), p0,
    1141             :                                                 Int32Constant(Shl(-1, shift)),
    1142          60 :                                                 graph()->start()));
    1143          30 :     ASSERT_TRUE(r.Changed());
    1144         540 :     EXPECT_THAT(
    1145             :         r.replacement(),
    1146             :         IsInt32Sub(
    1147             :             IsInt32Constant(0),
    1148             :             IsWord32Sar(
    1149             :                 IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
    1150             :                                        IsInt32Constant(32 - shift)),
    1151             :                            p0),
    1152           0 :                 IsInt32Constant(shift))));
    1153             :   }
    1154         401 :   TRACED_FOREACH(int32_t, divisor, kInt32Values) {
    1155         100 :     if (divisor < 0) {
    1156          97 :       if (divisor == kMinInt || base::bits::IsPowerOfTwo(-divisor)) continue;
    1157             :       Reduction const r = Reduce(graph()->NewNode(
    1158          96 :           machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
    1159          48 :       ASSERT_TRUE(r.Changed());
    1160         384 :       EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0),
    1161           0 :                                               IsTruncatingDiv(p0, -divisor)));
    1162          51 :     } else if (divisor > 0) {
    1163          50 :       if (base::bits::IsPowerOfTwo(divisor)) continue;
    1164             :       Reduction const r = Reduce(graph()->NewNode(
    1165          98 :           machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
    1166          49 :       ASSERT_TRUE(r.Changed());
    1167         245 :       EXPECT_THAT(r.replacement(), IsTruncatingDiv(p0, divisor));
    1168             :     }
    1169             :   }
    1170             : }
    1171             : 
    1172             : 
    1173       15374 : TEST_F(MachineOperatorReducerTest, Int32DivWithParameters) {
    1174           1 :   Node* const p0 = Parameter(0);
    1175             :   Reduction const r =
    1176           2 :       Reduce(graph()->NewNode(machine()->Int32Div(), p0, p0, graph()->start()));
    1177           1 :   ASSERT_TRUE(r.Changed());
    1178          10 :   EXPECT_THAT(
    1179             :       r.replacement(),
    1180           0 :       IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
    1181             : }
    1182             : 
    1183             : 
    1184             : // -----------------------------------------------------------------------------
    1185             : // Uint32Div
    1186             : 
    1187             : 
    1188       15374 : TEST_F(MachineOperatorReducerTest, Uint32DivWithConstant) {
    1189           1 :   Node* const p0 = Parameter(0);
    1190             :   {
    1191             :     Reduction const r = Reduce(graph()->NewNode(
    1192           3 :         machine()->Uint32Div(), Int32Constant(0), p0, graph()->start()));
    1193           1 :     ASSERT_TRUE(r.Changed());
    1194           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1195             :   }
    1196             :   {
    1197             :     Reduction const r = Reduce(graph()->NewNode(
    1198           2 :         machine()->Uint32Div(), p0, Int32Constant(0), graph()->start()));
    1199           1 :     ASSERT_TRUE(r.Changed());
    1200           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1201             :   }
    1202             :   {
    1203             :     Reduction const r = Reduce(graph()->NewNode(
    1204           2 :         machine()->Uint32Div(), p0, Int32Constant(1), graph()->start()));
    1205           1 :     ASSERT_TRUE(r.Changed());
    1206           2 :     EXPECT_EQ(r.replacement(), p0);
    1207             :   }
    1208         193 :   TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
    1209        9264 :     TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
    1210             :       Reduction const r = Reduce(
    1211             :           graph()->NewNode(machine()->Uint32Div(), Uint32Constant(dividend),
    1212        4608 :                            Uint32Constant(divisor), graph()->start()));
    1213        2304 :       ASSERT_TRUE(r.Changed());
    1214       13824 :       EXPECT_THAT(r.replacement(),
    1215             :                   IsInt32Constant(bit_cast<int32_t>(
    1216           0 :                       base::bits::UnsignedDiv32(dividend, divisor))));
    1217             :     }
    1218             :   }
    1219         125 :   TRACED_FORRANGE(uint32_t, shift, 1, 31) {
    1220             :     Reduction const r =
    1221             :         Reduce(graph()->NewNode(machine()->Uint32Div(), p0,
    1222          93 :                                 Uint32Constant(1u << shift), graph()->start()));
    1223          31 :     ASSERT_TRUE(r.Changed());
    1224         217 :     EXPECT_THAT(r.replacement(),
    1225           0 :                 IsWord32Shr(p0, IsInt32Constant(static_cast<int32_t>(shift))));
    1226             :   }
    1227             : }
    1228             : 
    1229             : 
    1230       15374 : TEST_F(MachineOperatorReducerTest, Uint32DivWithParameters) {
    1231           1 :   Node* const p0 = Parameter(0);
    1232             :   Reduction const r = Reduce(
    1233           2 :       graph()->NewNode(machine()->Uint32Div(), p0, p0, graph()->start()));
    1234           1 :   ASSERT_TRUE(r.Changed());
    1235          10 :   EXPECT_THAT(
    1236             :       r.replacement(),
    1237           0 :       IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
    1238             : }
    1239             : 
    1240             : 
    1241             : // -----------------------------------------------------------------------------
    1242             : // Int32Mod
    1243             : 
    1244             : 
    1245       15374 : TEST_F(MachineOperatorReducerTest, Int32ModWithConstant) {
    1246           1 :   Node* const p0 = Parameter(0);
    1247             :   {
    1248             :     Reduction const r = Reduce(graph()->NewNode(
    1249           3 :         machine()->Int32Mod(), Int32Constant(0), p0, graph()->start()));
    1250           1 :     ASSERT_TRUE(r.Changed());
    1251           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1252             :   }
    1253             :   {
    1254             :     Reduction const r = Reduce(graph()->NewNode(
    1255           2 :         machine()->Int32Mod(), p0, Int32Constant(0), graph()->start()));
    1256           1 :     ASSERT_TRUE(r.Changed());
    1257           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1258             :   }
    1259             :   {
    1260             :     Reduction const r = Reduce(graph()->NewNode(
    1261           2 :         machine()->Int32Mod(), p0, Int32Constant(1), graph()->start()));
    1262           1 :     ASSERT_TRUE(r.Changed());
    1263           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1264             :   }
    1265             :   {
    1266             :     Reduction const r = Reduce(graph()->NewNode(
    1267           2 :         machine()->Int32Mod(), p0, Int32Constant(-1), graph()->start()));
    1268           1 :     ASSERT_TRUE(r.Changed());
    1269           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1270             :   }
    1271         401 :   TRACED_FOREACH(int32_t, dividend, kInt32Values) {
    1272       40100 :     TRACED_FOREACH(int32_t, divisor, kInt32Values) {
    1273             :       Reduction const r = Reduce(
    1274             :           graph()->NewNode(machine()->Int32Mod(), Int32Constant(dividend),
    1275       20000 :                            Int32Constant(divisor), graph()->start()));
    1276       10000 :       ASSERT_TRUE(r.Changed());
    1277       50000 :       EXPECT_THAT(r.replacement(),
    1278           0 :                   IsInt32Constant(base::bits::SignedMod32(dividend, divisor)));
    1279             :     }
    1280             :   }
    1281         121 :   TRACED_FORRANGE(int32_t, shift, 1, 30) {
    1282             :     Reduction const r =
    1283             :         Reduce(graph()->NewNode(machine()->Int32Mod(), p0,
    1284          60 :                                 Int32Constant(1 << shift), graph()->start()));
    1285          30 :     int32_t const mask = (1 << shift) - 1;
    1286          30 :     ASSERT_TRUE(r.Changed());
    1287        1020 :     EXPECT_THAT(
    1288             :         r.replacement(),
    1289             :         IsPhi(
    1290             :             MachineRepresentation::kWord32,
    1291             :             IsInt32Sub(IsInt32Constant(0),
    1292             :                        IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
    1293             :                                    IsInt32Constant(mask))),
    1294             :             IsWord32And(p0, IsInt32Constant(mask)),
    1295             :             IsMerge(IsIfTrue(IsBranch(IsInt32LessThan(p0, IsInt32Constant(0)),
    1296             :                                       graph()->start())),
    1297             :                     IsIfFalse(IsBranch(IsInt32LessThan(p0, IsInt32Constant(0)),
    1298           0 :                                        graph()->start())))));
    1299             :   }
    1300         125 :   TRACED_FORRANGE(int32_t, shift, 1, 31) {
    1301             :     Reduction const r = Reduce(graph()->NewNode(machine()->Int32Mod(), p0,
    1302             :                                                 Int32Constant(Shl(-1, shift)),
    1303          62 :                                                 graph()->start()));
    1304          31 :     int32_t const mask = static_cast<int32_t>((1U << shift) - 1U);
    1305          31 :     ASSERT_TRUE(r.Changed());
    1306        1054 :     EXPECT_THAT(
    1307             :         r.replacement(),
    1308             :         IsPhi(
    1309             :             MachineRepresentation::kWord32,
    1310             :             IsInt32Sub(IsInt32Constant(0),
    1311             :                        IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
    1312             :                                    IsInt32Constant(mask))),
    1313             :             IsWord32And(p0, IsInt32Constant(mask)),
    1314             :             IsMerge(IsIfTrue(IsBranch(IsInt32LessThan(p0, IsInt32Constant(0)),
    1315             :                                       graph()->start())),
    1316             :                     IsIfFalse(IsBranch(IsInt32LessThan(p0, IsInt32Constant(0)),
    1317           0 :                                        graph()->start())))));
    1318             :   }
    1319         401 :   TRACED_FOREACH(int32_t, divisor, kInt32Values) {
    1320         199 :     if (divisor == 0 || base::bits::IsPowerOfTwo(Abs(divisor))) continue;
    1321             :     Reduction const r = Reduce(graph()->NewNode(
    1322         194 :         machine()->Int32Mod(), p0, Int32Constant(divisor), graph()->start()));
    1323          97 :     ASSERT_TRUE(r.Changed());
    1324        1067 :     EXPECT_THAT(r.replacement(),
    1325             :                 IsInt32Sub(p0, IsInt32Mul(IsTruncatingDiv(p0, Abs(divisor)),
    1326           0 :                                           IsInt32Constant(Abs(divisor)))));
    1327             :   }
    1328             : }
    1329             : 
    1330             : 
    1331       15374 : TEST_F(MachineOperatorReducerTest, Int32ModWithParameters) {
    1332           1 :   Node* const p0 = Parameter(0);
    1333             :   Reduction const r =
    1334           2 :       Reduce(graph()->NewNode(machine()->Int32Mod(), p0, p0, graph()->start()));
    1335           1 :   ASSERT_TRUE(r.Changed());
    1336           5 :   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1337             : }
    1338             : 
    1339             : 
    1340             : // -----------------------------------------------------------------------------
    1341             : // Uint32Mod
    1342             : 
    1343             : 
    1344       15374 : TEST_F(MachineOperatorReducerTest, Uint32ModWithConstant) {
    1345           1 :   Node* const p0 = Parameter(0);
    1346             :   {
    1347             :     Reduction const r = Reduce(graph()->NewNode(
    1348           3 :         machine()->Uint32Mod(), p0, Int32Constant(0), graph()->start()));
    1349           1 :     ASSERT_TRUE(r.Changed());
    1350           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1351             :   }
    1352             :   {
    1353             :     Reduction const r = Reduce(graph()->NewNode(
    1354           2 :         machine()->Uint32Mod(), Int32Constant(0), p0, graph()->start()));
    1355           1 :     ASSERT_TRUE(r.Changed());
    1356           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1357             :   }
    1358             :   {
    1359             :     Reduction const r = Reduce(graph()->NewNode(
    1360           2 :         machine()->Uint32Mod(), p0, Int32Constant(1), graph()->start()));
    1361           1 :     ASSERT_TRUE(r.Changed());
    1362           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1363             :   }
    1364         193 :   TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
    1365        9264 :     TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
    1366             :       Reduction const r = Reduce(
    1367             :           graph()->NewNode(machine()->Uint32Mod(), Uint32Constant(dividend),
    1368        4608 :                            Uint32Constant(divisor), graph()->start()));
    1369        2304 :       ASSERT_TRUE(r.Changed());
    1370       13824 :       EXPECT_THAT(r.replacement(),
    1371             :                   IsInt32Constant(bit_cast<int32_t>(
    1372           0 :                       base::bits::UnsignedMod32(dividend, divisor))));
    1373             :     }
    1374             :   }
    1375         125 :   TRACED_FORRANGE(uint32_t, shift, 1, 31) {
    1376             :     Reduction const r =
    1377             :         Reduce(graph()->NewNode(machine()->Uint32Mod(), p0,
    1378          93 :                                 Uint32Constant(1u << shift), graph()->start()));
    1379          31 :     ASSERT_TRUE(r.Changed());
    1380         217 :     EXPECT_THAT(r.replacement(),
    1381             :                 IsWord32And(p0, IsInt32Constant(
    1382           0 :                                     static_cast<int32_t>((1u << shift) - 1u))));
    1383             :   }
    1384             : }
    1385             : 
    1386             : 
    1387       15374 : TEST_F(MachineOperatorReducerTest, Uint32ModWithParameters) {
    1388           1 :   Node* const p0 = Parameter(0);
    1389             :   Reduction const r = Reduce(
    1390           2 :       graph()->NewNode(machine()->Uint32Mod(), p0, p0, graph()->start()));
    1391           1 :   ASSERT_TRUE(r.Changed());
    1392           5 :   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1393             : }
    1394             : 
    1395             : 
    1396             : // -----------------------------------------------------------------------------
    1397             : // Int32Add
    1398             : 
    1399             : 
    1400       15374 : TEST_F(MachineOperatorReducerTest, Int32AddWithInt32SubWithConstantZero) {
    1401           1 :   Node* const p0 = Parameter(0);
    1402           1 :   Node* const p1 = Parameter(1);
    1403             : 
    1404             :   Reduction const r1 = Reduce(graph()->NewNode(
    1405             :       machine()->Int32Add(),
    1406           4 :       graph()->NewNode(machine()->Int32Sub(), Int32Constant(0), p0), p1));
    1407           1 :   ASSERT_TRUE(r1.Changed());
    1408           6 :   EXPECT_THAT(r1.replacement(), IsInt32Sub(p1, p0));
    1409             : 
    1410             :   Reduction const r2 = Reduce(graph()->NewNode(
    1411             :       machine()->Int32Add(), p0,
    1412           3 :       graph()->NewNode(machine()->Int32Sub(), Int32Constant(0), p1)));
    1413           1 :   ASSERT_TRUE(r2.Changed());
    1414           6 :   EXPECT_THAT(r2.replacement(), IsInt32Sub(p0, p1));
    1415             : }
    1416             : 
    1417             : 
    1418             : // -----------------------------------------------------------------------------
    1419             : // Int32AddWithOverflow
    1420             : 
    1421             : 
    1422       15374 : TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
    1423             :   Node* control = graph()->start();
    1424           1 :   Node* p0 = Parameter(0);
    1425             :   {
    1426           2 :     Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
    1427             :                                  Int32Constant(0), p0, control);
    1428             : 
    1429             :     Reduction r =
    1430           2 :         Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1431           1 :     ASSERT_TRUE(r.Changed());
    1432           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1433             : 
    1434           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1435           1 :     ASSERT_TRUE(r.Changed());
    1436           2 :     EXPECT_EQ(p0, r.replacement());
    1437             :   }
    1438             :   {
    1439           1 :     Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
    1440             :                                  Int32Constant(0), control);
    1441             : 
    1442             :     Reduction r =
    1443           2 :         Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1444           1 :     ASSERT_TRUE(r.Changed());
    1445           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1446             : 
    1447           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1448           1 :     ASSERT_TRUE(r.Changed());
    1449           2 :     EXPECT_EQ(p0, r.replacement());
    1450             :   }
    1451             : }
    1452             : 
    1453             : 
    1454       15374 : TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
    1455             :   Node* control = graph()->start();
    1456         401 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
    1457       40100 :     TRACED_FOREACH(int32_t, y, kInt32Values) {
    1458             :       int32_t z;
    1459       20000 :       Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
    1460             :                                    Int32Constant(x), Int32Constant(y), control);
    1461             : 
    1462             :       Reduction r =
    1463       20000 :           Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1464       10000 :       ASSERT_TRUE(r.Changed());
    1465       60000 :       EXPECT_THAT(r.replacement(),
    1466           0 :                   IsInt32Constant(base::bits::SignedAddOverflow32(x, y, &z)));
    1467             : 
    1468       20000 :       r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1469       10000 :       ASSERT_TRUE(r.Changed());
    1470       50000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
    1471             :     }
    1472             :   }
    1473             : }
    1474             : 
    1475             : 
    1476             : // -----------------------------------------------------------------------------
    1477             : // Int32SubWithOverflow
    1478             : 
    1479             : 
    1480       15374 : TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
    1481             :   Node* control = graph()->start();
    1482           1 :   Node* p0 = Parameter(0);
    1483           2 :   Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(), p0,
    1484             :                                Int32Constant(0), control);
    1485             : 
    1486           2 :   Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1487           1 :   ASSERT_TRUE(r.Changed());
    1488           5 :   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1489             : 
    1490           2 :   r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1491           1 :   ASSERT_TRUE(r.Changed());
    1492           2 :   EXPECT_EQ(p0, r.replacement());
    1493             : }
    1494             : 
    1495             : 
    1496       15374 : TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
    1497             :   Node* control = graph()->start();
    1498         401 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
    1499       40100 :     TRACED_FOREACH(int32_t, y, kInt32Values) {
    1500             :       int32_t z;
    1501       20000 :       Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
    1502             :                                    Int32Constant(x), Int32Constant(y), control);
    1503             : 
    1504             :       Reduction r =
    1505       20000 :           Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1506       10000 :       ASSERT_TRUE(r.Changed());
    1507       60000 :       EXPECT_THAT(r.replacement(),
    1508           0 :                   IsInt32Constant(base::bits::SignedSubOverflow32(x, y, &z)));
    1509             : 
    1510       20000 :       r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1511       10000 :       ASSERT_TRUE(r.Changed());
    1512       50000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
    1513             :     }
    1514             :   }
    1515             : }
    1516             : 
    1517             : 
    1518             : // -----------------------------------------------------------------------------
    1519             : // Int32MulWithOverflow
    1520             : 
    1521       15374 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithZero) {
    1522             :   Node* control = graph()->start();
    1523           1 :   Node* p0 = Parameter(0);
    1524             :   {
    1525           2 :     Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(),
    1526             :                                  Int32Constant(0), p0, control);
    1527             : 
    1528             :     Reduction r =
    1529           2 :         Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1530           1 :     ASSERT_TRUE(r.Changed());
    1531           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1532             : 
    1533           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1534           1 :     ASSERT_TRUE(r.Changed());
    1535           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1536             :   }
    1537             :   {
    1538           1 :     Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(), p0,
    1539             :                                  Int32Constant(0), control);
    1540             : 
    1541             :     Reduction r =
    1542           2 :         Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1543           1 :     ASSERT_TRUE(r.Changed());
    1544           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1545             : 
    1546           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1547           1 :     ASSERT_TRUE(r.Changed());
    1548           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1549             :   }
    1550             : }
    1551             : 
    1552       15374 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithOne) {
    1553             :   Node* control = graph()->start();
    1554           1 :   Node* p0 = Parameter(0);
    1555             :   {
    1556           2 :     Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(),
    1557             :                                  Int32Constant(1), p0, control);
    1558             : 
    1559             :     Reduction r =
    1560           2 :         Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1561           1 :     ASSERT_TRUE(r.Changed());
    1562           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1563             : 
    1564           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1565           1 :     ASSERT_TRUE(r.Changed());
    1566           2 :     EXPECT_EQ(p0, r.replacement());
    1567             :   }
    1568             :   {
    1569           1 :     Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(), p0,
    1570             :                                  Int32Constant(1), control);
    1571             : 
    1572             :     Reduction r =
    1573           2 :         Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1574           1 :     ASSERT_TRUE(r.Changed());
    1575           5 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1576             : 
    1577           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1578           1 :     ASSERT_TRUE(r.Changed());
    1579           2 :     EXPECT_EQ(p0, r.replacement());
    1580             :   }
    1581             : }
    1582             : 
    1583       15374 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithMinusOne) {
    1584             :   Node* control = graph()->start();
    1585           1 :   Node* p0 = Parameter(0);
    1586             : 
    1587             :   {
    1588             :     Reduction r = Reduce(graph()->NewNode(machine()->Int32MulWithOverflow(),
    1589           3 :                                           Int32Constant(-1), p0, control));
    1590           1 :     ASSERT_TRUE(r.Changed());
    1591           7 :     EXPECT_THAT(r.replacement(),
    1592           0 :                 IsInt32SubWithOverflow(IsInt32Constant(0), p0));
    1593             :   }
    1594             : 
    1595             :   {
    1596             :     Reduction r = Reduce(graph()->NewNode(machine()->Int32MulWithOverflow(), p0,
    1597           2 :                                           Int32Constant(-1), control));
    1598           1 :     ASSERT_TRUE(r.Changed());
    1599           7 :     EXPECT_THAT(r.replacement(),
    1600           0 :                 IsInt32SubWithOverflow(IsInt32Constant(0), p0));
    1601             :   }
    1602             : }
    1603             : 
    1604       15374 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithTwo) {
    1605             :   Node* control = graph()->start();
    1606           1 :   Node* p0 = Parameter(0);
    1607             : 
    1608             :   {
    1609             :     Reduction r = Reduce(graph()->NewNode(machine()->Int32MulWithOverflow(),
    1610           3 :                                           Int32Constant(2), p0, control));
    1611           1 :     ASSERT_TRUE(r.Changed());
    1612           6 :     EXPECT_THAT(r.replacement(), IsInt32AddWithOverflow(p0, p0));
    1613             :   }
    1614             : 
    1615             :   {
    1616             :     Reduction r = Reduce(graph()->NewNode(machine()->Int32MulWithOverflow(), p0,
    1617           2 :                                           Int32Constant(2), control));
    1618           1 :     ASSERT_TRUE(r.Changed());
    1619           6 :     EXPECT_THAT(r.replacement(), IsInt32AddWithOverflow(p0, p0));
    1620             :   }
    1621             : }
    1622             : 
    1623       15374 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithConstant) {
    1624             :   Node* control = graph()->start();
    1625         401 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
    1626       40100 :     TRACED_FOREACH(int32_t, y, kInt32Values) {
    1627             :       int32_t z;
    1628       20000 :       Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(),
    1629             :                                    Int32Constant(x), Int32Constant(y), control);
    1630             : 
    1631             :       Reduction r =
    1632       20000 :           Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1633       10000 :       ASSERT_TRUE(r.Changed());
    1634       50000 :       EXPECT_THAT(r.replacement(),
    1635           0 :                   IsInt32Constant(base::bits::SignedMulOverflow32(x, y, &z)));
    1636             : 
    1637       20000 :       r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1638       10000 :       ASSERT_TRUE(r.Changed());
    1639       50000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
    1640             :     }
    1641             :   }
    1642             : }
    1643             : 
    1644             : // -----------------------------------------------------------------------------
    1645             : // Int32LessThan
    1646             : 
    1647       15374 : TEST_F(MachineOperatorReducerTest, Int32LessThanWithWord32Or) {
    1648           1 :   Node* const p0 = Parameter(0);
    1649         401 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
    1650             :     Node* word32_or =
    1651         200 :         graph()->NewNode(machine()->Word32Or(), p0, Int32Constant(x));
    1652         100 :     Node* less_than = graph()->NewNode(machine()->Int32LessThan(), word32_or,
    1653             :                                        Int32Constant(0));
    1654         100 :     Reduction r = Reduce(less_than);
    1655         100 :     if (x < 0) {
    1656          49 :       ASSERT_TRUE(r.Changed());
    1657         245 :       EXPECT_THAT(r.replacement(), IsInt32Constant(1));
    1658             :     } else {
    1659         102 :       ASSERT_FALSE(r.Changed());
    1660             :     }
    1661             :   }
    1662             : }
    1663             : 
    1664             : // -----------------------------------------------------------------------------
    1665             : // Uint32LessThan
    1666             : 
    1667       15374 : TEST_F(MachineOperatorReducerTest, Uint32LessThanWithWord32Sar) {
    1668           1 :   Node* const p0 = Parameter(0);
    1669          13 :   TRACED_FORRANGE(uint32_t, shift, 1, 3) {
    1670           3 :     const uint32_t limit = (kMaxInt >> shift) - 1;
    1671           6 :     Node* const node = graph()->NewNode(
    1672             :         machine()->Uint32LessThan(),
    1673             :         graph()->NewNode(machine()->Word32Sar(), p0, Uint32Constant(shift)),
    1674             :         Uint32Constant(limit));
    1675             : 
    1676           3 :     Reduction r = Reduce(node);
    1677           3 :     ASSERT_TRUE(r.Changed());
    1678          21 :     EXPECT_THAT(r.replacement(),
    1679             :                 IsUint32LessThan(
    1680           0 :                     p0, IsInt32Constant(static_cast<int32_t>(limit << shift))));
    1681             :   }
    1682             : }
    1683             : 
    1684             : 
    1685             : // -----------------------------------------------------------------------------
    1686             : // Float64Mul
    1687             : 
    1688             : 
    1689       15374 : TEST_F(MachineOperatorReducerTest, Float64MulWithMinusOne) {
    1690           1 :   Node* const p0 = Parameter(0);
    1691             :   {
    1692             :     Reduction r = Reduce(
    1693           3 :         graph()->NewNode(machine()->Float64Mul(), p0, Float64Constant(-1.0)));
    1694           1 :     ASSERT_TRUE(r.Changed());
    1695           7 :     EXPECT_THAT(r.replacement(),
    1696           0 :                 IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
    1697             :   }
    1698             :   {
    1699             :     Reduction r = Reduce(
    1700           2 :         graph()->NewNode(machine()->Float64Mul(), Float64Constant(-1.0), p0));
    1701           1 :     ASSERT_TRUE(r.Changed());
    1702           7 :     EXPECT_THAT(r.replacement(),
    1703           0 :                 IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
    1704             :   }
    1705             : }
    1706             : 
    1707       15374 : TEST_F(MachineOperatorReducerTest, Float64SubMinusZeroMinusX) {
    1708           1 :   Node* const p0 = Parameter(0);
    1709             :   {
    1710             :     Reduction r = Reduce(
    1711           3 :         graph()->NewNode(machine()->Float64Sub(), Float64Constant(-0.0), p0));
    1712           1 :     ASSERT_TRUE(r.Changed());
    1713           5 :     EXPECT_THAT(r.replacement(), IsFloat64Neg(p0));
    1714             :   }
    1715             : }
    1716             : 
    1717       15374 : TEST_F(MachineOperatorReducerTest, Float32SubMinusZeroMinusX) {
    1718           1 :   Node* const p0 = Parameter(0);
    1719             :   {
    1720             :     Reduction r = Reduce(
    1721           3 :         graph()->NewNode(machine()->Float32Sub(), Float32Constant(-0.0), p0));
    1722           1 :     ASSERT_TRUE(r.Changed());
    1723           5 :     EXPECT_THAT(r.replacement(), IsFloat32Neg(p0));
    1724             :   }
    1725             : }
    1726             : 
    1727       15374 : TEST_F(MachineOperatorReducerTest, Float64MulWithTwo) {
    1728           1 :   Node* const p0 = Parameter(0);
    1729             :   {
    1730             :     Reduction r = Reduce(
    1731           3 :         graph()->NewNode(machine()->Float64Mul(), Float64Constant(2.0), p0));
    1732           1 :     ASSERT_TRUE(r.Changed());
    1733           6 :     EXPECT_THAT(r.replacement(), IsFloat64Add(p0, p0));
    1734             :   }
    1735             :   {
    1736             :     Reduction r = Reduce(
    1737           2 :         graph()->NewNode(machine()->Float64Mul(), p0, Float64Constant(2.0)));
    1738           1 :     ASSERT_TRUE(r.Changed());
    1739           6 :     EXPECT_THAT(r.replacement(), IsFloat64Add(p0, p0));
    1740             :   }
    1741             : }
    1742             : 
    1743             : // -----------------------------------------------------------------------------
    1744             : // Float64Div
    1745             : 
    1746       15374 : TEST_F(MachineOperatorReducerTest, Float64DivWithMinusOne) {
    1747           1 :   Node* const p0 = Parameter(0);
    1748             :   {
    1749             :     Reduction r = Reduce(
    1750           3 :         graph()->NewNode(machine()->Float64Div(), p0, Float64Constant(-1.0)));
    1751           1 :     ASSERT_TRUE(r.Changed());
    1752           5 :     EXPECT_THAT(r.replacement(), IsFloat64Neg(p0));
    1753             :   }
    1754             : }
    1755             : 
    1756       15374 : TEST_F(MachineOperatorReducerTest, Float64DivWithPowerOfTwo) {
    1757           1 :   Node* const p0 = Parameter(0);
    1758        8185 :   TRACED_FORRANGE(uint64_t, exponent, 1, 0x7FE) {
    1759        2046 :     Double divisor = Double(exponent << Double::kPhysicalSignificandSize);
    1760        2046 :     if (divisor.value() == 1.0) continue;  // Skip x / 1.0 => x.
    1761             :     Reduction r = Reduce(graph()->NewNode(machine()->Float64Div(), p0,
    1762        6135 :                                           Float64Constant(divisor.value())));
    1763        2045 :     ASSERT_TRUE(r.Changed());
    1764       14315 :     EXPECT_THAT(r.replacement(),
    1765           0 :                 IsFloat64Mul(p0, IsFloat64Constant(1.0 / divisor.value())));
    1766             :   }
    1767             : }
    1768             : 
    1769             : // -----------------------------------------------------------------------------
    1770             : // Float64Acos
    1771             : 
    1772       15374 : TEST_F(MachineOperatorReducerTest, Float64AcosWithConstant) {
    1773         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1774             :     Reduction const r =
    1775         300 :         Reduce(graph()->NewNode(machine()->Float64Acos(), Float64Constant(x)));
    1776         100 :     ASSERT_TRUE(r.Changed());
    1777         600 :     EXPECT_THAT(
    1778             :         r.replacement(),
    1779           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::acos(x))));
    1780             :   }
    1781             : }
    1782             : 
    1783             : // -----------------------------------------------------------------------------
    1784             : // Float64Acosh
    1785             : 
    1786       15374 : TEST_F(MachineOperatorReducerTest, Float64AcoshWithConstant) {
    1787         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1788             :     Reduction const r =
    1789         300 :         Reduce(graph()->NewNode(machine()->Float64Acosh(), Float64Constant(x)));
    1790         100 :     ASSERT_TRUE(r.Changed());
    1791         600 :     EXPECT_THAT(
    1792             :         r.replacement(),
    1793           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::acosh(x))));
    1794             :   }
    1795             : }
    1796             : 
    1797             : // -----------------------------------------------------------------------------
    1798             : // Float64Asin
    1799             : 
    1800       15374 : TEST_F(MachineOperatorReducerTest, Float64AsinWithConstant) {
    1801         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1802             :     Reduction const r =
    1803         300 :         Reduce(graph()->NewNode(machine()->Float64Asin(), Float64Constant(x)));
    1804         100 :     ASSERT_TRUE(r.Changed());
    1805         600 :     EXPECT_THAT(
    1806             :         r.replacement(),
    1807           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::asin(x))));
    1808             :   }
    1809             : }
    1810             : 
    1811             : // -----------------------------------------------------------------------------
    1812             : // Float64Asinh
    1813             : 
    1814       15374 : TEST_F(MachineOperatorReducerTest, Float64AsinhWithConstant) {
    1815         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1816             :     Reduction const r =
    1817         300 :         Reduce(graph()->NewNode(machine()->Float64Asinh(), Float64Constant(x)));
    1818         100 :     ASSERT_TRUE(r.Changed());
    1819         600 :     EXPECT_THAT(
    1820             :         r.replacement(),
    1821           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::asinh(x))));
    1822             :   }
    1823             : }
    1824             : 
    1825             : // -----------------------------------------------------------------------------
    1826             : // Float64Atan
    1827             : 
    1828       15374 : TEST_F(MachineOperatorReducerTest, Float64AtanWithConstant) {
    1829         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1830             :     Reduction const r =
    1831         300 :         Reduce(graph()->NewNode(machine()->Float64Atan(), Float64Constant(x)));
    1832         100 :     ASSERT_TRUE(r.Changed());
    1833         600 :     EXPECT_THAT(
    1834             :         r.replacement(),
    1835           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::atan(x))));
    1836             :   }
    1837             : }
    1838             : 
    1839             : // -----------------------------------------------------------------------------
    1840             : // Float64Atanh
    1841             : 
    1842       15374 : TEST_F(MachineOperatorReducerTest, Float64AtanhWithConstant) {
    1843         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1844             :     Reduction const r =
    1845         300 :         Reduce(graph()->NewNode(machine()->Float64Atanh(), Float64Constant(x)));
    1846         100 :     ASSERT_TRUE(r.Changed());
    1847         600 :     EXPECT_THAT(
    1848             :         r.replacement(),
    1849           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::atanh(x))));
    1850             :   }
    1851             : }
    1852             : 
    1853             : // -----------------------------------------------------------------------------
    1854             : // Float64Atan2
    1855             : 
    1856       15374 : TEST_F(MachineOperatorReducerTest, Float64Atan2WithConstant) {
    1857         401 :   TRACED_FOREACH(double, y, kFloat64Values) {
    1858       40100 :     TRACED_FOREACH(double, x, kFloat64Values) {
    1859             :       Reduction const r = Reduce(graph()->NewNode(
    1860       30000 :           machine()->Float64Atan2(), Float64Constant(y), Float64Constant(x)));
    1861       10000 :       ASSERT_TRUE(r.Changed());
    1862       60000 :       EXPECT_THAT(
    1863             :           r.replacement(),
    1864           0 :           IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::atan2(y, x))));
    1865             :     }
    1866             :   }
    1867             : }
    1868             : 
    1869       15374 : TEST_F(MachineOperatorReducerTest, Float64Atan2WithNaN) {
    1870           1 :   Node* const p0 = Parameter(0);
    1871           1 :   Node* const nan = Float64Constant(std::numeric_limits<double>::quiet_NaN());
    1872             :   {
    1873             :     Reduction const r =
    1874           2 :         Reduce(graph()->NewNode(machine()->Float64Atan2(), p0, nan));
    1875           1 :     ASSERT_TRUE(r.Changed());
    1876           2 :     EXPECT_EQ(nan, r.replacement());
    1877             :   }
    1878             :   {
    1879             :     Reduction const r =
    1880           2 :         Reduce(graph()->NewNode(machine()->Float64Atan2(), nan, p0));
    1881           1 :     ASSERT_TRUE(r.Changed());
    1882           2 :     EXPECT_EQ(nan, r.replacement());
    1883             :   }
    1884             : }
    1885             : 
    1886             : // -----------------------------------------------------------------------------
    1887             : // Float64Cos
    1888             : 
    1889       15374 : TEST_F(MachineOperatorReducerTest, Float64CosWithConstant) {
    1890         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1891             :     Reduction const r =
    1892         300 :         Reduce(graph()->NewNode(machine()->Float64Cos(), Float64Constant(x)));
    1893         100 :     ASSERT_TRUE(r.Changed());
    1894         600 :     EXPECT_THAT(r.replacement(),
    1895           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::cos(x))));
    1896             :   }
    1897             : }
    1898             : 
    1899             : // -----------------------------------------------------------------------------
    1900             : // Float64Cosh
    1901             : 
    1902       15374 : TEST_F(MachineOperatorReducerTest, Float64CoshWithConstant) {
    1903         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1904             :     Reduction const r =
    1905         300 :         Reduce(graph()->NewNode(machine()->Float64Cosh(), Float64Constant(x)));
    1906         100 :     ASSERT_TRUE(r.Changed());
    1907         600 :     EXPECT_THAT(
    1908             :         r.replacement(),
    1909           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::cosh(x))));
    1910             :   }
    1911             : }
    1912             : 
    1913             : // -----------------------------------------------------------------------------
    1914             : // Float64Exp
    1915             : 
    1916       15374 : TEST_F(MachineOperatorReducerTest, Float64ExpWithConstant) {
    1917         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1918             :     Reduction const r =
    1919         300 :         Reduce(graph()->NewNode(machine()->Float64Exp(), Float64Constant(x)));
    1920         100 :     ASSERT_TRUE(r.Changed());
    1921         600 :     EXPECT_THAT(r.replacement(),
    1922           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::exp(x))));
    1923             :   }
    1924             : }
    1925             : 
    1926             : // -----------------------------------------------------------------------------
    1927             : // Float64Log
    1928             : 
    1929       15374 : TEST_F(MachineOperatorReducerTest, Float64LogWithConstant) {
    1930         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1931             :     Reduction const r =
    1932         300 :         Reduce(graph()->NewNode(machine()->Float64Log(), Float64Constant(x)));
    1933         100 :     ASSERT_TRUE(r.Changed());
    1934         600 :     EXPECT_THAT(r.replacement(),
    1935           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::log(x))));
    1936             :   }
    1937             : }
    1938             : 
    1939             : // -----------------------------------------------------------------------------
    1940             : // Float64Log1p
    1941             : 
    1942       15374 : TEST_F(MachineOperatorReducerTest, Float64Log1pWithConstant) {
    1943         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1944             :     Reduction const r =
    1945         300 :         Reduce(graph()->NewNode(machine()->Float64Log1p(), Float64Constant(x)));
    1946         100 :     ASSERT_TRUE(r.Changed());
    1947         600 :     EXPECT_THAT(
    1948             :         r.replacement(),
    1949           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::log1p(x))));
    1950             :   }
    1951             : }
    1952             : 
    1953             : // -----------------------------------------------------------------------------
    1954             : // Float64Pow
    1955             : 
    1956       15374 : TEST_F(MachineOperatorReducerTest, Float64PowWithConstant) {
    1957         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1958       40100 :     TRACED_FOREACH(double, y, kFloat64Values) {
    1959             :       Reduction const r = Reduce(graph()->NewNode(
    1960       30000 :           machine()->Float64Pow(), Float64Constant(x), Float64Constant(y)));
    1961       10000 :       ASSERT_TRUE(r.Changed());
    1962       60000 :       EXPECT_THAT(
    1963             :           r.replacement(),
    1964           0 :           IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::pow(x, y))));
    1965             :     }
    1966             :   }
    1967             : }
    1968             : 
    1969       15374 : TEST_F(MachineOperatorReducerTest, Float64PowWithZeroExponent) {
    1970           1 :   Node* const p0 = Parameter(0);
    1971             :   {
    1972             :     Reduction const r = Reduce(
    1973           3 :         graph()->NewNode(machine()->Float64Pow(), p0, Float64Constant(-0.0)));
    1974           1 :     ASSERT_TRUE(r.Changed());
    1975           5 :     EXPECT_THAT(r.replacement(), IsFloat64Constant(1.0));
    1976             :   }
    1977             :   {
    1978             :     Reduction const r = Reduce(
    1979           2 :         graph()->NewNode(machine()->Float64Pow(), p0, Float64Constant(0.0)));
    1980           1 :     ASSERT_TRUE(r.Changed());
    1981           5 :     EXPECT_THAT(r.replacement(), IsFloat64Constant(1.0));
    1982             :   }
    1983             : }
    1984             : 
    1985             : // -----------------------------------------------------------------------------
    1986             : // Float64Sin
    1987             : 
    1988       15374 : TEST_F(MachineOperatorReducerTest, Float64SinWithConstant) {
    1989         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1990             :     Reduction const r =
    1991         300 :         Reduce(graph()->NewNode(machine()->Float64Sin(), Float64Constant(x)));
    1992         100 :     ASSERT_TRUE(r.Changed());
    1993         600 :     EXPECT_THAT(r.replacement(),
    1994           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::sin(x))));
    1995             :   }
    1996             : }
    1997             : 
    1998             : // -----------------------------------------------------------------------------
    1999             : // Float64Sinh
    2000             : 
    2001       15374 : TEST_F(MachineOperatorReducerTest, Float64SinhWithConstant) {
    2002         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2003             :     Reduction const r =
    2004         300 :         Reduce(graph()->NewNode(machine()->Float64Sinh(), Float64Constant(x)));
    2005         100 :     ASSERT_TRUE(r.Changed());
    2006         600 :     EXPECT_THAT(
    2007             :         r.replacement(),
    2008           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::sinh(x))));
    2009             :   }
    2010             : }
    2011             : 
    2012             : // -----------------------------------------------------------------------------
    2013             : // Float64Tan
    2014             : 
    2015       15374 : TEST_F(MachineOperatorReducerTest, Float64TanWithConstant) {
    2016         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2017             :     Reduction const r =
    2018         300 :         Reduce(graph()->NewNode(machine()->Float64Tan(), Float64Constant(x)));
    2019         100 :     ASSERT_TRUE(r.Changed());
    2020         600 :     EXPECT_THAT(r.replacement(),
    2021           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::tan(x))));
    2022             :   }
    2023             : }
    2024             : 
    2025             : // -----------------------------------------------------------------------------
    2026             : // Float64Tanh
    2027             : 
    2028       15374 : TEST_F(MachineOperatorReducerTest, Float64TanhWithConstant) {
    2029         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2030             :     Reduction const r =
    2031         300 :         Reduce(graph()->NewNode(machine()->Float64Tanh(), Float64Constant(x)));
    2032         100 :     ASSERT_TRUE(r.Changed());
    2033         600 :     EXPECT_THAT(
    2034             :         r.replacement(),
    2035           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::tanh(x))));
    2036             :   }
    2037             : }
    2038             : 
    2039             : // -----------------------------------------------------------------------------
    2040             : // Float64InsertLowWord32
    2041             : 
    2042       15374 : TEST_F(MachineOperatorReducerTest, Float64InsertLowWord32WithConstant) {
    2043         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2044       19300 :     TRACED_FOREACH(uint32_t, y, kUint32Values) {
    2045             :       Reduction const r =
    2046             :           Reduce(graph()->NewNode(machine()->Float64InsertLowWord32(),
    2047       19200 :                                   Float64Constant(x), Uint32Constant(y)));
    2048        4800 :       ASSERT_TRUE(r.Changed());
    2049       24000 :       EXPECT_THAT(
    2050             :           r.replacement(),
    2051             :           IsFloat64Constant(BitEq(bit_cast<double>(
    2052           0 :               (bit_cast<uint64_t>(x) & uint64_t{0xFFFFFFFF00000000}) | y))));
    2053             :     }
    2054             :   }
    2055             : }
    2056             : 
    2057             : 
    2058             : // -----------------------------------------------------------------------------
    2059             : // Float64InsertHighWord32
    2060             : 
    2061             : 
    2062       15374 : TEST_F(MachineOperatorReducerTest, Float64InsertHighWord32WithConstant) {
    2063         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2064       19300 :     TRACED_FOREACH(uint32_t, y, kUint32Values) {
    2065             :       Reduction const r =
    2066             :           Reduce(graph()->NewNode(machine()->Float64InsertHighWord32(),
    2067       19200 :                                   Float64Constant(x), Uint32Constant(y)));
    2068        4800 :       ASSERT_TRUE(r.Changed());
    2069       24000 :       EXPECT_THAT(r.replacement(),
    2070             :                   IsFloat64Constant(BitEq(bit_cast<double>(
    2071             :                       (bit_cast<uint64_t>(x) & uint64_t{0xFFFFFFFF}) |
    2072           0 :                       (static_cast<uint64_t>(y) << 32)))));
    2073             :     }
    2074             :   }
    2075             : }
    2076             : 
    2077             : 
    2078             : // -----------------------------------------------------------------------------
    2079             : // Float64Equal
    2080             : 
    2081       15374 : TEST_F(MachineOperatorReducerTest, Float64EqualWithConstant) {
    2082         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2083       40100 :     TRACED_FOREACH(double, y, kFloat64Values) {
    2084             :       Reduction const r = Reduce(graph()->NewNode(
    2085       30000 :           machine()->Float64Equal(), Float64Constant(x), Float64Constant(y)));
    2086       10000 :       ASSERT_TRUE(r.Changed());
    2087       50000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(x == y));
    2088             :     }
    2089             :   }
    2090             : }
    2091             : 
    2092       15374 : TEST_F(MachineOperatorReducerTest, Float64EqualWithFloat32Conversions) {
    2093           1 :   Node* const p0 = Parameter(0);
    2094           1 :   Node* const p1 = Parameter(1);
    2095             :   Reduction const r = Reduce(graph()->NewNode(
    2096             :       machine()->Float64Equal(),
    2097             :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2098           4 :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
    2099           1 :   ASSERT_TRUE(r.Changed());
    2100           6 :   EXPECT_THAT(r.replacement(), IsFloat32Equal(p0, p1));
    2101             : }
    2102             : 
    2103             : 
    2104       15374 : TEST_F(MachineOperatorReducerTest, Float64EqualWithFloat32Constant) {
    2105           1 :   Node* const p0 = Parameter(0);
    2106         401 :   TRACED_FOREACH(float, x, kFloat32Values) {
    2107             :     Reduction r = Reduce(graph()->NewNode(
    2108             :         machine()->Float64Equal(),
    2109             :         graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2110         400 :         Float64Constant(x)));
    2111         100 :     ASSERT_TRUE(r.Changed());
    2112         700 :     EXPECT_THAT(r.replacement(), IsFloat32Equal(p0, IsFloat32Constant(x)));
    2113             :   }
    2114             : }
    2115             : 
    2116             : 
    2117             : // -----------------------------------------------------------------------------
    2118             : // Float64LessThan
    2119             : 
    2120       15374 : TEST_F(MachineOperatorReducerTest, Float64LessThanWithConstant) {
    2121         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2122       40100 :     TRACED_FOREACH(double, y, kFloat64Values) {
    2123             :       Reduction const r =
    2124             :           Reduce(graph()->NewNode(machine()->Float64LessThan(),
    2125       30000 :                                   Float64Constant(x), Float64Constant(y)));
    2126       10000 :       ASSERT_TRUE(r.Changed());
    2127       50000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(x < y));
    2128             :     }
    2129             :   }
    2130             : }
    2131             : 
    2132       15374 : TEST_F(MachineOperatorReducerTest, Float64LessThanWithFloat32Conversions) {
    2133           1 :   Node* const p0 = Parameter(0);
    2134           1 :   Node* const p1 = Parameter(1);
    2135             :   Reduction const r = Reduce(graph()->NewNode(
    2136             :       machine()->Float64LessThan(),
    2137             :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2138           4 :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
    2139           1 :   ASSERT_TRUE(r.Changed());
    2140           6 :   EXPECT_THAT(r.replacement(), IsFloat32LessThan(p0, p1));
    2141             : }
    2142             : 
    2143             : 
    2144       15374 : TEST_F(MachineOperatorReducerTest, Float64LessThanWithFloat32Constant) {
    2145           1 :   Node* const p0 = Parameter(0);
    2146             :   {
    2147         401 :     TRACED_FOREACH(float, x, kFloat32Values) {
    2148             :       Reduction r = Reduce(graph()->NewNode(
    2149             :           machine()->Float64LessThan(),
    2150             :           graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2151         400 :           Float64Constant(x)));
    2152         100 :       ASSERT_TRUE(r.Changed());
    2153         700 :       EXPECT_THAT(r.replacement(), IsFloat32LessThan(p0, IsFloat32Constant(x)));
    2154             :     }
    2155             :   }
    2156             :   {
    2157         401 :     TRACED_FOREACH(float, x, kFloat32Values) {
    2158             :       Reduction r = Reduce(graph()->NewNode(
    2159             :           machine()->Float64LessThan(), Float64Constant(x),
    2160         300 :           graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0)));
    2161         100 :       ASSERT_TRUE(r.Changed());
    2162         700 :       EXPECT_THAT(r.replacement(), IsFloat32LessThan(IsFloat32Constant(x), p0));
    2163             :     }
    2164             :   }
    2165             : }
    2166             : 
    2167             : 
    2168             : // -----------------------------------------------------------------------------
    2169             : // Float64LessThanOrEqual
    2170             : 
    2171       15374 : TEST_F(MachineOperatorReducerTest, Float64LessThanOrEqualWithConstant) {
    2172         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2173       40100 :     TRACED_FOREACH(double, y, kFloat64Values) {
    2174             :       Reduction const r =
    2175             :           Reduce(graph()->NewNode(machine()->Float64LessThanOrEqual(),
    2176       30000 :                                   Float64Constant(x), Float64Constant(y)));
    2177       10000 :       ASSERT_TRUE(r.Changed());
    2178       50000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(x <= y));
    2179             :     }
    2180             :   }
    2181             : }
    2182             : 
    2183       15374 : TEST_F(MachineOperatorReducerTest,
    2184             :        Float64LessThanOrEqualWithFloat32Conversions) {
    2185           1 :   Node* const p0 = Parameter(0);
    2186           1 :   Node* const p1 = Parameter(1);
    2187             :   Reduction const r = Reduce(graph()->NewNode(
    2188             :       machine()->Float64LessThanOrEqual(),
    2189             :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2190           4 :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
    2191           1 :   ASSERT_TRUE(r.Changed());
    2192           6 :   EXPECT_THAT(r.replacement(), IsFloat32LessThanOrEqual(p0, p1));
    2193             : }
    2194             : 
    2195             : 
    2196       15374 : TEST_F(MachineOperatorReducerTest, Float64LessThanOrEqualWithFloat32Constant) {
    2197           1 :   Node* const p0 = Parameter(0);
    2198             :   {
    2199         401 :     TRACED_FOREACH(float, x, kFloat32Values) {
    2200             :       Reduction r = Reduce(graph()->NewNode(
    2201             :           machine()->Float64LessThanOrEqual(),
    2202             :           graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2203         400 :           Float64Constant(x)));
    2204         100 :       ASSERT_TRUE(r.Changed());
    2205         700 :       EXPECT_THAT(r.replacement(),
    2206           0 :                   IsFloat32LessThanOrEqual(p0, IsFloat32Constant(x)));
    2207             :     }
    2208             :   }
    2209             :   {
    2210         401 :     TRACED_FOREACH(float, x, kFloat32Values) {
    2211             :       Reduction r = Reduce(graph()->NewNode(
    2212             :           machine()->Float64LessThanOrEqual(), Float64Constant(x),
    2213         300 :           graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0)));
    2214         100 :       ASSERT_TRUE(r.Changed());
    2215         700 :       EXPECT_THAT(r.replacement(),
    2216           0 :                   IsFloat32LessThanOrEqual(IsFloat32Constant(x), p0));
    2217             :     }
    2218             :   }
    2219             : }
    2220             : 
    2221             : 
    2222             : // -----------------------------------------------------------------------------
    2223             : // Float64RoundDown
    2224             : 
    2225       15374 : TEST_F(MachineOperatorReducerTest, Float64RoundDownWithConstant) {
    2226         401 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2227             :     Reduction r = Reduce(graph()->NewNode(
    2228         300 :         machine()->Float64RoundDown().placeholder(), Float64Constant(x)));
    2229         100 :     ASSERT_TRUE(r.Changed());
    2230         500 :     EXPECT_THAT(r.replacement(), IsFloat64Constant(std::floor(x)));
    2231             :   }
    2232             : }
    2233             : 
    2234             : // -----------------------------------------------------------------------------
    2235             : // Store
    2236             : 
    2237       15374 : TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32And) {
    2238             :   const StoreRepresentation rep(MachineRepresentation::kWord8, kNoWriteBarrier);
    2239           1 :   Node* const base = Parameter(0);
    2240           1 :   Node* const index = Parameter(1);
    2241           1 :   Node* const value = Parameter(2);
    2242             :   Node* const effect = graph()->start();
    2243             :   Node* const control = graph()->start();
    2244         193 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
    2245             :     Node* const node =
    2246         144 :         graph()->NewNode(machine()->Store(rep), base, index,
    2247             :                          graph()->NewNode(machine()->Word32And(), value,
    2248             :                                           Uint32Constant(x | 0xFFu)),
    2249             :                          effect, control);
    2250             : 
    2251          48 :     Reduction r = Reduce(node);
    2252          48 :     ASSERT_TRUE(r.Changed());
    2253         480 :     EXPECT_THAT(r.replacement(),
    2254           0 :                 IsStore(rep, base, index, value, effect, control));
    2255             :   }
    2256             : }
    2257             : 
    2258             : 
    2259       15374 : TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32SarAndWord32Shl) {
    2260             :   const StoreRepresentation rep(MachineRepresentation::kWord8, kNoWriteBarrier);
    2261           1 :   Node* const base = Parameter(0);
    2262           1 :   Node* const index = Parameter(1);
    2263           1 :   Node* const value = Parameter(2);
    2264             :   Node* const effect = graph()->start();
    2265             :   Node* const control = graph()->start();
    2266          97 :   TRACED_FORRANGE(int32_t, x, 1, 24) {
    2267          96 :     Node* const node = graph()->NewNode(
    2268             :         machine()->Store(rep), base, index,
    2269             :         graph()->NewNode(
    2270             :             machine()->Word32Sar(),
    2271             :             graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
    2272             :             Int32Constant(x)),
    2273             :         effect, control);
    2274             : 
    2275          24 :     Reduction r = Reduce(node);
    2276          24 :     ASSERT_TRUE(r.Changed());
    2277         240 :     EXPECT_THAT(r.replacement(),
    2278           0 :                 IsStore(rep, base, index, value, effect, control));
    2279             :   }
    2280             : }
    2281             : 
    2282             : 
    2283       15374 : TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32And) {
    2284             :   const StoreRepresentation rep(MachineRepresentation::kWord16,
    2285             :                                 kNoWriteBarrier);
    2286           1 :   Node* const base = Parameter(0);
    2287           1 :   Node* const index = Parameter(1);
    2288           1 :   Node* const value = Parameter(2);
    2289             :   Node* const effect = graph()->start();
    2290             :   Node* const control = graph()->start();
    2291         193 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
    2292             :     Node* const node =
    2293         144 :         graph()->NewNode(machine()->Store(rep), base, index,
    2294             :                          graph()->NewNode(machine()->Word32And(), value,
    2295             :                                           Uint32Constant(x | 0xFFFFu)),
    2296             :                          effect, control);
    2297             : 
    2298          48 :     Reduction r = Reduce(node);
    2299          48 :     ASSERT_TRUE(r.Changed());
    2300         480 :     EXPECT_THAT(r.replacement(),
    2301           0 :                 IsStore(rep, base, index, value, effect, control));
    2302             :   }
    2303             : }
    2304             : 
    2305             : 
    2306       15374 : TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32SarAndWord32Shl) {
    2307             :   const StoreRepresentation rep(MachineRepresentation::kWord16,
    2308             :                                 kNoWriteBarrier);
    2309           1 :   Node* const base = Parameter(0);
    2310           1 :   Node* const index = Parameter(1);
    2311           1 :   Node* const value = Parameter(2);
    2312             :   Node* const effect = graph()->start();
    2313             :   Node* const control = graph()->start();
    2314          65 :   TRACED_FORRANGE(int32_t, x, 1, 16) {
    2315          64 :     Node* const node = graph()->NewNode(
    2316             :         machine()->Store(rep), base, index,
    2317             :         graph()->NewNode(
    2318             :             machine()->Word32Sar(),
    2319             :             graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
    2320             :             Int32Constant(x)),
    2321             :         effect, control);
    2322             : 
    2323          16 :     Reduction r = Reduce(node);
    2324          16 :     ASSERT_TRUE(r.Changed());
    2325         160 :     EXPECT_THAT(r.replacement(),
    2326           0 :                 IsStore(rep, base, index, value, effect, control));
    2327             :   }
    2328             : }
    2329             : 
    2330             : }  // namespace compiler
    2331             : }  // namespace internal
    2332        9222 : }  // namespace v8

Generated by: LCOV version 1.10