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: 980 1045 93.8 %
Date: 2019-01-20 Functions: 207 310 66.8 %

          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      180224 :     MachineOperatorReducer reducer(&graph_reducer_, &jsgraph);
      44      180224 :     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             :   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             : }  // namespace
     319             : 
     320             : 
     321             : // -----------------------------------------------------------------------------
     322             : // ChangeFloat64ToFloat32
     323             : 
     324             : 
     325       15129 : TEST_F(MachineOperatorReducerTest, ChangeFloat64ToFloat32WithConstant) {
     326         601 :   TRACED_FOREACH(float, x, kFloat32Values) {
     327             :     Reduction reduction = Reduce(graph()->NewNode(
     328         200 :         machine()->ChangeFloat32ToFloat64(), Float32Constant(x)));
     329         101 :     ASSERT_TRUE(reduction.Changed());
     330         400 :     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq<double>(x)));
     331         100 :   }
     332             : }
     333             : 
     334             : 
     335             : // -----------------------------------------------------------------------------
     336             : // ChangeFloat64ToInt32
     337             : 
     338             : 
     339       15129 : TEST_F(MachineOperatorReducerTest,
     340             :        ChangeFloat64ToInt32WithChangeInt32ToFloat64) {
     341           1 :   Node* value = Parameter(0);
     342             :   Reduction reduction = Reduce(graph()->NewNode(
     343             :       machine()->ChangeFloat64ToInt32(),
     344           3 :       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
     345           2 :   ASSERT_TRUE(reduction.Changed());
     346           2 :   EXPECT_EQ(value, reduction.replacement());
     347             : }
     348             : 
     349       15129 : TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt32WithConstant) {
     350         601 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     351             :     Reduction reduction = Reduce(graph()->NewNode(
     352         200 :         machine()->ChangeFloat64ToInt32(), Float64Constant(FastI2D(x))));
     353         101 :     ASSERT_TRUE(reduction.Changed());
     354         400 :     EXPECT_THAT(reduction.replacement(), IsInt32Constant(x));
     355         100 :   }
     356             : }
     357             : 
     358             : // -----------------------------------------------------------------------------
     359             : // ChangeFloat64ToInt64
     360             : 
     361       15129 : TEST_F(MachineOperatorReducerTest,
     362             :        ChangeFloat64ToInt64WithChangeInt64ToFloat64) {
     363           1 :   Node* value = Parameter(0);
     364             :   Reduction reduction = Reduce(graph()->NewNode(
     365             :       machine()->ChangeFloat64ToInt64(),
     366           3 :       graph()->NewNode(machine()->ChangeInt64ToFloat64(), value)));
     367           2 :   ASSERT_TRUE(reduction.Changed());
     368           2 :   EXPECT_EQ(value, reduction.replacement());
     369             : }
     370             : 
     371       15129 : TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt64WithConstant) {
     372         601 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     373             :     Reduction reduction = Reduce(graph()->NewNode(
     374         200 :         machine()->ChangeFloat64ToInt64(), Float64Constant(FastI2D(x))));
     375         101 :     ASSERT_TRUE(reduction.Changed());
     376         400 :     EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
     377         100 :   }
     378             : }
     379             : 
     380             : // -----------------------------------------------------------------------------
     381             : // ChangeFloat64ToUint32
     382             : 
     383             : 
     384       15129 : TEST_F(MachineOperatorReducerTest,
     385             :        ChangeFloat64ToUint32WithChangeUint32ToFloat64) {
     386           1 :   Node* value = Parameter(0);
     387             :   Reduction reduction = Reduce(graph()->NewNode(
     388             :       machine()->ChangeFloat64ToUint32(),
     389           3 :       graph()->NewNode(machine()->ChangeUint32ToFloat64(), value)));
     390           2 :   ASSERT_TRUE(reduction.Changed());
     391           2 :   EXPECT_EQ(value, reduction.replacement());
     392             : }
     393             : 
     394             : 
     395       15129 : TEST_F(MachineOperatorReducerTest, ChangeFloat64ToUint32WithConstant) {
     396         289 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
     397             :     Reduction reduction = Reduce(graph()->NewNode(
     398          96 :         machine()->ChangeFloat64ToUint32(), Float64Constant(FastUI2D(x))));
     399          49 :     ASSERT_TRUE(reduction.Changed());
     400         240 :     EXPECT_THAT(reduction.replacement(), IsInt32Constant(bit_cast<int32_t>(x)));
     401          48 :   }
     402             : }
     403             : 
     404             : 
     405             : // -----------------------------------------------------------------------------
     406             : // ChangeInt32ToFloat64
     407             : 
     408             : 
     409       15129 : TEST_F(MachineOperatorReducerTest, ChangeInt32ToFloat64WithConstant) {
     410         601 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     411             :     Reduction reduction = Reduce(
     412         200 :         graph()->NewNode(machine()->ChangeInt32ToFloat64(), Int32Constant(x)));
     413         101 :     ASSERT_TRUE(reduction.Changed());
     414         500 :     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastI2D(x))));
     415         100 :   }
     416             : }
     417             : 
     418             : 
     419             : // -----------------------------------------------------------------------------
     420             : // ChangeInt32ToInt64
     421             : 
     422             : 
     423       15129 : TEST_F(MachineOperatorReducerTest, ChangeInt32ToInt64WithConstant) {
     424         601 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     425             :     Reduction reduction = Reduce(
     426         200 :         graph()->NewNode(machine()->ChangeInt32ToInt64(), Int32Constant(x)));
     427         101 :     ASSERT_TRUE(reduction.Changed());
     428         400 :     EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
     429         100 :   }
     430             : }
     431             : 
     432             : // -----------------------------------------------------------------------------
     433             : // ChangeInt64ToFloat64
     434             : 
     435       15129 : TEST_F(MachineOperatorReducerTest,
     436             :        ChangeInt64ToFloat64WithChangeFloat64ToInt64) {
     437           1 :   Node* value = Parameter(0);
     438             :   Reduction reduction = Reduce(graph()->NewNode(
     439             :       machine()->ChangeInt64ToFloat64(),
     440           3 :       graph()->NewNode(machine()->ChangeFloat64ToInt64(), value)));
     441           2 :   ASSERT_TRUE(reduction.Changed());
     442           2 :   EXPECT_EQ(value, reduction.replacement());
     443             : }
     444             : 
     445       15129 : TEST_F(MachineOperatorReducerTest, ChangeInt64ToFloat64WithConstant) {
     446         601 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
     447             :     Reduction reduction = Reduce(
     448         200 :         graph()->NewNode(machine()->ChangeInt64ToFloat64(), Int64Constant(x)));
     449         101 :     ASSERT_TRUE(reduction.Changed());
     450         500 :     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastI2D(x))));
     451         100 :   }
     452             : }
     453             : 
     454             : // -----------------------------------------------------------------------------
     455             : // ChangeUint32ToFloat64
     456             : 
     457             : 
     458       15129 : TEST_F(MachineOperatorReducerTest, ChangeUint32ToFloat64WithConstant) {
     459         289 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
     460             :     Reduction reduction =
     461             :         Reduce(graph()->NewNode(machine()->ChangeUint32ToFloat64(),
     462          96 :                                 Int32Constant(bit_cast<int32_t>(x))));
     463          49 :     ASSERT_TRUE(reduction.Changed());
     464         240 :     EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastUI2D(x))));
     465          48 :   }
     466             : }
     467             : 
     468             : 
     469             : // -----------------------------------------------------------------------------
     470             : // ChangeUint32ToUint64
     471             : 
     472             : 
     473       15129 : TEST_F(MachineOperatorReducerTest, ChangeUint32ToUint64WithConstant) {
     474         289 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
     475             :     Reduction reduction =
     476             :         Reduce(graph()->NewNode(machine()->ChangeUint32ToUint64(),
     477          96 :                                 Int32Constant(bit_cast<int32_t>(x))));
     478          49 :     ASSERT_TRUE(reduction.Changed());
     479         240 :     EXPECT_THAT(reduction.replacement(),
     480           0 :                 IsInt64Constant(bit_cast<int64_t>(static_cast<uint64_t>(x))));
     481          48 :   }
     482             : }
     483             : 
     484             : 
     485             : // -----------------------------------------------------------------------------
     486             : // TruncateFloat64ToFloat32
     487             : 
     488             : 
     489       15129 : TEST_F(MachineOperatorReducerTest,
     490             :        TruncateFloat64ToFloat32WithChangeFloat32ToFloat64) {
     491           1 :   Node* value = Parameter(0);
     492             :   Reduction reduction = Reduce(graph()->NewNode(
     493             :       machine()->TruncateFloat64ToFloat32(),
     494           3 :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), value)));
     495           2 :   ASSERT_TRUE(reduction.Changed());
     496           2 :   EXPECT_EQ(value, reduction.replacement());
     497             : }
     498             : 
     499             : 
     500       15129 : TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
     501         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
     502             :     Reduction reduction = Reduce(graph()->NewNode(
     503         200 :         machine()->TruncateFloat64ToFloat32(), Float64Constant(x)));
     504         101 :     ASSERT_TRUE(reduction.Changed());
     505         500 :     EXPECT_THAT(reduction.replacement(),
     506           0 :                 IsFloat32Constant(BitEq(DoubleToFloat32(x))));
     507         100 :   }
     508             : }
     509             : 
     510             : 
     511             : // -----------------------------------------------------------------------------
     512             : // TruncateFloat64ToWord32
     513             : 
     514       15129 : TEST_F(MachineOperatorReducerTest,
     515             :        TruncateFloat64ToWord32WithChangeInt32ToFloat64) {
     516           1 :   Node* value = Parameter(0);
     517             :   Reduction reduction = Reduce(graph()->NewNode(
     518             :       machine()->TruncateFloat64ToWord32(),
     519           3 :       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
     520           2 :   ASSERT_TRUE(reduction.Changed());
     521           2 :   EXPECT_EQ(value, reduction.replacement());
     522             : }
     523             : 
     524       15129 : TEST_F(MachineOperatorReducerTest, TruncateFloat64ToWord32WithConstant) {
     525         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
     526             :     Reduction reduction = Reduce(graph()->NewNode(
     527         200 :         machine()->TruncateFloat64ToWord32(), Float64Constant(x)));
     528         101 :     ASSERT_TRUE(reduction.Changed());
     529         400 :     EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
     530         100 :   }
     531             : }
     532             : 
     533             : 
     534             : // -----------------------------------------------------------------------------
     535             : // TruncateInt64ToInt32
     536             : 
     537             : 
     538       15129 : TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithChangeInt32ToInt64) {
     539           1 :   Node* value = Parameter(0);
     540             :   Reduction reduction = Reduce(graph()->NewNode(
     541             :       machine()->TruncateInt64ToInt32(),
     542           3 :       graph()->NewNode(machine()->ChangeInt32ToInt64(), value)));
     543           2 :   ASSERT_TRUE(reduction.Changed());
     544           2 :   EXPECT_EQ(value, reduction.replacement());
     545             : }
     546             : 
     547             : 
     548       15129 : TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithConstant) {
     549         601 :   TRACED_FOREACH(int64_t, x, kInt64Values) {
     550             :     Reduction reduction = Reduce(
     551         200 :         graph()->NewNode(machine()->TruncateInt64ToInt32(), Int64Constant(x)));
     552         101 :     ASSERT_TRUE(reduction.Changed());
     553         600 :     EXPECT_THAT(reduction.replacement(),
     554             :                 IsInt32Constant(bit_cast<int32_t>(
     555           0 :                     static_cast<uint32_t>(bit_cast<uint64_t>(x)))));
     556         100 :   }
     557             : }
     558             : 
     559             : 
     560             : // -----------------------------------------------------------------------------
     561             : // RoundFloat64ToInt32
     562             : 
     563       15129 : TEST_F(MachineOperatorReducerTest,
     564             :        RoundFloat64ToInt32WithChangeInt32ToFloat64) {
     565           1 :   Node* value = Parameter(0);
     566             :   Reduction reduction = Reduce(graph()->NewNode(
     567             :       machine()->RoundFloat64ToInt32(),
     568           3 :       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
     569           2 :   ASSERT_TRUE(reduction.Changed());
     570           2 :   EXPECT_EQ(value, reduction.replacement());
     571             : }
     572             : 
     573       15129 : TEST_F(MachineOperatorReducerTest, RoundFloat64ToInt32WithConstant) {
     574         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
     575             :     Reduction reduction = Reduce(
     576         200 :         graph()->NewNode(machine()->RoundFloat64ToInt32(), Float64Constant(x)));
     577         101 :     ASSERT_TRUE(reduction.Changed());
     578         400 :     EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
     579         100 :   }
     580             : }
     581             : 
     582             : // -----------------------------------------------------------------------------
     583             : // Word32And
     584             : 
     585       15129 : TEST_F(MachineOperatorReducerTest, Word32AndWithWord32ShlWithConstant) {
     586           1 :   Node* const p0 = Parameter(0);
     587             : 
     588         187 :   TRACED_FORRANGE(int32_t, l, 1, 31) {
     589        3472 :     TRACED_FORRANGE(int32_t, k, 1, l) {
     590             :       // (x << L) & (-1 << K) => x << L
     591             :       Reduction const r1 = Reduce(graph()->NewNode(
     592             :           machine()->Word32And(),
     593             :           graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(l)),
     594        1488 :           Int32Constant(-1 << k)));
     595         496 :       ASSERT_TRUE(r1.Changed());
     596        2976 :       EXPECT_THAT(r1.replacement(), IsWord32Shl(p0, IsInt32Constant(l)));
     597             : 
     598             :       // (-1 << K) & (x << L) => x << L
     599             :       Reduction const r2 = Reduce(graph()->NewNode(
     600             :           machine()->Word32And(), Int32Constant(-1 << k),
     601        1488 :           graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(l))));
     602         496 :       ASSERT_TRUE(r2.Changed());
     603        2976 :       EXPECT_THAT(r2.replacement(), IsWord32Shl(p0, IsInt32Constant(l)));
     604         496 :     }
     605          31 :   }
     606             : }
     607             : 
     608             : 
     609       15129 : TEST_F(MachineOperatorReducerTest, Word32AndWithWord32AndWithConstant) {
     610           1 :   Node* const p0 = Parameter(0);
     611             : 
     612         601 :   TRACED_FOREACH(int32_t, k, kInt32Values) {
     613       70000 :     TRACED_FOREACH(int32_t, l, kInt32Values) {
     614       10000 :       if (k == 0 || k == -1 || l == 0 || l == -1) continue;
     615             : 
     616             :       // (x & K) & L => x & (K & L)
     617             :       Reduction const r1 = Reduce(graph()->NewNode(
     618             :           machine()->Word32And(),
     619             :           graph()->NewNode(machine()->Word32And(), p0, Int32Constant(k)),
     620       29403 :           Int32Constant(l)));
     621        9801 :       ASSERT_TRUE(r1.Changed());
     622       57486 :       EXPECT_THAT(r1.replacement(),
     623             :                   (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
     624           0 :                           : IsInt32Constant(0));
     625             : 
     626             :       // (K & x) & L => x & (K & L)
     627             :       Reduction const r2 = Reduce(graph()->NewNode(
     628             :           machine()->Word32And(),
     629             :           graph()->NewNode(machine()->Word32And(), Int32Constant(k), p0),
     630       29403 :           Int32Constant(l)));
     631        9801 :       ASSERT_TRUE(r2.Changed());
     632       57486 :       EXPECT_THAT(r2.replacement(),
     633             :                   (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
     634           0 :                           : IsInt32Constant(0));
     635       10000 :     }
     636         100 :   }
     637             : }
     638             : 
     639             : 
     640       15129 : TEST_F(MachineOperatorReducerTest, Word32AndWithInt32AddAndConstant) {
     641           1 :   Node* const p0 = Parameter(0);
     642           1 :   Node* const p1 = Parameter(1);
     643             : 
     644         187 :   TRACED_FORRANGE(int32_t, l, 1, 31) {
     645       21700 :     TRACED_FOREACH(int32_t, k, kInt32Values) {
     646        3100 :       if ((k << l) == 0) continue;
     647             :       // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
     648             :       Reduction const r = Reduce(graph()->NewNode(
     649             :           machine()->Word32And(),
     650             :           graph()->NewNode(machine()->Int32Add(), p0, Int32Constant(k << l)),
     651        8769 :           Int32Constant(-1 << l)));
     652        2923 :       ASSERT_TRUE(r.Changed());
     653       26307 :       EXPECT_THAT(r.replacement(),
     654             :                   IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
     655           0 :                              IsInt32Constant(k << l)));
     656        3100 :     }
     657             : 
     658          31 :     Node* s1 = graph()->NewNode(machine()->Word32Shl(), p1, Int32Constant(l));
     659             : 
     660             :     // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
     661             :     Reduction const r1 = Reduce(graph()->NewNode(
     662             :         machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), s1, p0),
     663          93 :         Int32Constant(-1 << l)));
     664          31 :     ASSERT_TRUE(r1.Changed());
     665         248 :     EXPECT_THAT(r1.replacement(),
     666           0 :                 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)), s1));
     667             : 
     668             :     // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
     669             :     Reduction const r2 = Reduce(graph()->NewNode(
     670             :         machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), p0, s1),
     671          93 :         Int32Constant(-1 << l)));
     672          31 :     ASSERT_TRUE(r2.Changed());
     673         248 :     EXPECT_THAT(r2.replacement(),
     674           0 :                 IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)), s1));
     675          31 :   }
     676             : }
     677             : 
     678             : 
     679       15129 : TEST_F(MachineOperatorReducerTest, Word32AndWithInt32MulAndConstant) {
     680           1 :   Node* const p0 = Parameter(0);
     681             : 
     682         187 :   TRACED_FORRANGE(int32_t, l, 1, 31) {
     683       21700 :     TRACED_FOREACH(int32_t, k, kInt32Values) {
     684        3100 :       if ((k << l) == 0) continue;
     685             : 
     686             :       // (x * (K << L)) & (-1 << L) => x * (K << L)
     687             :       Reduction const r1 = Reduce(graph()->NewNode(
     688             :           machine()->Word32And(),
     689             :           graph()->NewNode(machine()->Int32Mul(), p0, Int32Constant(k << l)),
     690        8769 :           Int32Constant(-1 << l)));
     691        2923 :       ASSERT_TRUE(r1.Changed());
     692       17538 :       EXPECT_THAT(r1.replacement(), IsInt32Mul(p0, IsInt32Constant(k << l)));
     693             : 
     694             :       // ((K << L) * x) & (-1 << L) => x * (K << L)
     695             :       Reduction const r2 = Reduce(graph()->NewNode(
     696             :           machine()->Word32And(),
     697             :           graph()->NewNode(machine()->Int32Mul(), Int32Constant(k << l), p0),
     698        8769 :           Int32Constant(-1 << l)));
     699        2923 :       ASSERT_TRUE(r2.Changed());
     700       17538 :       EXPECT_THAT(r2.replacement(), IsInt32Mul(p0, IsInt32Constant(k << l)));
     701        3100 :     }
     702          31 :   }
     703             : }
     704             : 
     705             : 
     706       15129 : TEST_F(MachineOperatorReducerTest,
     707             :        Word32AndWithInt32AddAndInt32MulAndConstant) {
     708           1 :   Node* const p0 = Parameter(0);
     709           1 :   Node* const p1 = Parameter(1);
     710             : 
     711         187 :   TRACED_FORRANGE(int32_t, l, 1, 31) {
     712       21700 :     TRACED_FOREACH(int32_t, k, kInt32Values) {
     713        3100 :       if ((k << l) == 0) continue;
     714             :       // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
     715             :       Reduction const r1 = Reduce(graph()->NewNode(
     716             :           machine()->Word32And(),
     717             :           graph()->NewNode(machine()->Int32Add(),
     718             :                            graph()->NewNode(machine()->Int32Mul(), p1,
     719             :                                             Int32Constant(k << l)),
     720             :                            p0),
     721       11692 :           Int32Constant(-1 << l)));
     722        2923 :       ASSERT_TRUE(r1.Changed());
     723       32153 :       EXPECT_THAT(r1.replacement(),
     724             :                   IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
     725           0 :                              IsInt32Mul(p1, IsInt32Constant(k << l))));
     726             : 
     727             :       // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
     728             :       Reduction const r2 = Reduce(graph()->NewNode(
     729             :           machine()->Word32And(),
     730             :           graph()->NewNode(machine()->Int32Add(), p0,
     731             :                            graph()->NewNode(machine()->Int32Mul(), p1,
     732             :                                             Int32Constant(k << l))),
     733       11692 :           Int32Constant(-1 << l)));
     734        2923 :       ASSERT_TRUE(r2.Changed());
     735       32153 :       EXPECT_THAT(r2.replacement(),
     736             :                   IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
     737           0 :                              IsInt32Mul(p1, IsInt32Constant(k << l))));
     738        3100 :     }
     739          31 :   }
     740             : }
     741             : 
     742             : 
     743       15129 : TEST_F(MachineOperatorReducerTest, Word32AndWithComparisonAndConstantOne) {
     744           1 :   Node* const p0 = Parameter(0);
     745           1 :   Node* const p1 = Parameter(1);
     746          97 :   TRACED_FOREACH(ComparisonBinaryOperator, cbop, kComparisonBinaryOperators) {
     747          32 :     Node* cmp = graph()->NewNode((machine()->*cbop.constructor)(), p0, p1);
     748             : 
     749             :     // cmp & 1 => cmp
     750             :     Reduction const r1 =
     751          32 :         Reduce(graph()->NewNode(machine()->Word32And(), cmp, Int32Constant(1)));
     752          16 :     ASSERT_TRUE(r1.Changed());
     753          32 :     EXPECT_EQ(cmp, r1.replacement());
     754             : 
     755             :     // 1 & cmp => cmp
     756             :     Reduction const r2 =
     757          32 :         Reduce(graph()->NewNode(machine()->Word32And(), Int32Constant(1), cmp));
     758          16 :     ASSERT_TRUE(r2.Changed());
     759          32 :     EXPECT_EQ(cmp, r2.replacement());
     760          16 :   }
     761             : }
     762             : 
     763             : 
     764             : // -----------------------------------------------------------------------------
     765             : // Word32Xor
     766             : 
     767             : 
     768       15129 : TEST_F(MachineOperatorReducerTest, Word32XorWithWord32XorAndMinusOne) {
     769           1 :   Node* const p0 = Parameter(0);
     770             : 
     771             :   // (x ^ -1) ^ -1 => x
     772             :   Reduction r1 = Reduce(graph()->NewNode(
     773             :       machine()->Word32Xor(),
     774             :       graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1)),
     775           3 :       Int32Constant(-1)));
     776           1 :   ASSERT_TRUE(r1.Changed());
     777           2 :   EXPECT_EQ(r1.replacement(), p0);
     778             : 
     779             :   // -1 ^ (x ^ -1) => x
     780             :   Reduction r2 = Reduce(graph()->NewNode(
     781             :       machine()->Word32Xor(), Int32Constant(-1),
     782           3 :       graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1))));
     783           1 :   ASSERT_TRUE(r2.Changed());
     784           2 :   EXPECT_EQ(r2.replacement(), p0);
     785             : 
     786             :   // (-1 ^ x) ^ -1 => x
     787             :   Reduction r3 = Reduce(graph()->NewNode(
     788             :       machine()->Word32Xor(),
     789             :       graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0),
     790           3 :       Int32Constant(-1)));
     791           1 :   ASSERT_TRUE(r3.Changed());
     792           2 :   EXPECT_EQ(r3.replacement(), p0);
     793             : 
     794             :   // -1 ^ (-1 ^ x) => x
     795             :   Reduction r4 = Reduce(graph()->NewNode(
     796             :       machine()->Word32Xor(), Int32Constant(-1),
     797           3 :       graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0)));
     798           1 :   ASSERT_TRUE(r4.Changed());
     799           2 :   EXPECT_EQ(r4.replacement(), p0);
     800             : }
     801             : 
     802             : 
     803             : // -----------------------------------------------------------------------------
     804             : // Word32Ror
     805             : 
     806             : 
     807       15129 : TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
     808           1 :   Node* value = Parameter(0);
     809           1 :   Node* shift = Parameter(1);
     810           1 :   Node* sub = graph()->NewNode(machine()->Int32Sub(), Int32Constant(32), shift);
     811             : 
     812             :   // Testing rotate left.
     813           1 :   Node* shl_l = graph()->NewNode(machine()->Word32Shl(), value, shift);
     814           1 :   Node* shr_l = graph()->NewNode(machine()->Word32Shr(), value, sub);
     815             : 
     816             :   // (x << y) | (x >>> (32 - y)) => x ror (32 - y)
     817           2 :   Node* node1 = graph()->NewNode(machine()->Word32Or(), shl_l, shr_l);
     818           1 :   Reduction reduction1 = Reduce(node1);
     819           1 :   EXPECT_TRUE(reduction1.Changed());
     820           2 :   EXPECT_EQ(reduction1.replacement(), node1);
     821           5 :   EXPECT_THAT(reduction1.replacement(), IsWord32Ror(value, sub));
     822             : 
     823             :   // (x >>> (32 - y)) | (x << y) => x ror (32 - y)
     824           2 :   Node* node2 = graph()->NewNode(machine()->Word32Or(), shr_l, shl_l);
     825           1 :   Reduction reduction2 = Reduce(node2);
     826           1 :   EXPECT_TRUE(reduction2.Changed());
     827           2 :   EXPECT_EQ(reduction2.replacement(), node2);
     828           5 :   EXPECT_THAT(reduction2.replacement(), IsWord32Ror(value, sub));
     829             : 
     830             :   // (x << y) ^ (x >>> (32 - y)) => x ror (32 - y)
     831           2 :   Node* node3 = graph()->NewNode(machine()->Word32Xor(), shl_l, shr_l);
     832           1 :   Reduction reduction3 = Reduce(node3);
     833           1 :   EXPECT_TRUE(reduction3.Changed());
     834           2 :   EXPECT_EQ(reduction3.replacement(), node3);
     835           5 :   EXPECT_THAT(reduction3.replacement(), IsWord32Ror(value, sub));
     836             : 
     837             :   // (x >>> (32 - y)) ^ (x << y) => x ror (32 - y)
     838           2 :   Node* node4 = graph()->NewNode(machine()->Word32Xor(), shr_l, shl_l);
     839           1 :   Reduction reduction4 = Reduce(node4);
     840           1 :   EXPECT_TRUE(reduction4.Changed());
     841           2 :   EXPECT_EQ(reduction4.replacement(), node4);
     842           5 :   EXPECT_THAT(reduction4.replacement(), IsWord32Ror(value, sub));
     843             : 
     844             :   // Testing rotate right.
     845           1 :   Node* shl_r = graph()->NewNode(machine()->Word32Shl(), value, sub);
     846           1 :   Node* shr_r = graph()->NewNode(machine()->Word32Shr(), value, shift);
     847             : 
     848             :   // (x << (32 - y)) | (x >>> y) => x ror y
     849           2 :   Node* node5 = graph()->NewNode(machine()->Word32Or(), shl_r, shr_r);
     850           1 :   Reduction reduction5 = Reduce(node5);
     851           1 :   EXPECT_TRUE(reduction5.Changed());
     852           2 :   EXPECT_EQ(reduction5.replacement(), node5);
     853           5 :   EXPECT_THAT(reduction5.replacement(), IsWord32Ror(value, shift));
     854             : 
     855             :   // (x >>> y) | (x << (32 - y)) => x ror y
     856           2 :   Node* node6 = graph()->NewNode(machine()->Word32Or(), shr_r, shl_r);
     857           1 :   Reduction reduction6 = Reduce(node6);
     858           1 :   EXPECT_TRUE(reduction6.Changed());
     859           2 :   EXPECT_EQ(reduction6.replacement(), node6);
     860           5 :   EXPECT_THAT(reduction6.replacement(), IsWord32Ror(value, shift));
     861             : 
     862             :   // (x << (32 - y)) ^ (x >>> y) => x ror y
     863           2 :   Node* node7 = graph()->NewNode(machine()->Word32Xor(), shl_r, shr_r);
     864           1 :   Reduction reduction7 = Reduce(node7);
     865           1 :   EXPECT_TRUE(reduction7.Changed());
     866           2 :   EXPECT_EQ(reduction7.replacement(), node7);
     867           5 :   EXPECT_THAT(reduction7.replacement(), IsWord32Ror(value, shift));
     868             : 
     869             :   // (x >>> y) ^ (x << (32 - y)) => x ror y
     870           2 :   Node* node8 = graph()->NewNode(machine()->Word32Xor(), shr_r, shl_r);
     871           1 :   Reduction reduction8 = Reduce(node8);
     872           1 :   EXPECT_TRUE(reduction8.Changed());
     873           2 :   EXPECT_EQ(reduction8.replacement(), node8);
     874           5 :   EXPECT_THAT(reduction8.replacement(), IsWord32Ror(value, shift));
     875           1 : }
     876             : 
     877       15129 : TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
     878           1 :   Node* value = Parameter(0);
     879         193 :   TRACED_FORRANGE(int32_t, k, 0, 31) {
     880             :     Node* shl =
     881          32 :         graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(k));
     882             :     Node* shr =
     883          32 :         graph()->NewNode(machine()->Word32Shr(), value, Int32Constant(32 - k));
     884             : 
     885             :     // (x << K) | (x >>> ((32 - K) - y)) => x ror (32 - K)
     886          64 :     Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
     887          32 :     Reduction reduction1 = Reduce(node1);
     888          32 :     EXPECT_TRUE(reduction1.Changed());
     889          64 :     EXPECT_EQ(reduction1.replacement(), node1);
     890         192 :     EXPECT_THAT(reduction1.replacement(),
     891           0 :                 IsWord32Ror(value, IsInt32Constant(32 - k)));
     892             : 
     893             :     // (x >>> (32 - K)) | (x << K) => x ror (32 - K)
     894          64 :     Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
     895          32 :     Reduction reduction2 = Reduce(node2);
     896          32 :     EXPECT_TRUE(reduction2.Changed());
     897          64 :     EXPECT_EQ(reduction2.replacement(), node2);
     898         192 :     EXPECT_THAT(reduction2.replacement(),
     899           0 :                 IsWord32Ror(value, IsInt32Constant(32 - k)));
     900          32 :   }
     901           1 : }
     902             : 
     903             : 
     904       15129 : TEST_F(MachineOperatorReducerTest, Word32RorWithZeroShift) {
     905           1 :   Node* value = Parameter(0);
     906             :   Node* node =
     907           1 :       graph()->NewNode(machine()->Word32Ror(), value, Int32Constant(0));
     908           1 :   Reduction reduction = Reduce(node);
     909           1 :   EXPECT_TRUE(reduction.Changed());
     910           2 :   EXPECT_EQ(reduction.replacement(), value);
     911           1 : }
     912             : 
     913             : 
     914       15129 : TEST_F(MachineOperatorReducerTest, Word32RorWithConstants) {
     915         289 :   TRACED_FOREACH(int32_t, x, kUint32Values) {
     916       10752 :     TRACED_FORRANGE(int32_t, y, 0, 31) {
     917             :       Node* node = graph()->NewNode(machine()->Word32Ror(), Int32Constant(x),
     918        1536 :                                     Int32Constant(y));
     919        1536 :       Reduction reduction = Reduce(node);
     920        1536 :       EXPECT_TRUE(reduction.Changed());
     921        7680 :       EXPECT_THAT(reduction.replacement(),
     922           0 :                   IsInt32Constant(base::bits::RotateRight32(x, y)));
     923        1536 :     }
     924          48 :   }
     925           1 : }
     926             : 
     927             : 
     928             : // -----------------------------------------------------------------------------
     929             : // Word32Sar
     930             : 
     931             : 
     932       15129 : TEST_F(MachineOperatorReducerTest, Word32SarWithWord32ShlAndComparison) {
     933           1 :   Node* const p0 = Parameter(0);
     934           1 :   Node* const p1 = Parameter(1);
     935             : 
     936          97 :   TRACED_FOREACH(ComparisonBinaryOperator, cbop, kComparisonBinaryOperators) {
     937          16 :     Node* cmp = graph()->NewNode((machine()->*cbop.constructor)(), p0, p1);
     938             : 
     939             :     // cmp << 31 >> 31 => 0 - cmp
     940             :     Reduction const r = Reduce(graph()->NewNode(
     941             :         machine()->Word32Sar(),
     942             :         graph()->NewNode(machine()->Word32Shl(), cmp, Int32Constant(31)),
     943          48 :         Int32Constant(31)));
     944          17 :     ASSERT_TRUE(r.Changed());
     945          96 :     EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0), cmp));
     946          16 :   }
     947             : }
     948             : 
     949             : 
     950       15129 : TEST_F(MachineOperatorReducerTest, Word32SarWithWord32ShlAndLoad) {
     951           1 :   Node* const p0 = Parameter(0);
     952           1 :   Node* const p1 = Parameter(1);
     953             :   {
     954             :     Node* const l = graph()->NewNode(machine()->Load(MachineType::Int8()), p0,
     955           2 :                                      p1, graph()->start(), graph()->start());
     956             :     Reduction const r = Reduce(graph()->NewNode(
     957             :         machine()->Word32Sar(),
     958             :         graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(24)),
     959           3 :         Int32Constant(24)));
     960           1 :     ASSERT_TRUE(r.Changed());
     961           2 :     EXPECT_EQ(l, r.replacement());
     962             :   }
     963             :   {
     964             :     Node* const l = graph()->NewNode(machine()->Load(MachineType::Int16()), p0,
     965           2 :                                      p1, graph()->start(), graph()->start());
     966             :     Reduction const r = Reduce(graph()->NewNode(
     967             :         machine()->Word32Sar(),
     968             :         graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(16)),
     969           3 :         Int32Constant(16)));
     970           1 :     ASSERT_TRUE(r.Changed());
     971           2 :     EXPECT_EQ(l, r.replacement());
     972             :   }
     973             : }
     974             : 
     975             : 
     976             : // -----------------------------------------------------------------------------
     977             : // Word32Shr
     978             : 
     979       15129 : TEST_F(MachineOperatorReducerTest, Word32ShrWithWord32And) {
     980           1 :   Node* const p0 = Parameter(0);
     981         187 :   TRACED_FORRANGE(int32_t, shift, 1, 31) {
     982             :     uint32_t mask =
     983             :         base::SubWithWraparound(base::ShlWithWraparound(1, shift), 1);
     984             :     Node* node = graph()->NewNode(
     985             :         machine()->Word32Shr(),
     986             :         graph()->NewNode(machine()->Word32And(), p0, Int32Constant(mask)),
     987          62 :         Int32Constant(shift));
     988          31 :     Reduction r = Reduce(node);
     989          32 :     ASSERT_TRUE(r.Changed());
     990         124 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
     991          31 :   }
     992             : }
     993             : 
     994             : // -----------------------------------------------------------------------------
     995             : // Word32Shl
     996             : 
     997       15129 : TEST_F(MachineOperatorReducerTest, Word32ShlWithZeroShift) {
     998           1 :   Node* p0 = Parameter(0);
     999           1 :   Node* node = graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(0));
    1000           1 :   Reduction r = Reduce(node);
    1001           2 :   ASSERT_TRUE(r.Changed());
    1002           2 :   EXPECT_EQ(p0, r.replacement());
    1003             : }
    1004             : 
    1005             : 
    1006       15129 : TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Sar) {
    1007           1 :   Node* p0 = Parameter(0);
    1008         187 :   TRACED_FORRANGE(int32_t, x, 1, 31) {
    1009             :     Node* node = graph()->NewNode(
    1010             :         machine()->Word32Shl(),
    1011             :         graph()->NewNode(machine()->Word32Sar(), p0, Int32Constant(x)),
    1012          62 :         Int32Constant(x));
    1013          31 :     Reduction r = Reduce(node);
    1014          32 :     ASSERT_TRUE(r.Changed());
    1015          31 :     int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
    1016         186 :     EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
    1017          31 :   }
    1018             : }
    1019             : 
    1020             : 
    1021       15129 : TEST_F(MachineOperatorReducerTest,
    1022             :        Word32ShlWithWord32SarAndInt32AddAndConstant) {
    1023           1 :   Node* const p0 = Parameter(0);
    1024         601 :   TRACED_FOREACH(int32_t, k, kInt32Values) {
    1025       21700 :     TRACED_FORRANGE(int32_t, l, 1, 31) {
    1026        3100 :       if ((k << l) == 0) continue;
    1027             :       // (x + (K << L)) >> L << L => (x & (-1 << L)) + (K << L)
    1028             :       Reduction const r = Reduce(graph()->NewNode(
    1029             :           machine()->Word32Shl(),
    1030             :           graph()->NewNode(machine()->Word32Sar(),
    1031             :                            graph()->NewNode(machine()->Int32Add(), p0,
    1032             :                                             Int32Constant(k << l)),
    1033             :                            Int32Constant(l)),
    1034       11692 :           Int32Constant(l)));
    1035        2924 :       ASSERT_TRUE(r.Changed());
    1036       26307 :       EXPECT_THAT(r.replacement(),
    1037             :                   IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
    1038           0 :                              IsInt32Constant(k << l)));
    1039        3100 :     }
    1040         100 :   }
    1041             : }
    1042             : 
    1043             : 
    1044       15129 : TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Shr) {
    1045           1 :   Node* p0 = Parameter(0);
    1046         187 :   TRACED_FORRANGE(int32_t, x, 1, 31) {
    1047             :     Node* node = graph()->NewNode(
    1048             :         machine()->Word32Shl(),
    1049             :         graph()->NewNode(machine()->Word32Shr(), p0, Int32Constant(x)),
    1050          62 :         Int32Constant(x));
    1051          31 :     Reduction r = Reduce(node);
    1052          32 :     ASSERT_TRUE(r.Changed());
    1053          31 :     int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
    1054         186 :     EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
    1055          31 :   }
    1056             : }
    1057             : 
    1058             : 
    1059             : // -----------------------------------------------------------------------------
    1060             : // Int32Sub
    1061             : 
    1062             : 
    1063       15129 : TEST_F(MachineOperatorReducerTest, Int32SubWithConstant) {
    1064           1 :   Node* const p0 = Parameter(0);
    1065         601 :   TRACED_FOREACH(int32_t, k, kInt32Values) {
    1066             :     Reduction const r =
    1067         200 :         Reduce(graph()->NewNode(machine()->Int32Sub(), p0, Int32Constant(k)));
    1068         101 :     ASSERT_TRUE(r.Changed());
    1069         100 :     if (k == 0) {
    1070           2 :       EXPECT_EQ(p0, r.replacement());
    1071             :     } else {
    1072         693 :       EXPECT_THAT(
    1073             :           r.replacement(),
    1074           0 :           IsInt32Add(p0, IsInt32Constant(base::NegateWithWraparound(k))));
    1075             :     }
    1076         100 :   }
    1077             : }
    1078             : 
    1079             : 
    1080             : // -----------------------------------------------------------------------------
    1081             : // Int32Div
    1082             : 
    1083             : 
    1084       15129 : TEST_F(MachineOperatorReducerTest, Int32DivWithConstant) {
    1085           1 :   Node* const p0 = Parameter(0);
    1086             :   {
    1087             :     Reduction const r = Reduce(graph()->NewNode(
    1088           2 :         machine()->Int32Div(), p0, Int32Constant(0), graph()->start()));
    1089           1 :     ASSERT_TRUE(r.Changed());
    1090           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1091             :   }
    1092             :   {
    1093             :     Reduction const r = Reduce(graph()->NewNode(
    1094           2 :         machine()->Int32Div(), p0, Int32Constant(1), graph()->start()));
    1095           1 :     ASSERT_TRUE(r.Changed());
    1096           2 :     EXPECT_EQ(r.replacement(), p0);
    1097             :   }
    1098             :   {
    1099             :     Reduction const r = Reduce(graph()->NewNode(
    1100           2 :         machine()->Int32Div(), p0, Int32Constant(-1), graph()->start()));
    1101           1 :     ASSERT_TRUE(r.Changed());
    1102           6 :     EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0), p0));
    1103             :   }
    1104             :   {
    1105             :     Reduction const r = Reduce(graph()->NewNode(
    1106           2 :         machine()->Int32Div(), p0, Int32Constant(2), graph()->start()));
    1107           1 :     ASSERT_TRUE(r.Changed());
    1108          11 :     EXPECT_THAT(
    1109             :         r.replacement(),
    1110             :         IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
    1111           0 :                     IsInt32Constant(1)));
    1112             :   }
    1113             :   {
    1114             :     Reduction const r = Reduce(graph()->NewNode(
    1115           2 :         machine()->Int32Div(), p0, Int32Constant(-2), graph()->start()));
    1116           1 :     ASSERT_TRUE(r.Changed());
    1117          14 :     EXPECT_THAT(
    1118             :         r.replacement(),
    1119             :         IsInt32Sub(
    1120             :             IsInt32Constant(0),
    1121             :             IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
    1122           0 :                         IsInt32Constant(1))));
    1123             :   }
    1124         175 :   TRACED_FORRANGE(int32_t, shift, 2, 30) {
    1125             :     Reduction const r =
    1126             :         Reduce(graph()->NewNode(machine()->Int32Div(), p0,
    1127          58 :                                 Int32Constant(1 << shift), graph()->start()));
    1128          29 :     ASSERT_TRUE(r.Changed());
    1129         406 :     EXPECT_THAT(
    1130             :         r.replacement(),
    1131             :         IsWord32Sar(IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
    1132             :                                            IsInt32Constant(32 - shift)),
    1133             :                                p0),
    1134           0 :                     IsInt32Constant(shift)));
    1135          29 :   }
    1136         210 :   TRACED_FORRANGE(int32_t, shift, 2, 31) {
    1137             :     Reduction const r = Reduce(graph()->NewNode(
    1138             :         machine()->Int32Div(), p0,
    1139             :         Uint32Constant(bit_cast<uint32_t, int32_t>(-1) << shift),
    1140          90 :         graph()->start()));
    1141          30 :     ASSERT_TRUE(r.Changed());
    1142         510 :     EXPECT_THAT(
    1143             :         r.replacement(),
    1144             :         IsInt32Sub(
    1145             :             IsInt32Constant(0),
    1146             :             IsWord32Sar(
    1147             :                 IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
    1148             :                                        IsInt32Constant(32 - shift)),
    1149             :                            p0),
    1150           0 :                 IsInt32Constant(shift))));
    1151          30 :   }
    1152         700 :   TRACED_FOREACH(int32_t, divisor, kInt32Values) {
    1153         100 :     if (divisor < 0) {
    1154          97 :       if (divisor == kMinInt || base::bits::IsPowerOfTwo(-divisor)) continue;
    1155             :       Reduction const r = Reduce(graph()->NewNode(
    1156          96 :           machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
    1157          48 :       ASSERT_TRUE(r.Changed());
    1158         336 :       EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0),
    1159           0 :                                               IsTruncatingDiv(p0, -divisor)));
    1160          51 :     } else if (divisor > 0) {
    1161          50 :       if (base::bits::IsPowerOfTwo(divisor)) continue;
    1162             :       Reduction const r = Reduce(graph()->NewNode(
    1163          98 :           machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
    1164          49 :       ASSERT_TRUE(r.Changed());
    1165         196 :       EXPECT_THAT(r.replacement(), IsTruncatingDiv(p0, divisor));
    1166             :     }
    1167         100 :   }
    1168             : }
    1169             : 
    1170             : 
    1171       15129 : TEST_F(MachineOperatorReducerTest, Int32DivWithParameters) {
    1172           1 :   Node* const p0 = Parameter(0);
    1173             :   Reduction const r =
    1174           2 :       Reduce(graph()->NewNode(machine()->Int32Div(), p0, p0, graph()->start()));
    1175           2 :   ASSERT_TRUE(r.Changed());
    1176           9 :   EXPECT_THAT(
    1177             :       r.replacement(),
    1178           0 :       IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
    1179             : }
    1180             : 
    1181             : 
    1182             : // -----------------------------------------------------------------------------
    1183             : // Uint32Div
    1184             : 
    1185             : 
    1186       15129 : TEST_F(MachineOperatorReducerTest, Uint32DivWithConstant) {
    1187           1 :   Node* const p0 = Parameter(0);
    1188             :   {
    1189             :     Reduction const r = Reduce(graph()->NewNode(
    1190           2 :         machine()->Uint32Div(), Int32Constant(0), p0, graph()->start()));
    1191           1 :     ASSERT_TRUE(r.Changed());
    1192           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1193             :   }
    1194             :   {
    1195             :     Reduction const r = Reduce(graph()->NewNode(
    1196           2 :         machine()->Uint32Div(), p0, Int32Constant(0), graph()->start()));
    1197           1 :     ASSERT_TRUE(r.Changed());
    1198           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1199             :   }
    1200             :   {
    1201             :     Reduction const r = Reduce(graph()->NewNode(
    1202           2 :         machine()->Uint32Div(), p0, Int32Constant(1), graph()->start()));
    1203           1 :     ASSERT_TRUE(r.Changed());
    1204           2 :     EXPECT_EQ(r.replacement(), p0);
    1205             :   }
    1206         289 :   TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
    1207       16128 :     TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
    1208             :       Reduction const r = Reduce(
    1209             :           graph()->NewNode(machine()->Uint32Div(), Uint32Constant(dividend),
    1210        6912 :                            Uint32Constant(divisor), graph()->start()));
    1211        2304 :       ASSERT_TRUE(r.Changed());
    1212       11520 :       EXPECT_THAT(r.replacement(),
    1213             :                   IsInt32Constant(bit_cast<int32_t>(
    1214           0 :                       base::bits::UnsignedDiv32(dividend, divisor))));
    1215        2304 :     }
    1216          48 :   }
    1217         217 :   TRACED_FORRANGE(uint32_t, shift, 1, 31) {
    1218             :     Reduction const r =
    1219             :         Reduce(graph()->NewNode(machine()->Uint32Div(), p0,
    1220          93 :                                 Uint32Constant(1u << shift), graph()->start()));
    1221          31 :     ASSERT_TRUE(r.Changed());
    1222         186 :     EXPECT_THAT(r.replacement(),
    1223           0 :                 IsWord32Shr(p0, IsInt32Constant(bit_cast<int32_t>(shift))));
    1224          31 :   }
    1225             : }
    1226             : 
    1227             : 
    1228       15129 : TEST_F(MachineOperatorReducerTest, Uint32DivWithParameters) {
    1229           1 :   Node* const p0 = Parameter(0);
    1230             :   Reduction const r = Reduce(
    1231           2 :       graph()->NewNode(machine()->Uint32Div(), p0, p0, graph()->start()));
    1232           2 :   ASSERT_TRUE(r.Changed());
    1233           9 :   EXPECT_THAT(
    1234             :       r.replacement(),
    1235           0 :       IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
    1236             : }
    1237             : 
    1238             : 
    1239             : // -----------------------------------------------------------------------------
    1240             : // Int32Mod
    1241             : 
    1242             : 
    1243       15129 : TEST_F(MachineOperatorReducerTest, Int32ModWithConstant) {
    1244           1 :   Node* const p0 = Parameter(0);
    1245             :   {
    1246             :     Reduction const r = Reduce(graph()->NewNode(
    1247           2 :         machine()->Int32Mod(), Int32Constant(0), p0, graph()->start()));
    1248           1 :     ASSERT_TRUE(r.Changed());
    1249           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1250             :   }
    1251             :   {
    1252             :     Reduction const r = Reduce(graph()->NewNode(
    1253           2 :         machine()->Int32Mod(), p0, Int32Constant(0), graph()->start()));
    1254           1 :     ASSERT_TRUE(r.Changed());
    1255           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1256             :   }
    1257             :   {
    1258             :     Reduction const r = Reduce(graph()->NewNode(
    1259           2 :         machine()->Int32Mod(), p0, Int32Constant(1), graph()->start()));
    1260           1 :     ASSERT_TRUE(r.Changed());
    1261           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1262             :   }
    1263             :   {
    1264             :     Reduction const r = Reduce(graph()->NewNode(
    1265           2 :         machine()->Int32Mod(), p0, Int32Constant(-1), graph()->start()));
    1266           1 :     ASSERT_TRUE(r.Changed());
    1267           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1268             :   }
    1269         601 :   TRACED_FOREACH(int32_t, dividend, kInt32Values) {
    1270       70000 :     TRACED_FOREACH(int32_t, divisor, kInt32Values) {
    1271             :       Reduction const r = Reduce(
    1272             :           graph()->NewNode(machine()->Int32Mod(), Int32Constant(dividend),
    1273       20000 :                            Int32Constant(divisor), graph()->start()));
    1274       10000 :       ASSERT_TRUE(r.Changed());
    1275       40000 :       EXPECT_THAT(r.replacement(),
    1276           0 :                   IsInt32Constant(base::bits::SignedMod32(dividend, divisor)));
    1277       10000 :     }
    1278         100 :   }
    1279         210 :   TRACED_FORRANGE(int32_t, shift, 1, 30) {
    1280             :     Reduction const r =
    1281             :         Reduce(graph()->NewNode(machine()->Int32Mod(), p0,
    1282          60 :                                 Int32Constant(1 << shift), graph()->start()));
    1283          30 :     int32_t const mask = (1 << shift) - 1;
    1284          30 :     ASSERT_TRUE(r.Changed());
    1285         990 :     EXPECT_THAT(
    1286             :         r.replacement(),
    1287             :         IsPhi(
    1288             :             MachineRepresentation::kWord32,
    1289             :             IsInt32Sub(IsInt32Constant(0),
    1290             :                        IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
    1291             :                                    IsInt32Constant(mask))),
    1292             :             IsWord32And(p0, IsInt32Constant(mask)),
    1293             :             IsMerge(IsIfTrue(IsBranch(IsInt32LessThan(p0, IsInt32Constant(0)),
    1294             :                                       graph()->start())),
    1295             :                     IsIfFalse(IsBranch(IsInt32LessThan(p0, IsInt32Constant(0)),
    1296           0 :                                        graph()->start())))));
    1297          30 :   }
    1298         217 :   TRACED_FORRANGE(int32_t, shift, 1, 31) {
    1299             :     Reduction const r = Reduce(graph()->NewNode(
    1300             :         machine()->Int32Mod(), p0,
    1301             :         Uint32Constant(bit_cast<uint32_t, int32_t>(-1) << shift),
    1302          93 :         graph()->start()));
    1303          31 :     int32_t const mask = bit_cast<int32_t, uint32_t>((1U << shift) - 1);
    1304          31 :     ASSERT_TRUE(r.Changed());
    1305        1023 :     EXPECT_THAT(
    1306             :         r.replacement(),
    1307             :         IsPhi(
    1308             :             MachineRepresentation::kWord32,
    1309             :             IsInt32Sub(IsInt32Constant(0),
    1310             :                        IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
    1311             :                                    IsInt32Constant(mask))),
    1312             :             IsWord32And(p0, IsInt32Constant(mask)),
    1313             :             IsMerge(IsIfTrue(IsBranch(IsInt32LessThan(p0, IsInt32Constant(0)),
    1314             :                                       graph()->start())),
    1315             :                     IsIfFalse(IsBranch(IsInt32LessThan(p0, IsInt32Constant(0)),
    1316           0 :                                        graph()->start())))));
    1317          31 :   }
    1318         700 :   TRACED_FOREACH(int32_t, divisor, kInt32Values) {
    1319         199 :     if (divisor == 0 || base::bits::IsPowerOfTwo(Abs(divisor))) continue;
    1320             :     Reduction const r = Reduce(graph()->NewNode(
    1321         194 :         machine()->Int32Mod(), p0, Int32Constant(divisor), graph()->start()));
    1322          97 :     ASSERT_TRUE(r.Changed());
    1323         970 :     EXPECT_THAT(r.replacement(),
    1324             :                 IsInt32Sub(p0, IsInt32Mul(IsTruncatingDiv(p0, Abs(divisor)),
    1325           0 :                                           IsInt32Constant(Abs(divisor)))));
    1326         100 :   }
    1327             : }
    1328             : 
    1329             : 
    1330       15129 : TEST_F(MachineOperatorReducerTest, Int32ModWithParameters) {
    1331           1 :   Node* const p0 = Parameter(0);
    1332             :   Reduction const r =
    1333           2 :       Reduce(graph()->NewNode(machine()->Int32Mod(), p0, p0, graph()->start()));
    1334           2 :   ASSERT_TRUE(r.Changed());
    1335           4 :   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1336             : }
    1337             : 
    1338             : 
    1339             : // -----------------------------------------------------------------------------
    1340             : // Uint32Mod
    1341             : 
    1342             : 
    1343       15129 : TEST_F(MachineOperatorReducerTest, Uint32ModWithConstant) {
    1344           1 :   Node* const p0 = Parameter(0);
    1345             :   {
    1346             :     Reduction const r = Reduce(graph()->NewNode(
    1347           2 :         machine()->Uint32Mod(), p0, Int32Constant(0), graph()->start()));
    1348           1 :     ASSERT_TRUE(r.Changed());
    1349           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1350             :   }
    1351             :   {
    1352             :     Reduction const r = Reduce(graph()->NewNode(
    1353           2 :         machine()->Uint32Mod(), Int32Constant(0), p0, graph()->start()));
    1354           1 :     ASSERT_TRUE(r.Changed());
    1355           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1356             :   }
    1357             :   {
    1358             :     Reduction const r = Reduce(graph()->NewNode(
    1359           2 :         machine()->Uint32Mod(), p0, Int32Constant(1), graph()->start()));
    1360           1 :     ASSERT_TRUE(r.Changed());
    1361           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1362             :   }
    1363         289 :   TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
    1364       16128 :     TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
    1365             :       Reduction const r = Reduce(
    1366             :           graph()->NewNode(machine()->Uint32Mod(), Uint32Constant(dividend),
    1367        6912 :                            Uint32Constant(divisor), graph()->start()));
    1368        2304 :       ASSERT_TRUE(r.Changed());
    1369       11520 :       EXPECT_THAT(r.replacement(),
    1370             :                   IsInt32Constant(bit_cast<int32_t>(
    1371           0 :                       base::bits::UnsignedMod32(dividend, divisor))));
    1372        2304 :     }
    1373          48 :   }
    1374         217 :   TRACED_FORRANGE(uint32_t, shift, 1, 31) {
    1375             :     Reduction const r =
    1376             :         Reduce(graph()->NewNode(machine()->Uint32Mod(), p0,
    1377          93 :                                 Uint32Constant(1u << shift), graph()->start()));
    1378          31 :     ASSERT_TRUE(r.Changed());
    1379         217 :     EXPECT_THAT(r.replacement(),
    1380             :                 IsWord32And(p0, IsInt32Constant(
    1381           0 :                                     bit_cast<int32_t>((1u << shift) - 1u))));
    1382          31 :   }
    1383             : }
    1384             : 
    1385             : 
    1386       15129 : TEST_F(MachineOperatorReducerTest, Uint32ModWithParameters) {
    1387           1 :   Node* const p0 = Parameter(0);
    1388             :   Reduction const r = Reduce(
    1389           2 :       graph()->NewNode(machine()->Uint32Mod(), p0, p0, graph()->start()));
    1390           2 :   ASSERT_TRUE(r.Changed());
    1391           4 :   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1392             : }
    1393             : 
    1394             : 
    1395             : // -----------------------------------------------------------------------------
    1396             : // Int32Add
    1397             : 
    1398             : 
    1399       15129 : TEST_F(MachineOperatorReducerTest, Int32AddWithInt32SubWithConstantZero) {
    1400           1 :   Node* const p0 = Parameter(0);
    1401           1 :   Node* const p1 = Parameter(1);
    1402             : 
    1403             :   Reduction const r1 = Reduce(graph()->NewNode(
    1404             :       machine()->Int32Add(),
    1405           3 :       graph()->NewNode(machine()->Int32Sub(), Int32Constant(0), p0), p1));
    1406           1 :   ASSERT_TRUE(r1.Changed());
    1407           5 :   EXPECT_THAT(r1.replacement(), IsInt32Sub(p1, p0));
    1408             : 
    1409             :   Reduction const r2 = Reduce(graph()->NewNode(
    1410             :       machine()->Int32Add(), p0,
    1411           3 :       graph()->NewNode(machine()->Int32Sub(), Int32Constant(0), p1)));
    1412           1 :   ASSERT_TRUE(r2.Changed());
    1413           5 :   EXPECT_THAT(r2.replacement(), IsInt32Sub(p0, p1));
    1414             : }
    1415             : 
    1416             : 
    1417             : // -----------------------------------------------------------------------------
    1418             : // Int32AddWithOverflow
    1419             : 
    1420             : 
    1421       15129 : TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
    1422           1 :   Node* control = graph()->start();
    1423           1 :   Node* p0 = Parameter(0);
    1424             :   {
    1425             :     Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
    1426           1 :                                  Int32Constant(0), p0, control);
    1427             : 
    1428             :     Reduction r =
    1429           2 :         Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1430           1 :     ASSERT_TRUE(r.Changed());
    1431           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1432             : 
    1433           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1434           1 :     ASSERT_TRUE(r.Changed());
    1435           2 :     EXPECT_EQ(p0, r.replacement());
    1436             :   }
    1437             :   {
    1438             :     Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
    1439           1 :                                  Int32Constant(0), control);
    1440             : 
    1441             :     Reduction r =
    1442           2 :         Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1443           1 :     ASSERT_TRUE(r.Changed());
    1444           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1445             : 
    1446           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1447           1 :     ASSERT_TRUE(r.Changed());
    1448           2 :     EXPECT_EQ(p0, r.replacement());
    1449             :   }
    1450             : }
    1451             : 
    1452             : 
    1453       15129 : TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
    1454           1 :   Node* control = graph()->start();
    1455         601 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
    1456       70000 :     TRACED_FOREACH(int32_t, y, kInt32Values) {
    1457             :       int32_t z;
    1458             :       Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
    1459       10000 :                                    Int32Constant(x), Int32Constant(y), control);
    1460             : 
    1461             :       Reduction r =
    1462       20000 :           Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1463       10000 :       ASSERT_TRUE(r.Changed());
    1464       50000 :       EXPECT_THAT(r.replacement(),
    1465           0 :                   IsInt32Constant(base::bits::SignedAddOverflow32(x, y, &z)));
    1466             : 
    1467       20000 :       r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1468       10000 :       ASSERT_TRUE(r.Changed());
    1469       40000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
    1470       10000 :     }
    1471         100 :   }
    1472             : }
    1473             : 
    1474             : 
    1475             : // -----------------------------------------------------------------------------
    1476             : // Int32SubWithOverflow
    1477             : 
    1478             : 
    1479       15129 : TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
    1480           1 :   Node* control = graph()->start();
    1481           1 :   Node* p0 = Parameter(0);
    1482             :   Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(), p0,
    1483           1 :                                Int32Constant(0), control);
    1484             : 
    1485           2 :   Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1486           1 :   ASSERT_TRUE(r.Changed());
    1487           4 :   EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1488             : 
    1489           2 :   r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1490           1 :   ASSERT_TRUE(r.Changed());
    1491           2 :   EXPECT_EQ(p0, r.replacement());
    1492             : }
    1493             : 
    1494             : 
    1495       15129 : TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
    1496           1 :   Node* control = graph()->start();
    1497         601 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
    1498       70000 :     TRACED_FOREACH(int32_t, y, kInt32Values) {
    1499             :       int32_t z;
    1500             :       Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
    1501       10000 :                                    Int32Constant(x), Int32Constant(y), control);
    1502             : 
    1503             :       Reduction r =
    1504       20000 :           Reduce(graph()->NewNode(common()->Projection(1), add, control));
    1505       10000 :       ASSERT_TRUE(r.Changed());
    1506       50000 :       EXPECT_THAT(r.replacement(),
    1507           0 :                   IsInt32Constant(base::bits::SignedSubOverflow32(x, y, &z)));
    1508             : 
    1509       20000 :       r = Reduce(graph()->NewNode(common()->Projection(0), add, control));
    1510       10000 :       ASSERT_TRUE(r.Changed());
    1511       40000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
    1512       10000 :     }
    1513         100 :   }
    1514             : }
    1515             : 
    1516             : 
    1517             : // -----------------------------------------------------------------------------
    1518             : // Int32MulWithOverflow
    1519             : 
    1520       15129 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithZero) {
    1521           1 :   Node* control = graph()->start();
    1522           1 :   Node* p0 = Parameter(0);
    1523             :   {
    1524             :     Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(),
    1525           1 :                                  Int32Constant(0), p0, control);
    1526             : 
    1527             :     Reduction r =
    1528           2 :         Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1529           1 :     ASSERT_TRUE(r.Changed());
    1530           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1531             : 
    1532           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1533           1 :     ASSERT_TRUE(r.Changed());
    1534           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1535             :   }
    1536             :   {
    1537             :     Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(), p0,
    1538           1 :                                  Int32Constant(0), control);
    1539             : 
    1540             :     Reduction r =
    1541           2 :         Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1542           1 :     ASSERT_TRUE(r.Changed());
    1543           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1544             : 
    1545           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1546           1 :     ASSERT_TRUE(r.Changed());
    1547           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1548             :   }
    1549             : }
    1550             : 
    1551       15129 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithOne) {
    1552           1 :   Node* control = graph()->start();
    1553           1 :   Node* p0 = Parameter(0);
    1554             :   {
    1555             :     Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(),
    1556           1 :                                  Int32Constant(1), p0, control);
    1557             : 
    1558             :     Reduction r =
    1559           2 :         Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1560           1 :     ASSERT_TRUE(r.Changed());
    1561           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1562             : 
    1563           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1564           1 :     ASSERT_TRUE(r.Changed());
    1565           2 :     EXPECT_EQ(p0, r.replacement());
    1566             :   }
    1567             :   {
    1568             :     Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(), p0,
    1569           1 :                                  Int32Constant(1), control);
    1570             : 
    1571             :     Reduction r =
    1572           2 :         Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1573           1 :     ASSERT_TRUE(r.Changed());
    1574           4 :     EXPECT_THAT(r.replacement(), IsInt32Constant(0));
    1575             : 
    1576           2 :     r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1577           1 :     ASSERT_TRUE(r.Changed());
    1578           2 :     EXPECT_EQ(p0, r.replacement());
    1579             :   }
    1580             : }
    1581             : 
    1582       15129 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithMinusOne) {
    1583           1 :   Node* control = graph()->start();
    1584           1 :   Node* p0 = Parameter(0);
    1585             : 
    1586             :   {
    1587             :     Reduction r = Reduce(graph()->NewNode(machine()->Int32MulWithOverflow(),
    1588           2 :                                           Int32Constant(-1), p0, control));
    1589           1 :     ASSERT_TRUE(r.Changed());
    1590           6 :     EXPECT_THAT(r.replacement(),
    1591           0 :                 IsInt32SubWithOverflow(IsInt32Constant(0), p0));
    1592             :   }
    1593             : 
    1594             :   {
    1595             :     Reduction r = Reduce(graph()->NewNode(machine()->Int32MulWithOverflow(), p0,
    1596           2 :                                           Int32Constant(-1), control));
    1597           1 :     ASSERT_TRUE(r.Changed());
    1598           6 :     EXPECT_THAT(r.replacement(),
    1599           0 :                 IsInt32SubWithOverflow(IsInt32Constant(0), p0));
    1600             :   }
    1601             : }
    1602             : 
    1603       15129 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithTwo) {
    1604           1 :   Node* control = graph()->start();
    1605           1 :   Node* p0 = Parameter(0);
    1606             : 
    1607             :   {
    1608             :     Reduction r = Reduce(graph()->NewNode(machine()->Int32MulWithOverflow(),
    1609           2 :                                           Int32Constant(2), p0, control));
    1610           1 :     ASSERT_TRUE(r.Changed());
    1611           5 :     EXPECT_THAT(r.replacement(), IsInt32AddWithOverflow(p0, p0));
    1612             :   }
    1613             : 
    1614             :   {
    1615             :     Reduction r = Reduce(graph()->NewNode(machine()->Int32MulWithOverflow(), p0,
    1616           2 :                                           Int32Constant(2), control));
    1617           1 :     ASSERT_TRUE(r.Changed());
    1618           5 :     EXPECT_THAT(r.replacement(), IsInt32AddWithOverflow(p0, p0));
    1619             :   }
    1620             : }
    1621             : 
    1622       15129 : TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithConstant) {
    1623           1 :   Node* control = graph()->start();
    1624         601 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
    1625       70000 :     TRACED_FOREACH(int32_t, y, kInt32Values) {
    1626             :       int32_t z;
    1627             :       Node* mul = graph()->NewNode(machine()->Int32MulWithOverflow(),
    1628       10000 :                                    Int32Constant(x), Int32Constant(y), control);
    1629             : 
    1630             :       Reduction r =
    1631       20000 :           Reduce(graph()->NewNode(common()->Projection(1), mul, control));
    1632       10000 :       ASSERT_TRUE(r.Changed());
    1633       40000 :       EXPECT_THAT(r.replacement(),
    1634           0 :                   IsInt32Constant(base::bits::SignedMulOverflow32(x, y, &z)));
    1635             : 
    1636       20000 :       r = Reduce(graph()->NewNode(common()->Projection(0), mul, control));
    1637       10000 :       ASSERT_TRUE(r.Changed());
    1638       40000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(z));
    1639       10000 :     }
    1640         100 :   }
    1641             : }
    1642             : 
    1643             : // -----------------------------------------------------------------------------
    1644             : // Int32LessThan
    1645             : 
    1646       15129 : TEST_F(MachineOperatorReducerTest, Int32LessThanWithWord32Or) {
    1647           1 :   Node* const p0 = Parameter(0);
    1648         601 :   TRACED_FOREACH(int32_t, x, kInt32Values) {
    1649             :     Node* word32_or =
    1650         100 :         graph()->NewNode(machine()->Word32Or(), p0, Int32Constant(x));
    1651             :     Node* less_than = graph()->NewNode(machine()->Int32LessThan(), word32_or,
    1652         100 :                                        Int32Constant(0));
    1653         100 :     Reduction r = Reduce(less_than);
    1654         100 :     if (x < 0) {
    1655          49 :       ASSERT_TRUE(r.Changed());
    1656         196 :       EXPECT_THAT(r.replacement(), IsInt32Constant(1));
    1657             :     } else {
    1658         102 :       ASSERT_FALSE(r.Changed());
    1659             :     }
    1660         100 :   }
    1661             : }
    1662             : 
    1663             : // -----------------------------------------------------------------------------
    1664             : // Uint32LessThan
    1665             : 
    1666       15129 : TEST_F(MachineOperatorReducerTest, Uint32LessThanWithWord32Sar) {
    1667           1 :   Node* const p0 = Parameter(0);
    1668          19 :   TRACED_FORRANGE(uint32_t, shift, 1, 3) {
    1669           3 :     const uint32_t limit = (kMaxInt >> shift) - 1;
    1670             :     Node* const node = graph()->NewNode(
    1671             :         machine()->Uint32LessThan(),
    1672             :         graph()->NewNode(machine()->Word32Sar(), p0, Uint32Constant(shift)),
    1673           6 :         Uint32Constant(limit));
    1674             : 
    1675           3 :     Reduction r = Reduce(node);
    1676           4 :     ASSERT_TRUE(r.Changed());
    1677          21 :     EXPECT_THAT(r.replacement(),
    1678             :                 IsUint32LessThan(
    1679           0 :                     p0, IsInt32Constant(bit_cast<int32_t>(limit << shift))));
    1680           3 :   }
    1681             : }
    1682             : 
    1683             : 
    1684             : // -----------------------------------------------------------------------------
    1685             : // Float64Mul
    1686             : 
    1687             : 
    1688       15129 : TEST_F(MachineOperatorReducerTest, Float64MulWithMinusOne) {
    1689           1 :   Node* const p0 = Parameter(0);
    1690             :   {
    1691             :     Reduction r = Reduce(
    1692           2 :         graph()->NewNode(machine()->Float64Mul(), p0, Float64Constant(-1.0)));
    1693           1 :     ASSERT_TRUE(r.Changed());
    1694           6 :     EXPECT_THAT(r.replacement(),
    1695           0 :                 IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
    1696             :   }
    1697             :   {
    1698             :     Reduction r = Reduce(
    1699           2 :         graph()->NewNode(machine()->Float64Mul(), Float64Constant(-1.0), p0));
    1700           1 :     ASSERT_TRUE(r.Changed());
    1701           6 :     EXPECT_THAT(r.replacement(),
    1702           0 :                 IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
    1703             :   }
    1704             : }
    1705             : 
    1706       15129 : TEST_F(MachineOperatorReducerTest, Float64SubMinusZeroMinusX) {
    1707           1 :   Node* const p0 = Parameter(0);
    1708             :   {
    1709             :     Reduction r = Reduce(
    1710           2 :         graph()->NewNode(machine()->Float64Sub(), Float64Constant(-0.0), p0));
    1711           2 :     ASSERT_TRUE(r.Changed());
    1712           4 :     EXPECT_THAT(r.replacement(), IsFloat64Neg(p0));
    1713             :   }
    1714             : }
    1715             : 
    1716       15129 : TEST_F(MachineOperatorReducerTest, Float32SubMinusZeroMinusX) {
    1717           1 :   Node* const p0 = Parameter(0);
    1718             :   {
    1719             :     Reduction r = Reduce(
    1720           2 :         graph()->NewNode(machine()->Float32Sub(), Float32Constant(-0.0), p0));
    1721           2 :     ASSERT_TRUE(r.Changed());
    1722           4 :     EXPECT_THAT(r.replacement(), IsFloat32Neg(p0));
    1723             :   }
    1724             : }
    1725             : 
    1726       15129 : TEST_F(MachineOperatorReducerTest, Float64MulWithTwo) {
    1727           1 :   Node* const p0 = Parameter(0);
    1728             :   {
    1729             :     Reduction r = Reduce(
    1730           2 :         graph()->NewNode(machine()->Float64Mul(), Float64Constant(2.0), p0));
    1731           1 :     ASSERT_TRUE(r.Changed());
    1732           5 :     EXPECT_THAT(r.replacement(), IsFloat64Add(p0, p0));
    1733             :   }
    1734             :   {
    1735             :     Reduction r = Reduce(
    1736           2 :         graph()->NewNode(machine()->Float64Mul(), p0, Float64Constant(2.0)));
    1737           1 :     ASSERT_TRUE(r.Changed());
    1738           5 :     EXPECT_THAT(r.replacement(), IsFloat64Add(p0, p0));
    1739             :   }
    1740             : }
    1741             : 
    1742             : // -----------------------------------------------------------------------------
    1743             : // Float64Div
    1744             : 
    1745       15129 : TEST_F(MachineOperatorReducerTest, Float64DivWithMinusOne) {
    1746           1 :   Node* const p0 = Parameter(0);
    1747             :   {
    1748             :     Reduction r = Reduce(
    1749           2 :         graph()->NewNode(machine()->Float64Div(), p0, Float64Constant(-1.0)));
    1750           2 :     ASSERT_TRUE(r.Changed());
    1751           4 :     EXPECT_THAT(r.replacement(), IsFloat64Neg(p0));
    1752             :   }
    1753             : }
    1754             : 
    1755       15129 : TEST_F(MachineOperatorReducerTest, Float64DivWithPowerOfTwo) {
    1756           1 :   Node* const p0 = Parameter(0);
    1757       12277 :   TRACED_FORRANGE(uint64_t, exponent, 1, 0x7FE) {
    1758        2046 :     Double divisor = Double(exponent << Double::kPhysicalSignificandSize);
    1759        2046 :     if (divisor.value() == 1.0) continue;  // Skip x / 1.0 => x.
    1760             :     Reduction r = Reduce(graph()->NewNode(machine()->Float64Div(), p0,
    1761        4090 :                                           Float64Constant(divisor.value())));
    1762        2046 :     ASSERT_TRUE(r.Changed());
    1763       12270 :     EXPECT_THAT(r.replacement(),
    1764           0 :                 IsFloat64Mul(p0, IsFloat64Constant(1.0 / divisor.value())));
    1765        2046 :   }
    1766             : }
    1767             : 
    1768             : // -----------------------------------------------------------------------------
    1769             : // Float64Acos
    1770             : 
    1771       15129 : TEST_F(MachineOperatorReducerTest, Float64AcosWithConstant) {
    1772         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1773             :     Reduction const r =
    1774         200 :         Reduce(graph()->NewNode(machine()->Float64Acos(), Float64Constant(x)));
    1775         101 :     ASSERT_TRUE(r.Changed());
    1776         500 :     EXPECT_THAT(
    1777             :         r.replacement(),
    1778           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::acos(x))));
    1779         100 :   }
    1780             : }
    1781             : 
    1782             : // -----------------------------------------------------------------------------
    1783             : // Float64Acosh
    1784             : 
    1785       15129 : TEST_F(MachineOperatorReducerTest, Float64AcoshWithConstant) {
    1786         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1787             :     Reduction const r =
    1788         200 :         Reduce(graph()->NewNode(machine()->Float64Acosh(), Float64Constant(x)));
    1789         101 :     ASSERT_TRUE(r.Changed());
    1790         500 :     EXPECT_THAT(
    1791             :         r.replacement(),
    1792           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::acosh(x))));
    1793         100 :   }
    1794             : }
    1795             : 
    1796             : // -----------------------------------------------------------------------------
    1797             : // Float64Asin
    1798             : 
    1799       15129 : TEST_F(MachineOperatorReducerTest, Float64AsinWithConstant) {
    1800         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1801             :     Reduction const r =
    1802         200 :         Reduce(graph()->NewNode(machine()->Float64Asin(), Float64Constant(x)));
    1803         101 :     ASSERT_TRUE(r.Changed());
    1804         500 :     EXPECT_THAT(
    1805             :         r.replacement(),
    1806           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::asin(x))));
    1807         100 :   }
    1808             : }
    1809             : 
    1810             : // -----------------------------------------------------------------------------
    1811             : // Float64Asinh
    1812             : 
    1813       15129 : TEST_F(MachineOperatorReducerTest, Float64AsinhWithConstant) {
    1814         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1815             :     Reduction const r =
    1816         200 :         Reduce(graph()->NewNode(machine()->Float64Asinh(), Float64Constant(x)));
    1817         101 :     ASSERT_TRUE(r.Changed());
    1818         500 :     EXPECT_THAT(
    1819             :         r.replacement(),
    1820           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::asinh(x))));
    1821         100 :   }
    1822             : }
    1823             : 
    1824             : // -----------------------------------------------------------------------------
    1825             : // Float64Atan
    1826             : 
    1827       15129 : TEST_F(MachineOperatorReducerTest, Float64AtanWithConstant) {
    1828         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1829             :     Reduction const r =
    1830         200 :         Reduce(graph()->NewNode(machine()->Float64Atan(), Float64Constant(x)));
    1831         101 :     ASSERT_TRUE(r.Changed());
    1832         500 :     EXPECT_THAT(
    1833             :         r.replacement(),
    1834           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::atan(x))));
    1835         100 :   }
    1836             : }
    1837             : 
    1838             : // -----------------------------------------------------------------------------
    1839             : // Float64Atanh
    1840             : 
    1841       15129 : TEST_F(MachineOperatorReducerTest, Float64AtanhWithConstant) {
    1842         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1843             :     Reduction const r =
    1844         200 :         Reduce(graph()->NewNode(machine()->Float64Atanh(), Float64Constant(x)));
    1845         101 :     ASSERT_TRUE(r.Changed());
    1846         500 :     EXPECT_THAT(
    1847             :         r.replacement(),
    1848           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::atanh(x))));
    1849         100 :   }
    1850             : }
    1851             : 
    1852             : // -----------------------------------------------------------------------------
    1853             : // Float64Atan2
    1854             : 
    1855       15129 : TEST_F(MachineOperatorReducerTest, Float64Atan2WithConstant) {
    1856         601 :   TRACED_FOREACH(double, y, kFloat64Values) {
    1857       70000 :     TRACED_FOREACH(double, x, kFloat64Values) {
    1858             :       Reduction const r = Reduce(graph()->NewNode(
    1859       20000 :           machine()->Float64Atan2(), Float64Constant(y), Float64Constant(x)));
    1860       10001 :       ASSERT_TRUE(r.Changed());
    1861       50000 :       EXPECT_THAT(
    1862             :           r.replacement(),
    1863           0 :           IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::atan2(y, x))));
    1864       10000 :     }
    1865         100 :   }
    1866             : }
    1867             : 
    1868       15129 : TEST_F(MachineOperatorReducerTest, Float64Atan2WithNaN) {
    1869           1 :   Node* const p0 = Parameter(0);
    1870           1 :   Node* const nan = Float64Constant(std::numeric_limits<double>::quiet_NaN());
    1871             :   {
    1872             :     Reduction const r =
    1873           2 :         Reduce(graph()->NewNode(machine()->Float64Atan2(), p0, nan));
    1874           1 :     ASSERT_TRUE(r.Changed());
    1875           2 :     EXPECT_EQ(nan, r.replacement());
    1876             :   }
    1877             :   {
    1878             :     Reduction const r =
    1879           2 :         Reduce(graph()->NewNode(machine()->Float64Atan2(), nan, p0));
    1880           1 :     ASSERT_TRUE(r.Changed());
    1881           2 :     EXPECT_EQ(nan, r.replacement());
    1882             :   }
    1883             : }
    1884             : 
    1885             : // -----------------------------------------------------------------------------
    1886             : // Float64Cos
    1887             : 
    1888       15129 : TEST_F(MachineOperatorReducerTest, Float64CosWithConstant) {
    1889         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1890             :     Reduction const r =
    1891         200 :         Reduce(graph()->NewNode(machine()->Float64Cos(), Float64Constant(x)));
    1892         101 :     ASSERT_TRUE(r.Changed());
    1893         500 :     EXPECT_THAT(r.replacement(),
    1894           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::cos(x))));
    1895         100 :   }
    1896             : }
    1897             : 
    1898             : // -----------------------------------------------------------------------------
    1899             : // Float64Cosh
    1900             : 
    1901       15129 : TEST_F(MachineOperatorReducerTest, Float64CoshWithConstant) {
    1902         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1903             :     Reduction const r =
    1904         200 :         Reduce(graph()->NewNode(machine()->Float64Cosh(), Float64Constant(x)));
    1905         101 :     ASSERT_TRUE(r.Changed());
    1906         500 :     EXPECT_THAT(
    1907             :         r.replacement(),
    1908           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::cosh(x))));
    1909         100 :   }
    1910             : }
    1911             : 
    1912             : // -----------------------------------------------------------------------------
    1913             : // Float64Exp
    1914             : 
    1915       15129 : TEST_F(MachineOperatorReducerTest, Float64ExpWithConstant) {
    1916         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1917             :     Reduction const r =
    1918         200 :         Reduce(graph()->NewNode(machine()->Float64Exp(), Float64Constant(x)));
    1919         101 :     ASSERT_TRUE(r.Changed());
    1920         500 :     EXPECT_THAT(r.replacement(),
    1921           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::exp(x))));
    1922         100 :   }
    1923             : }
    1924             : 
    1925             : // -----------------------------------------------------------------------------
    1926             : // Float64Log
    1927             : 
    1928       15129 : TEST_F(MachineOperatorReducerTest, Float64LogWithConstant) {
    1929         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1930             :     Reduction const r =
    1931         200 :         Reduce(graph()->NewNode(machine()->Float64Log(), Float64Constant(x)));
    1932         101 :     ASSERT_TRUE(r.Changed());
    1933         500 :     EXPECT_THAT(r.replacement(),
    1934           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::log(x))));
    1935         100 :   }
    1936             : }
    1937             : 
    1938             : // -----------------------------------------------------------------------------
    1939             : // Float64Log1p
    1940             : 
    1941       15129 : TEST_F(MachineOperatorReducerTest, Float64Log1pWithConstant) {
    1942         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1943             :     Reduction const r =
    1944         200 :         Reduce(graph()->NewNode(machine()->Float64Log1p(), Float64Constant(x)));
    1945         101 :     ASSERT_TRUE(r.Changed());
    1946         500 :     EXPECT_THAT(
    1947             :         r.replacement(),
    1948           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::log1p(x))));
    1949         100 :   }
    1950             : }
    1951             : 
    1952             : // -----------------------------------------------------------------------------
    1953             : // Float64Pow
    1954             : 
    1955       15129 : TEST_F(MachineOperatorReducerTest, Float64PowWithConstant) {
    1956         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1957       70000 :     TRACED_FOREACH(double, y, kFloat64Values) {
    1958             :       Reduction const r = Reduce(graph()->NewNode(
    1959       20000 :           machine()->Float64Pow(), Float64Constant(x), Float64Constant(y)));
    1960       10001 :       ASSERT_TRUE(r.Changed());
    1961       50000 :       EXPECT_THAT(r.replacement(),
    1962           0 :                   IsFloat64Constant(NanSensitiveDoubleEq(Pow(x, y))));
    1963       10000 :     }
    1964         100 :   }
    1965             : }
    1966             : 
    1967       15129 : TEST_F(MachineOperatorReducerTest, Float64PowWithZeroExponent) {
    1968           1 :   Node* const p0 = Parameter(0);
    1969             :   {
    1970             :     Reduction const r = Reduce(
    1971           2 :         graph()->NewNode(machine()->Float64Pow(), p0, Float64Constant(-0.0)));
    1972           1 :     ASSERT_TRUE(r.Changed());
    1973           4 :     EXPECT_THAT(r.replacement(), IsFloat64Constant(1.0));
    1974             :   }
    1975             :   {
    1976             :     Reduction const r = Reduce(
    1977           2 :         graph()->NewNode(machine()->Float64Pow(), p0, Float64Constant(0.0)));
    1978           1 :     ASSERT_TRUE(r.Changed());
    1979           4 :     EXPECT_THAT(r.replacement(), IsFloat64Constant(1.0));
    1980             :   }
    1981             : }
    1982             : 
    1983             : // -----------------------------------------------------------------------------
    1984             : // Float64Sin
    1985             : 
    1986       15129 : TEST_F(MachineOperatorReducerTest, Float64SinWithConstant) {
    1987         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    1988             :     Reduction const r =
    1989         200 :         Reduce(graph()->NewNode(machine()->Float64Sin(), Float64Constant(x)));
    1990         101 :     ASSERT_TRUE(r.Changed());
    1991         500 :     EXPECT_THAT(r.replacement(),
    1992           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::sin(x))));
    1993         100 :   }
    1994             : }
    1995             : 
    1996             : // -----------------------------------------------------------------------------
    1997             : // Float64Sinh
    1998             : 
    1999       15129 : TEST_F(MachineOperatorReducerTest, Float64SinhWithConstant) {
    2000         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2001             :     Reduction const r =
    2002         200 :         Reduce(graph()->NewNode(machine()->Float64Sinh(), Float64Constant(x)));
    2003         101 :     ASSERT_TRUE(r.Changed());
    2004         500 :     EXPECT_THAT(
    2005             :         r.replacement(),
    2006           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::sinh(x))));
    2007         100 :   }
    2008             : }
    2009             : 
    2010             : // -----------------------------------------------------------------------------
    2011             : // Float64Tan
    2012             : 
    2013       15129 : TEST_F(MachineOperatorReducerTest, Float64TanWithConstant) {
    2014         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2015             :     Reduction const r =
    2016         200 :         Reduce(graph()->NewNode(machine()->Float64Tan(), Float64Constant(x)));
    2017         101 :     ASSERT_TRUE(r.Changed());
    2018         500 :     EXPECT_THAT(r.replacement(),
    2019           0 :                 IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::tan(x))));
    2020         100 :   }
    2021             : }
    2022             : 
    2023             : // -----------------------------------------------------------------------------
    2024             : // Float64Tanh
    2025             : 
    2026       15129 : TEST_F(MachineOperatorReducerTest, Float64TanhWithConstant) {
    2027         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2028             :     Reduction const r =
    2029         200 :         Reduce(graph()->NewNode(machine()->Float64Tanh(), Float64Constant(x)));
    2030         101 :     ASSERT_TRUE(r.Changed());
    2031         500 :     EXPECT_THAT(
    2032             :         r.replacement(),
    2033           0 :         IsFloat64Constant(NanSensitiveDoubleEq(base::ieee754::tanh(x))));
    2034         100 :   }
    2035             : }
    2036             : 
    2037             : // -----------------------------------------------------------------------------
    2038             : // Float64InsertLowWord32
    2039             : 
    2040       15129 : TEST_F(MachineOperatorReducerTest, Float64InsertLowWord32WithConstant) {
    2041         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2042       33600 :     TRACED_FOREACH(uint32_t, y, kUint32Values) {
    2043             :       Reduction const r =
    2044             :           Reduce(graph()->NewNode(machine()->Float64InsertLowWord32(),
    2045       14400 :                                   Float64Constant(x), Uint32Constant(y)));
    2046        4801 :       ASSERT_TRUE(r.Changed());
    2047       28800 :       EXPECT_THAT(
    2048             :           r.replacement(),
    2049             :           IsFloat64Constant(BitEq(bit_cast<double>(
    2050           0 :               (bit_cast<uint64_t>(x) & uint64_t{0xFFFFFFFF00000000}) | y))));
    2051        4800 :     }
    2052         100 :   }
    2053             : }
    2054             : 
    2055             : 
    2056             : // -----------------------------------------------------------------------------
    2057             : // Float64InsertHighWord32
    2058             : 
    2059             : 
    2060       15129 : TEST_F(MachineOperatorReducerTest, Float64InsertHighWord32WithConstant) {
    2061         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2062       33600 :     TRACED_FOREACH(uint32_t, y, kUint32Values) {
    2063             :       Reduction const r =
    2064             :           Reduce(graph()->NewNode(machine()->Float64InsertHighWord32(),
    2065       14400 :                                   Float64Constant(x), Uint32Constant(y)));
    2066        4801 :       ASSERT_TRUE(r.Changed());
    2067       28800 :       EXPECT_THAT(r.replacement(),
    2068             :                   IsFloat64Constant(BitEq(bit_cast<double>(
    2069             :                       (bit_cast<uint64_t>(x) & uint64_t{0xFFFFFFFF}) |
    2070           0 :                       (static_cast<uint64_t>(y) << 32)))));
    2071        4800 :     }
    2072         100 :   }
    2073             : }
    2074             : 
    2075             : 
    2076             : // -----------------------------------------------------------------------------
    2077             : // Float64Equal
    2078             : 
    2079       15129 : TEST_F(MachineOperatorReducerTest, Float64EqualWithConstant) {
    2080         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2081       70000 :     TRACED_FOREACH(double, y, kFloat64Values) {
    2082             :       Reduction const r = Reduce(graph()->NewNode(
    2083       20000 :           machine()->Float64Equal(), Float64Constant(x), Float64Constant(y)));
    2084       10001 :       ASSERT_TRUE(r.Changed());
    2085       40000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(x == y));
    2086       10000 :     }
    2087         100 :   }
    2088             : }
    2089             : 
    2090       15129 : TEST_F(MachineOperatorReducerTest, Float64EqualWithFloat32Conversions) {
    2091           1 :   Node* const p0 = Parameter(0);
    2092           1 :   Node* const p1 = Parameter(1);
    2093             :   Reduction const r = Reduce(graph()->NewNode(
    2094             :       machine()->Float64Equal(),
    2095             :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2096           4 :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
    2097           2 :   ASSERT_TRUE(r.Changed());
    2098           5 :   EXPECT_THAT(r.replacement(), IsFloat32Equal(p0, p1));
    2099             : }
    2100             : 
    2101             : 
    2102       15129 : TEST_F(MachineOperatorReducerTest, Float64EqualWithFloat32Constant) {
    2103           1 :   Node* const p0 = Parameter(0);
    2104         601 :   TRACED_FOREACH(float, x, kFloat32Values) {
    2105             :     Reduction r = Reduce(graph()->NewNode(
    2106             :         machine()->Float64Equal(),
    2107             :         graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2108         300 :         Float64Constant(x)));
    2109         101 :     ASSERT_TRUE(r.Changed());
    2110         600 :     EXPECT_THAT(r.replacement(), IsFloat32Equal(p0, IsFloat32Constant(x)));
    2111         100 :   }
    2112             : }
    2113             : 
    2114             : 
    2115             : // -----------------------------------------------------------------------------
    2116             : // Float64LessThan
    2117             : 
    2118       15129 : TEST_F(MachineOperatorReducerTest, Float64LessThanWithConstant) {
    2119         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2120       70000 :     TRACED_FOREACH(double, y, kFloat64Values) {
    2121             :       Reduction const r =
    2122             :           Reduce(graph()->NewNode(machine()->Float64LessThan(),
    2123       20000 :                                   Float64Constant(x), Float64Constant(y)));
    2124       10001 :       ASSERT_TRUE(r.Changed());
    2125       40000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(x < y));
    2126       10000 :     }
    2127         100 :   }
    2128             : }
    2129             : 
    2130       15129 : TEST_F(MachineOperatorReducerTest, Float64LessThanWithFloat32Conversions) {
    2131           1 :   Node* const p0 = Parameter(0);
    2132           1 :   Node* const p1 = Parameter(1);
    2133             :   Reduction const r = Reduce(graph()->NewNode(
    2134             :       machine()->Float64LessThan(),
    2135             :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2136           4 :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
    2137           2 :   ASSERT_TRUE(r.Changed());
    2138           5 :   EXPECT_THAT(r.replacement(), IsFloat32LessThan(p0, p1));
    2139             : }
    2140             : 
    2141             : 
    2142       15129 : TEST_F(MachineOperatorReducerTest, Float64LessThanWithFloat32Constant) {
    2143           1 :   Node* const p0 = Parameter(0);
    2144             :   {
    2145         601 :     TRACED_FOREACH(float, x, kFloat32Values) {
    2146             :       Reduction r = Reduce(graph()->NewNode(
    2147             :           machine()->Float64LessThan(),
    2148             :           graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2149         300 :           Float64Constant(x)));
    2150         100 :       ASSERT_TRUE(r.Changed());
    2151         600 :       EXPECT_THAT(r.replacement(), IsFloat32LessThan(p0, IsFloat32Constant(x)));
    2152         100 :     }
    2153             :   }
    2154             :   {
    2155         700 :     TRACED_FOREACH(float, x, kFloat32Values) {
    2156             :       Reduction r = Reduce(graph()->NewNode(
    2157             :           machine()->Float64LessThan(), Float64Constant(x),
    2158         300 :           graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0)));
    2159         100 :       ASSERT_TRUE(r.Changed());
    2160         600 :       EXPECT_THAT(r.replacement(), IsFloat32LessThan(IsFloat32Constant(x), p0));
    2161         100 :     }
    2162             :   }
    2163             : }
    2164             : 
    2165             : 
    2166             : // -----------------------------------------------------------------------------
    2167             : // Float64LessThanOrEqual
    2168             : 
    2169       15129 : TEST_F(MachineOperatorReducerTest, Float64LessThanOrEqualWithConstant) {
    2170         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2171       70000 :     TRACED_FOREACH(double, y, kFloat64Values) {
    2172             :       Reduction const r =
    2173             :           Reduce(graph()->NewNode(machine()->Float64LessThanOrEqual(),
    2174       20000 :                                   Float64Constant(x), Float64Constant(y)));
    2175       10001 :       ASSERT_TRUE(r.Changed());
    2176       40000 :       EXPECT_THAT(r.replacement(), IsInt32Constant(x <= y));
    2177       10000 :     }
    2178         100 :   }
    2179             : }
    2180             : 
    2181       15129 : TEST_F(MachineOperatorReducerTest,
    2182             :        Float64LessThanOrEqualWithFloat32Conversions) {
    2183           1 :   Node* const p0 = Parameter(0);
    2184           1 :   Node* const p1 = Parameter(1);
    2185             :   Reduction const r = Reduce(graph()->NewNode(
    2186             :       machine()->Float64LessThanOrEqual(),
    2187             :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2188           4 :       graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
    2189           2 :   ASSERT_TRUE(r.Changed());
    2190           5 :   EXPECT_THAT(r.replacement(), IsFloat32LessThanOrEqual(p0, p1));
    2191             : }
    2192             : 
    2193             : 
    2194       15129 : TEST_F(MachineOperatorReducerTest, Float64LessThanOrEqualWithFloat32Constant) {
    2195           1 :   Node* const p0 = Parameter(0);
    2196             :   {
    2197         601 :     TRACED_FOREACH(float, x, kFloat32Values) {
    2198             :       Reduction r = Reduce(graph()->NewNode(
    2199             :           machine()->Float64LessThanOrEqual(),
    2200             :           graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
    2201         300 :           Float64Constant(x)));
    2202         100 :       ASSERT_TRUE(r.Changed());
    2203         600 :       EXPECT_THAT(r.replacement(),
    2204           0 :                   IsFloat32LessThanOrEqual(p0, IsFloat32Constant(x)));
    2205         100 :     }
    2206             :   }
    2207             :   {
    2208         700 :     TRACED_FOREACH(float, x, kFloat32Values) {
    2209             :       Reduction r = Reduce(graph()->NewNode(
    2210             :           machine()->Float64LessThanOrEqual(), Float64Constant(x),
    2211         300 :           graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0)));
    2212         100 :       ASSERT_TRUE(r.Changed());
    2213         600 :       EXPECT_THAT(r.replacement(),
    2214           0 :                   IsFloat32LessThanOrEqual(IsFloat32Constant(x), p0));
    2215         100 :     }
    2216             :   }
    2217             : }
    2218             : 
    2219             : 
    2220             : // -----------------------------------------------------------------------------
    2221             : // Float64RoundDown
    2222             : 
    2223       15129 : TEST_F(MachineOperatorReducerTest, Float64RoundDownWithConstant) {
    2224         601 :   TRACED_FOREACH(double, x, kFloat64Values) {
    2225             :     Reduction r = Reduce(graph()->NewNode(
    2226         200 :         machine()->Float64RoundDown().placeholder(), Float64Constant(x)));
    2227         101 :     ASSERT_TRUE(r.Changed());
    2228         500 :     EXPECT_THAT(r.replacement(), IsFloat64Constant(Floor(x)));
    2229         100 :   }
    2230             : }
    2231             : 
    2232             : // -----------------------------------------------------------------------------
    2233             : // Store
    2234             : 
    2235       15129 : TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32And) {
    2236             :   const StoreRepresentation rep(MachineRepresentation::kWord8, kNoWriteBarrier);
    2237           1 :   Node* const base = Parameter(0);
    2238           1 :   Node* const index = Parameter(1);
    2239           1 :   Node* const value = Parameter(2);
    2240           1 :   Node* const effect = graph()->start();
    2241             :   Node* const control = graph()->start();
    2242         289 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
    2243             :     Node* const node =
    2244             :         graph()->NewNode(machine()->Store(rep), base, index,
    2245             :                          graph()->NewNode(machine()->Word32And(), value,
    2246             :                                           Uint32Constant(x | 0xFFu)),
    2247         144 :                          effect, control);
    2248             : 
    2249          48 :     Reduction r = Reduce(node);
    2250          49 :     ASSERT_TRUE(r.Changed());
    2251         432 :     EXPECT_THAT(r.replacement(),
    2252           0 :                 IsStore(rep, base, index, value, effect, control));
    2253          48 :   }
    2254             : }
    2255             : 
    2256             : 
    2257       15129 : TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32SarAndWord32Shl) {
    2258             :   const StoreRepresentation rep(MachineRepresentation::kWord8, kNoWriteBarrier);
    2259           1 :   Node* const base = Parameter(0);
    2260           1 :   Node* const index = Parameter(1);
    2261           1 :   Node* const value = Parameter(2);
    2262           1 :   Node* const effect = graph()->start();
    2263             :   Node* const control = graph()->start();
    2264         145 :   TRACED_FORRANGE(int32_t, x, 1, 24) {
    2265             :     Node* const node = graph()->NewNode(
    2266             :         machine()->Store(rep), base, index,
    2267             :         graph()->NewNode(
    2268             :             machine()->Word32Sar(),
    2269             :             graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
    2270             :             Int32Constant(x)),
    2271          72 :         effect, control);
    2272             : 
    2273          24 :     Reduction r = Reduce(node);
    2274          25 :     ASSERT_TRUE(r.Changed());
    2275         216 :     EXPECT_THAT(r.replacement(),
    2276           0 :                 IsStore(rep, base, index, value, effect, control));
    2277          24 :   }
    2278             : }
    2279             : 
    2280             : 
    2281       15129 : TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32And) {
    2282             :   const StoreRepresentation rep(MachineRepresentation::kWord16,
    2283             :                                 kNoWriteBarrier);
    2284           1 :   Node* const base = Parameter(0);
    2285           1 :   Node* const index = Parameter(1);
    2286           1 :   Node* const value = Parameter(2);
    2287           1 :   Node* const effect = graph()->start();
    2288             :   Node* const control = graph()->start();
    2289         289 :   TRACED_FOREACH(uint32_t, x, kUint32Values) {
    2290             :     Node* const node =
    2291             :         graph()->NewNode(machine()->Store(rep), base, index,
    2292             :                          graph()->NewNode(machine()->Word32And(), value,
    2293             :                                           Uint32Constant(x | 0xFFFFu)),
    2294         144 :                          effect, control);
    2295             : 
    2296          48 :     Reduction r = Reduce(node);
    2297          49 :     ASSERT_TRUE(r.Changed());
    2298         432 :     EXPECT_THAT(r.replacement(),
    2299           0 :                 IsStore(rep, base, index, value, effect, control));
    2300          48 :   }
    2301             : }
    2302             : 
    2303             : 
    2304       15129 : TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32SarAndWord32Shl) {
    2305             :   const StoreRepresentation rep(MachineRepresentation::kWord16,
    2306             :                                 kNoWriteBarrier);
    2307           1 :   Node* const base = Parameter(0);
    2308           1 :   Node* const index = Parameter(1);
    2309           1 :   Node* const value = Parameter(2);
    2310           1 :   Node* const effect = graph()->start();
    2311             :   Node* const control = graph()->start();
    2312          97 :   TRACED_FORRANGE(int32_t, x, 1, 16) {
    2313             :     Node* const node = graph()->NewNode(
    2314             :         machine()->Store(rep), base, index,
    2315             :         graph()->NewNode(
    2316             :             machine()->Word32Sar(),
    2317             :             graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
    2318             :             Int32Constant(x)),
    2319          48 :         effect, control);
    2320             : 
    2321          16 :     Reduction r = Reduce(node);
    2322          17 :     ASSERT_TRUE(r.Changed());
    2323         144 :     EXPECT_THAT(r.replacement(),
    2324           0 :                 IsStore(rep, base, index, value, effect, control));
    2325          16 :   }
    2326             : }
    2327             : 
    2328             : }  // namespace compiler
    2329             : }  // namespace internal
    2330        9075 : }  // namespace v8

Generated by: LCOV version 1.10