LCOV - code coverage report
Current view: top level - test/cctest/compiler - test-branch-combine.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 538 538 100.0 %
Date: 2019-04-19 Functions: 41 45 91.1 %

          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/base/overflowing-math.h"
       6             : #include "src/objects-inl.h"
       7             : #include "test/cctest/cctest.h"
       8             : #include "test/cctest/compiler/codegen-tester.h"
       9             : #include "test/cctest/compiler/value-helper.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : namespace compiler {
      14             : 
      15             : static IrOpcode::Value int32cmp_opcodes[] = {
      16             :     IrOpcode::kWord32Equal, IrOpcode::kInt32LessThan,
      17             :     IrOpcode::kInt32LessThanOrEqual, IrOpcode::kUint32LessThan,
      18             :     IrOpcode::kUint32LessThanOrEqual};
      19             : 
      20             : 
      21       26660 : TEST(BranchCombineWord32EqualZero_1) {
      22             :   // Test combining a branch with x == 0
      23           4 :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
      24             :   int32_t eq_constant = -1033;
      25             :   int32_t ne_constant = 825118;
      26           4 :   Node* p0 = m.Parameter(0);
      27             : 
      28           4 :   RawMachineLabel blocka, blockb;
      29           4 :   m.Branch(m.Word32Equal(p0, m.Int32Constant(0)), &blocka, &blockb);
      30           4 :   m.Bind(&blocka);
      31           4 :   m.Return(m.Int32Constant(eq_constant));
      32           4 :   m.Bind(&blockb);
      33           4 :   m.Return(m.Int32Constant(ne_constant));
      34             : 
      35         468 :   FOR_INT32_INPUTS(a) {
      36         232 :     int32_t expect = a == 0 ? eq_constant : ne_constant;
      37         232 :     CHECK_EQ(expect, m.Call(a));
      38             :   }
      39           4 : }
      40             : 
      41             : 
      42       26660 : TEST(BranchCombineWord32EqualZero_chain) {
      43             :   // Test combining a branch with a chain of x == 0 == 0 == 0 ...
      44             :   int32_t eq_constant = -1133;
      45             :   int32_t ne_constant = 815118;
      46             : 
      47          52 :   for (int k = 0; k < 6; k++) {
      48          24 :     RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
      49          24 :     Node* p0 = m.Parameter(0);
      50          24 :     RawMachineLabel blocka, blockb;
      51             :     Node* cond = p0;
      52         144 :     for (int j = 0; j < k; j++) {
      53          60 :       cond = m.Word32Equal(cond, m.Int32Constant(0));
      54             :     }
      55          24 :     m.Branch(cond, &blocka, &blockb);
      56          24 :     m.Bind(&blocka);
      57          24 :     m.Return(m.Int32Constant(eq_constant));
      58          24 :     m.Bind(&blockb);
      59          24 :     m.Return(m.Int32Constant(ne_constant));
      60             : 
      61        2808 :     FOR_INT32_INPUTS(a) {
      62        1392 :       int32_t expect = (k & 1) == 1 ? (a == 0 ? eq_constant : ne_constant)
      63        1392 :                                     : (a == 0 ? ne_constant : eq_constant);
      64        1392 :       CHECK_EQ(expect, m.Call(a));
      65             :     }
      66             :   }
      67           4 : }
      68             : 
      69             : 
      70       26660 : TEST(BranchCombineInt32LessThanZero_1) {
      71             :   // Test combining a branch with x < 0
      72           4 :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
      73             :   int32_t eq_constant = -1433;
      74             :   int32_t ne_constant = 845118;
      75           4 :   Node* p0 = m.Parameter(0);
      76             : 
      77           4 :   RawMachineLabel blocka, blockb;
      78           4 :   m.Branch(m.Int32LessThan(p0, m.Int32Constant(0)), &blocka, &blockb);
      79           4 :   m.Bind(&blocka);
      80           4 :   m.Return(m.Int32Constant(eq_constant));
      81           4 :   m.Bind(&blockb);
      82           4 :   m.Return(m.Int32Constant(ne_constant));
      83             : 
      84         468 :   FOR_INT32_INPUTS(a) {
      85         232 :     int32_t expect = a < 0 ? eq_constant : ne_constant;
      86         232 :     CHECK_EQ(expect, m.Call(a));
      87             :   }
      88           4 : }
      89             : 
      90             : 
      91       26660 : TEST(BranchCombineUint32LessThan100_1) {
      92             :   // Test combining a branch with x < 100
      93           4 :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
      94             :   int32_t eq_constant = 1471;
      95             :   int32_t ne_constant = 88845718;
      96           4 :   Node* p0 = m.Parameter(0);
      97             : 
      98           4 :   RawMachineLabel blocka, blockb;
      99           4 :   m.Branch(m.Uint32LessThan(p0, m.Int32Constant(100)), &blocka, &blockb);
     100           4 :   m.Bind(&blocka);
     101           4 :   m.Return(m.Int32Constant(eq_constant));
     102           4 :   m.Bind(&blockb);
     103           4 :   m.Return(m.Int32Constant(ne_constant));
     104             : 
     105         468 :   FOR_UINT32_INPUTS(a) {
     106         232 :     int32_t expect = a < 100 ? eq_constant : ne_constant;
     107         232 :     CHECK_EQ(expect, m.Call(a));
     108             :   }
     109           4 : }
     110             : 
     111             : 
     112       26660 : TEST(BranchCombineUint32LessThanOrEqual100_1) {
     113             :   // Test combining a branch with x <= 100
     114           4 :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
     115             :   int32_t eq_constant = 1479;
     116             :   int32_t ne_constant = 77845719;
     117           4 :   Node* p0 = m.Parameter(0);
     118             : 
     119           4 :   RawMachineLabel blocka, blockb;
     120           4 :   m.Branch(m.Uint32LessThanOrEqual(p0, m.Int32Constant(100)), &blocka, &blockb);
     121           4 :   m.Bind(&blocka);
     122           4 :   m.Return(m.Int32Constant(eq_constant));
     123           4 :   m.Bind(&blockb);
     124           4 :   m.Return(m.Int32Constant(ne_constant));
     125             : 
     126         468 :   FOR_UINT32_INPUTS(a) {
     127         232 :     int32_t expect = a <= 100 ? eq_constant : ne_constant;
     128         232 :     CHECK_EQ(expect, m.Call(a));
     129             :   }
     130           4 : }
     131             : 
     132             : 
     133       26660 : TEST(BranchCombineZeroLessThanInt32_1) {
     134             :   // Test combining a branch with 0 < x
     135           4 :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
     136             :   int32_t eq_constant = -2033;
     137             :   int32_t ne_constant = 225118;
     138           4 :   Node* p0 = m.Parameter(0);
     139             : 
     140           4 :   RawMachineLabel blocka, blockb;
     141           4 :   m.Branch(m.Int32LessThan(m.Int32Constant(0), p0), &blocka, &blockb);
     142           4 :   m.Bind(&blocka);
     143           4 :   m.Return(m.Int32Constant(eq_constant));
     144           4 :   m.Bind(&blockb);
     145           4 :   m.Return(m.Int32Constant(ne_constant));
     146             : 
     147         468 :   FOR_INT32_INPUTS(a) {
     148         232 :     int32_t expect = 0 < a ? eq_constant : ne_constant;
     149         232 :     CHECK_EQ(expect, m.Call(a));
     150             :   }
     151           4 : }
     152             : 
     153             : 
     154       26660 : TEST(BranchCombineInt32GreaterThanZero_1) {
     155             :   // Test combining a branch with x > 0
     156           4 :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
     157             :   int32_t eq_constant = -1073;
     158             :   int32_t ne_constant = 825178;
     159           4 :   Node* p0 = m.Parameter(0);
     160             : 
     161           4 :   RawMachineLabel blocka, blockb;
     162           8 :   m.Branch(m.Int32GreaterThan(p0, m.Int32Constant(0)), &blocka, &blockb);
     163           4 :   m.Bind(&blocka);
     164           4 :   m.Return(m.Int32Constant(eq_constant));
     165           4 :   m.Bind(&blockb);
     166           4 :   m.Return(m.Int32Constant(ne_constant));
     167             : 
     168         468 :   FOR_INT32_INPUTS(a) {
     169         232 :     int32_t expect = a > 0 ? eq_constant : ne_constant;
     170         232 :     CHECK_EQ(expect, m.Call(a));
     171             :   }
     172           4 : }
     173             : 
     174             : 
     175       26660 : TEST(BranchCombineWord32EqualP) {
     176             :   // Test combining a branch with an Word32Equal.
     177             :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     178           4 :                                        MachineType::Int32());
     179             :   int32_t eq_constant = -1035;
     180             :   int32_t ne_constant = 825018;
     181           4 :   Node* p0 = m.Parameter(0);
     182           4 :   Node* p1 = m.Parameter(1);
     183             : 
     184           4 :   RawMachineLabel blocka, blockb;
     185           4 :   m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb);
     186           4 :   m.Bind(&blocka);
     187           4 :   m.Return(m.Int32Constant(eq_constant));
     188           4 :   m.Bind(&blockb);
     189           4 :   m.Return(m.Int32Constant(ne_constant));
     190             : 
     191         468 :   FOR_INT32_INPUTS(a) {
     192       27144 :     FOR_INT32_INPUTS(b) {
     193       13456 :       int32_t expect = a == b ? eq_constant : ne_constant;
     194       13456 :       CHECK_EQ(expect, m.Call(a, b));
     195             :     }
     196             :   }
     197           4 : }
     198             : 
     199             : 
     200       26660 : TEST(BranchCombineWord32EqualI) {
     201             :   int32_t eq_constant = -1135;
     202             :   int32_t ne_constant = 925718;
     203             : 
     204          20 :   for (int left = 0; left < 2; left++) {
     205         936 :     FOR_INT32_INPUTS(a) {
     206         464 :       RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
     207             : 
     208         464 :       Node* p0 = m.Int32Constant(a);
     209         464 :       Node* p1 = m.Parameter(0);
     210             : 
     211         464 :       RawMachineLabel blocka, blockb;
     212         464 :       if (left == 1) m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb);
     213         464 :       if (left == 0) m.Branch(m.Word32Equal(p1, p0), &blocka, &blockb);
     214         464 :       m.Bind(&blocka);
     215         464 :       m.Return(m.Int32Constant(eq_constant));
     216         464 :       m.Bind(&blockb);
     217         464 :       m.Return(m.Int32Constant(ne_constant));
     218             : 
     219       54288 :       FOR_INT32_INPUTS(b) {
     220       26912 :         int32_t expect = a == b ? eq_constant : ne_constant;
     221       26912 :         CHECK_EQ(expect, m.Call(b));
     222             :       }
     223             :     }
     224             :   }
     225           4 : }
     226             : 
     227             : 
     228       26660 : TEST(BranchCombineInt32CmpP) {
     229             :   int32_t eq_constant = -1235;
     230             :   int32_t ne_constant = 725018;
     231             : 
     232          20 :   for (int op = 0; op < 2; op++) {
     233             :     RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     234           8 :                                          MachineType::Int32());
     235           8 :     Node* p0 = m.Parameter(0);
     236           8 :     Node* p1 = m.Parameter(1);
     237             : 
     238           8 :     RawMachineLabel blocka, blockb;
     239           8 :     if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb);
     240           8 :     if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb);
     241           8 :     m.Bind(&blocka);
     242           8 :     m.Return(m.Int32Constant(eq_constant));
     243           8 :     m.Bind(&blockb);
     244           8 :     m.Return(m.Int32Constant(ne_constant));
     245             : 
     246         936 :     FOR_INT32_INPUTS(a) {
     247       54288 :       FOR_INT32_INPUTS(b) {
     248             :         int32_t expect = 0;
     249       26912 :         if (op == 0) expect = a < b ? eq_constant : ne_constant;
     250       26912 :         if (op == 1) expect = a <= b ? eq_constant : ne_constant;
     251       26912 :         CHECK_EQ(expect, m.Call(a, b));
     252             :       }
     253             :     }
     254             :   }
     255           4 : }
     256             : 
     257             : 
     258       26660 : TEST(BranchCombineInt32CmpI) {
     259             :   int32_t eq_constant = -1175;
     260             :   int32_t ne_constant = 927711;
     261             : 
     262          20 :   for (int op = 0; op < 2; op++) {
     263         936 :     FOR_INT32_INPUTS(a) {
     264         464 :       RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
     265         464 :       Node* p0 = m.Int32Constant(a);
     266         464 :       Node* p1 = m.Parameter(0);
     267             : 
     268         464 :       RawMachineLabel blocka, blockb;
     269         464 :       if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb);
     270         464 :       if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb);
     271         464 :       m.Bind(&blocka);
     272         464 :       m.Return(m.Int32Constant(eq_constant));
     273         464 :       m.Bind(&blockb);
     274         464 :       m.Return(m.Int32Constant(ne_constant));
     275             : 
     276       54288 :       FOR_INT32_INPUTS(b) {
     277             :         int32_t expect = 0;
     278       26912 :         if (op == 0) expect = a < b ? eq_constant : ne_constant;
     279       26912 :         if (op == 1) expect = a <= b ? eq_constant : ne_constant;
     280       26912 :         CHECK_EQ(expect, m.Call(b));
     281             :       }
     282             :     }
     283             :   }
     284           4 : }
     285             : 
     286             : 
     287             : // Now come the sophisticated tests for many input shape combinations.
     288             : 
     289             : // Materializes a boolean (1 or 0) from a comparison.
     290          80 : class CmpMaterializeBoolGen : public BinopGen<int32_t> {
     291             :  public:
     292             :   CompareWrapper w;
     293             :   bool invert;
     294             : 
     295             :   CmpMaterializeBoolGen(IrOpcode::Value opcode, bool i)
     296          80 :       : w(opcode), invert(i) {}
     297             : 
     298        2720 :   void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) override {
     299        2720 :     Node* cond = w.MakeNode(m, a, b);
     300        2720 :     if (invert) cond = m->Word32Equal(cond, m->Int32Constant(0));
     301        2720 :     m->Return(cond);
     302        2720 :   }
     303      686720 :   int32_t expected(int32_t a, int32_t b) override {
     304      686720 :     if (invert) return !w.Int32Compare(a, b) ? 1 : 0;
     305      343360 :     return w.Int32Compare(a, b) ? 1 : 0;
     306             :   }
     307             : };
     308             : 
     309             : 
     310             : // Generates a branch and return one of two values from a comparison.
     311         160 : class CmpBranchGen : public BinopGen<int32_t> {
     312             :  public:
     313             :   CompareWrapper w;
     314             :   bool invert;
     315             :   bool true_first;
     316             :   int32_t eq_constant;
     317             :   int32_t ne_constant;
     318             : 
     319             :   CmpBranchGen(IrOpcode::Value opcode, bool i, bool t, int32_t eq, int32_t ne)
     320         160 :       : w(opcode), invert(i), true_first(t), eq_constant(eq), ne_constant(ne) {}
     321             : 
     322        5440 :   void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) override {
     323        5440 :     RawMachineLabel blocka, blockb;
     324        5440 :     Node* cond = w.MakeNode(m, a, b);
     325        5440 :     if (invert) cond = m->Word32Equal(cond, m->Int32Constant(0));
     326        5440 :     m->Branch(cond, &blocka, &blockb);
     327        5440 :     if (true_first) {
     328        2720 :       m->Bind(&blocka);
     329        2720 :       m->Return(m->Int32Constant(eq_constant));
     330        2720 :       m->Bind(&blockb);
     331        2720 :       m->Return(m->Int32Constant(ne_constant));
     332             :     } else {
     333        2720 :       m->Bind(&blockb);
     334        2720 :       m->Return(m->Int32Constant(ne_constant));
     335        2720 :       m->Bind(&blocka);
     336        2720 :       m->Return(m->Int32Constant(eq_constant));
     337             :     }
     338        5440 :   }
     339     1373440 :   int32_t expected(int32_t a, int32_t b) override {
     340     1373440 :     if (invert) return !w.Int32Compare(a, b) ? eq_constant : ne_constant;
     341      686720 :     return w.Int32Compare(a, b) ? eq_constant : ne_constant;
     342             :   }
     343             : };
     344             : 
     345             : 
     346       26660 : TEST(BranchCombineInt32CmpAllInputShapes_materialized) {
     347          44 :   for (size_t i = 0; i < arraysize(int32cmp_opcodes); i++) {
     348          20 :     CmpMaterializeBoolGen gen(int32cmp_opcodes[i], false);
     349             :     Int32BinopInputShapeTester tester(&gen);
     350          20 :     tester.TestAllInputShapes();
     351             :   }
     352           4 : }
     353             : 
     354             : 
     355       26660 : TEST(BranchCombineInt32CmpAllInputShapes_inverted_materialized) {
     356          44 :   for (size_t i = 0; i < arraysize(int32cmp_opcodes); i++) {
     357          20 :     CmpMaterializeBoolGen gen(int32cmp_opcodes[i], true);
     358             :     Int32BinopInputShapeTester tester(&gen);
     359          20 :     tester.TestAllInputShapes();
     360             :   }
     361           4 : }
     362             : 
     363             : 
     364       26660 : TEST(BranchCombineInt32CmpAllInputShapes_branch_true) {
     365          44 :   for (int i = 0; i < static_cast<int>(arraysize(int32cmp_opcodes)); i++) {
     366          20 :     CmpBranchGen gen(int32cmp_opcodes[i], false, false, 995 + i, -1011 - i);
     367             :     Int32BinopInputShapeTester tester(&gen);
     368          20 :     tester.TestAllInputShapes();
     369             :   }
     370           4 : }
     371             : 
     372             : 
     373       26660 : TEST(BranchCombineInt32CmpAllInputShapes_branch_false) {
     374          44 :   for (int i = 0; i < static_cast<int>(arraysize(int32cmp_opcodes)); i++) {
     375          20 :     CmpBranchGen gen(int32cmp_opcodes[i], false, true, 795 + i, -2011 - i);
     376             :     Int32BinopInputShapeTester tester(&gen);
     377          20 :     tester.TestAllInputShapes();
     378             :   }
     379           4 : }
     380             : 
     381             : 
     382       26660 : TEST(BranchCombineInt32CmpAllInputShapes_inverse_branch_true) {
     383          44 :   for (int i = 0; i < static_cast<int>(arraysize(int32cmp_opcodes)); i++) {
     384          20 :     CmpBranchGen gen(int32cmp_opcodes[i], true, false, 695 + i, -3011 - i);
     385             :     Int32BinopInputShapeTester tester(&gen);
     386          20 :     tester.TestAllInputShapes();
     387             :   }
     388           4 : }
     389             : 
     390             : 
     391       26660 : TEST(BranchCombineInt32CmpAllInputShapes_inverse_branch_false) {
     392          44 :   for (int i = 0; i < static_cast<int>(arraysize(int32cmp_opcodes)); i++) {
     393          20 :     CmpBranchGen gen(int32cmp_opcodes[i], true, true, 595 + i, -4011 - i);
     394             :     Int32BinopInputShapeTester tester(&gen);
     395          20 :     tester.TestAllInputShapes();
     396             :   }
     397           4 : }
     398             : 
     399             : 
     400       26660 : TEST(BranchCombineFloat64Compares) {
     401             :   double inf = V8_INFINITY;
     402             :   double nan = std::numeric_limits<double>::quiet_NaN();
     403           4 :   double inputs[] = {0.0, 1.0, -1.0, -inf, inf, nan};
     404             : 
     405             :   int32_t eq_constant = -1733;
     406             :   int32_t ne_constant = 915118;
     407             : 
     408           4 :   double input_a = 0.0;
     409           4 :   double input_b = 0.0;
     410             : 
     411             :   CompareWrapper cmps[] = {CompareWrapper(IrOpcode::kFloat64Equal),
     412             :                            CompareWrapper(IrOpcode::kFloat64LessThan),
     413             :                            CompareWrapper(IrOpcode::kFloat64LessThanOrEqual)};
     414             : 
     415          28 :   for (size_t c = 0; c < arraysize(cmps); c++) {
     416          12 :     CompareWrapper cmp = cmps[c];
     417          60 :     for (int invert = 0; invert < 2; invert++) {
     418          24 :       RawMachineAssemblerTester<int32_t> m;
     419          24 :       Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
     420          24 :       Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
     421             : 
     422          24 :       RawMachineLabel blocka, blockb;
     423          24 :       Node* cond = cmp.MakeNode(&m, a, b);
     424          24 :       if (invert) cond = m.Word32Equal(cond, m.Int32Constant(0));
     425          24 :       m.Branch(cond, &blocka, &blockb);
     426          24 :       m.Bind(&blocka);
     427          24 :       m.Return(m.Int32Constant(eq_constant));
     428          24 :       m.Bind(&blockb);
     429          24 :       m.Return(m.Int32Constant(ne_constant));
     430             : 
     431         312 :       for (size_t i = 0; i < arraysize(inputs); ++i) {
     432        1872 :         for (size_t j = 0; j < arraysize(inputs); ++j) {
     433         864 :           input_a = inputs[i];
     434         864 :           input_b = inputs[j];
     435             :           int32_t expected =
     436         432 :               invert ? (cmp.Float64Compare(input_a, input_b) ? ne_constant
     437             :                                                              : eq_constant)
     438         432 :                      : (cmp.Float64Compare(input_a, input_b) ? eq_constant
     439        1728 :                                                              : ne_constant);
     440         864 :           CHECK_EQ(expected, m.Call());
     441             :         }
     442             :       }
     443             :     }
     444             :   }
     445           4 : }
     446             : 
     447       26660 : TEST(BranchCombineEffectLevel) {
     448             :   // Test that the load doesn't get folded into the branch, as there's a store
     449             :   // between them. See http://crbug.com/611976.
     450           4 :   int32_t input = 0;
     451             : 
     452           4 :   RawMachineAssemblerTester<int32_t> m;
     453           4 :   Node* a = m.LoadFromPointer(&input, MachineType::Int32());
     454           4 :   Node* compare = m.Word32And(a, m.Int32Constant(1));
     455           4 :   Node* equal = m.Word32Equal(compare, m.Int32Constant(0));
     456           4 :   m.StoreToPointer(&input, MachineRepresentation::kWord32, m.Int32Constant(1));
     457             : 
     458           4 :   RawMachineLabel blocka, blockb;
     459           4 :   m.Branch(equal, &blocka, &blockb);
     460           4 :   m.Bind(&blocka);
     461           4 :   m.Return(m.Int32Constant(42));
     462           4 :   m.Bind(&blockb);
     463           4 :   m.Return(m.Int32Constant(0));
     464             : 
     465           4 :   CHECK_EQ(42, m.Call());
     466           4 : }
     467             : 
     468       26660 : TEST(BranchCombineInt32AddLessThanZero) {
     469             :   int32_t t_constant = -1033;
     470             :   int32_t f_constant = 825118;
     471             : 
     472             :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     473           4 :                                        MachineType::Int32());
     474           4 :   Node* a = m.Parameter(0);
     475           4 :   Node* b = m.Parameter(1);
     476           4 :   Node* add = m.Int32Add(a, b);
     477           4 :   Node* compare = m.Int32LessThan(add, m.Int32Constant(0));
     478             : 
     479           4 :   RawMachineLabel blocka, blockb;
     480           4 :   m.Branch(compare, &blocka, &blockb);
     481           4 :   m.Bind(&blocka);
     482           4 :   m.Return(m.Int32Constant(t_constant));
     483           4 :   m.Bind(&blockb);
     484           4 :   m.Return(m.Int32Constant(f_constant));
     485             : 
     486         468 :   FOR_INT32_INPUTS(a) {
     487       27144 :     FOR_INT32_INPUTS(b) {
     488             :       int32_t expect =
     489       13456 :           (base::AddWithWraparound(a, b) < 0) ? t_constant : f_constant;
     490       13456 :       CHECK_EQ(expect, m.Call(a, b));
     491             :     }
     492             :   }
     493           4 : }
     494             : 
     495       26660 : TEST(BranchCombineInt32AddGreaterThanOrEqualZero) {
     496             :   int32_t t_constant = -1033;
     497             :   int32_t f_constant = 825118;
     498             : 
     499             :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     500           4 :                                        MachineType::Int32());
     501           4 :   Node* a = m.Parameter(0);
     502           4 :   Node* b = m.Parameter(1);
     503           4 :   Node* add = m.Int32Add(a, b);
     504           4 :   Node* compare = m.Int32GreaterThanOrEqual(add, m.Int32Constant(0));
     505             : 
     506           4 :   RawMachineLabel blocka, blockb;
     507           4 :   m.Branch(compare, &blocka, &blockb);
     508           4 :   m.Bind(&blocka);
     509           4 :   m.Return(m.Int32Constant(t_constant));
     510           4 :   m.Bind(&blockb);
     511           4 :   m.Return(m.Int32Constant(f_constant));
     512             : 
     513         468 :   FOR_INT32_INPUTS(a) {
     514       27144 :     FOR_INT32_INPUTS(b) {
     515             :       int32_t expect =
     516       13456 :           (base::AddWithWraparound(a, b) >= 0) ? t_constant : f_constant;
     517       13456 :       CHECK_EQ(expect, m.Call(a, b));
     518             :     }
     519             :   }
     520           4 : }
     521             : 
     522       26660 : TEST(BranchCombineInt32ZeroGreaterThanAdd) {
     523             :   int32_t t_constant = -1033;
     524             :   int32_t f_constant = 825118;
     525             : 
     526             :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     527           4 :                                        MachineType::Int32());
     528           4 :   Node* a = m.Parameter(0);
     529           4 :   Node* b = m.Parameter(1);
     530           4 :   Node* add = m.Int32Add(a, b);
     531           4 :   Node* compare = m.Int32GreaterThan(m.Int32Constant(0), add);
     532             : 
     533           4 :   RawMachineLabel blocka, blockb;
     534           4 :   m.Branch(compare, &blocka, &blockb);
     535           4 :   m.Bind(&blocka);
     536           4 :   m.Return(m.Int32Constant(t_constant));
     537           4 :   m.Bind(&blockb);
     538           4 :   m.Return(m.Int32Constant(f_constant));
     539             : 
     540         468 :   FOR_INT32_INPUTS(a) {
     541       27144 :     FOR_INT32_INPUTS(b) {
     542             :       int32_t expect =
     543       13456 :           (0 > base::AddWithWraparound(a, b)) ? t_constant : f_constant;
     544       13456 :       CHECK_EQ(expect, m.Call(a, b));
     545             :     }
     546             :   }
     547           4 : }
     548             : 
     549       26660 : TEST(BranchCombineInt32ZeroLessThanOrEqualAdd) {
     550             :   int32_t t_constant = -1033;
     551             :   int32_t f_constant = 825118;
     552             : 
     553             :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     554           4 :                                        MachineType::Int32());
     555           4 :   Node* a = m.Parameter(0);
     556           4 :   Node* b = m.Parameter(1);
     557           4 :   Node* add = m.Int32Add(a, b);
     558           4 :   Node* compare = m.Int32LessThanOrEqual(m.Int32Constant(0), add);
     559             : 
     560           4 :   RawMachineLabel blocka, blockb;
     561           4 :   m.Branch(compare, &blocka, &blockb);
     562           4 :   m.Bind(&blocka);
     563           4 :   m.Return(m.Int32Constant(t_constant));
     564           4 :   m.Bind(&blockb);
     565           4 :   m.Return(m.Int32Constant(f_constant));
     566             : 
     567         468 :   FOR_INT32_INPUTS(a) {
     568       27144 :     FOR_INT32_INPUTS(b) {
     569             :       int32_t expect =
     570       13456 :           (0 <= base::AddWithWraparound(a, b)) ? t_constant : f_constant;
     571       13456 :       CHECK_EQ(expect, m.Call(a, b));
     572             :     }
     573             :   }
     574           4 : }
     575             : 
     576       26660 : TEST(BranchCombineUint32AddLessThanOrEqualZero) {
     577             :   int32_t t_constant = -1033;
     578             :   int32_t f_constant = 825118;
     579             : 
     580             :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
     581           4 :                                        MachineType::Uint32());
     582           4 :   Node* a = m.Parameter(0);
     583           4 :   Node* b = m.Parameter(1);
     584           4 :   Node* add = m.Int32Add(a, b);
     585           4 :   Node* compare = m.Uint32LessThanOrEqual(add, m.Int32Constant(0));
     586             : 
     587           4 :   RawMachineLabel blocka, blockb;
     588           4 :   m.Branch(compare, &blocka, &blockb);
     589           4 :   m.Bind(&blocka);
     590           4 :   m.Return(m.Int32Constant(t_constant));
     591           4 :   m.Bind(&blockb);
     592           4 :   m.Return(m.Int32Constant(f_constant));
     593             : 
     594         468 :   FOR_UINT32_INPUTS(a) {
     595       27144 :     FOR_UINT32_INPUTS(b) {
     596       13456 :       int32_t expect = (a + b <= 0) ? t_constant : f_constant;
     597       13456 :       CHECK_EQ(expect, m.Call(a, b));
     598             :     }
     599             :   }
     600           4 : }
     601             : 
     602       26660 : TEST(BranchCombineUint32AddGreaterThanZero) {
     603             :   int32_t t_constant = -1033;
     604             :   int32_t f_constant = 825118;
     605             : 
     606             :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
     607           4 :                                        MachineType::Uint32());
     608           4 :   Node* a = m.Parameter(0);
     609           4 :   Node* b = m.Parameter(1);
     610           4 :   Node* add = m.Int32Add(a, b);
     611           4 :   Node* compare = m.Uint32GreaterThan(add, m.Int32Constant(0));
     612             : 
     613           4 :   RawMachineLabel blocka, blockb;
     614           4 :   m.Branch(compare, &blocka, &blockb);
     615           4 :   m.Bind(&blocka);
     616           4 :   m.Return(m.Int32Constant(t_constant));
     617           4 :   m.Bind(&blockb);
     618           4 :   m.Return(m.Int32Constant(f_constant));
     619             : 
     620         468 :   FOR_UINT32_INPUTS(a) {
     621       27144 :     FOR_UINT32_INPUTS(b) {
     622       13456 :       int32_t expect = (a + b > 0) ? t_constant : f_constant;
     623       13456 :       CHECK_EQ(expect, m.Call(a, b));
     624             :     }
     625             :   }
     626           4 : }
     627             : 
     628       26660 : TEST(BranchCombineUint32ZeroGreaterThanOrEqualAdd) {
     629             :   int32_t t_constant = -1033;
     630             :   int32_t f_constant = 825118;
     631             : 
     632             :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
     633           4 :                                        MachineType::Uint32());
     634           4 :   Node* a = m.Parameter(0);
     635           4 :   Node* b = m.Parameter(1);
     636           4 :   Node* add = m.Int32Add(a, b);
     637           4 :   Node* compare = m.Uint32GreaterThanOrEqual(m.Int32Constant(0), add);
     638             : 
     639           4 :   RawMachineLabel blocka, blockb;
     640           4 :   m.Branch(compare, &blocka, &blockb);
     641           4 :   m.Bind(&blocka);
     642           4 :   m.Return(m.Int32Constant(t_constant));
     643           4 :   m.Bind(&blockb);
     644           4 :   m.Return(m.Int32Constant(f_constant));
     645             : 
     646         468 :   FOR_UINT32_INPUTS(a) {
     647       27144 :     FOR_UINT32_INPUTS(b) {
     648       13456 :       int32_t expect = (0 >= a + b) ? t_constant : f_constant;
     649       13456 :       CHECK_EQ(expect, m.Call(a, b));
     650             :     }
     651             :   }
     652           4 : }
     653             : 
     654       26660 : TEST(BranchCombineUint32ZeroLessThanAdd) {
     655             :   int32_t t_constant = -1033;
     656             :   int32_t f_constant = 825118;
     657             : 
     658             :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
     659           4 :                                        MachineType::Uint32());
     660           4 :   Node* a = m.Parameter(0);
     661           4 :   Node* b = m.Parameter(1);
     662           4 :   Node* add = m.Int32Add(a, b);
     663           4 :   Node* compare = m.Uint32LessThan(m.Int32Constant(0), add);
     664             : 
     665           4 :   RawMachineLabel blocka, blockb;
     666           4 :   m.Branch(compare, &blocka, &blockb);
     667           4 :   m.Bind(&blocka);
     668           4 :   m.Return(m.Int32Constant(t_constant));
     669           4 :   m.Bind(&blockb);
     670           4 :   m.Return(m.Int32Constant(f_constant));
     671             : 
     672         468 :   FOR_UINT32_INPUTS(a) {
     673       27144 :     FOR_UINT32_INPUTS(b) {
     674       13456 :       int32_t expect = (0 < a + b) ? t_constant : f_constant;
     675       13456 :       CHECK_EQ(expect, m.Call(a, b));
     676             :     }
     677             :   }
     678           4 : }
     679             : 
     680       26660 : TEST(BranchCombineWord32AndLessThanZero) {
     681             :   int32_t t_constant = -1033;
     682             :   int32_t f_constant = 825118;
     683             : 
     684             :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     685           4 :                                        MachineType::Int32());
     686           4 :   Node* a = m.Parameter(0);
     687           4 :   Node* b = m.Parameter(1);
     688           4 :   Node* add = m.Word32And(a, b);
     689           4 :   Node* compare = m.Int32LessThan(add, m.Int32Constant(0));
     690             : 
     691           4 :   RawMachineLabel blocka, blockb;
     692           4 :   m.Branch(compare, &blocka, &blockb);
     693           4 :   m.Bind(&blocka);
     694           4 :   m.Return(m.Int32Constant(t_constant));
     695           4 :   m.Bind(&blockb);
     696           4 :   m.Return(m.Int32Constant(f_constant));
     697             : 
     698         468 :   FOR_INT32_INPUTS(a) {
     699       27144 :     FOR_INT32_INPUTS(b) {
     700       13456 :       int32_t expect = ((a & b) < 0) ? t_constant : f_constant;
     701       13456 :       CHECK_EQ(expect, m.Call(a, b));
     702             :     }
     703             :   }
     704           4 : }
     705             : 
     706       26660 : TEST(BranchCombineWord32AndGreaterThanOrEqualZero) {
     707             :   int32_t t_constant = -1033;
     708             :   int32_t f_constant = 825118;
     709             : 
     710             :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     711           4 :                                        MachineType::Int32());
     712           4 :   Node* a = m.Parameter(0);
     713           4 :   Node* b = m.Parameter(1);
     714           4 :   Node* add = m.Word32And(a, b);
     715           4 :   Node* compare = m.Int32GreaterThanOrEqual(add, m.Int32Constant(0));
     716             : 
     717           4 :   RawMachineLabel blocka, blockb;
     718           4 :   m.Branch(compare, &blocka, &blockb);
     719           4 :   m.Bind(&blocka);
     720           4 :   m.Return(m.Int32Constant(t_constant));
     721           4 :   m.Bind(&blockb);
     722           4 :   m.Return(m.Int32Constant(f_constant));
     723             : 
     724         468 :   FOR_INT32_INPUTS(a) {
     725       27144 :     FOR_INT32_INPUTS(b) {
     726       13456 :       int32_t expect = ((a & b) >= 0) ? t_constant : f_constant;
     727       13456 :       CHECK_EQ(expect, m.Call(a, b));
     728             :     }
     729             :   }
     730           4 : }
     731             : 
     732       26660 : TEST(BranchCombineInt32ZeroGreaterThanAnd) {
     733             :   int32_t t_constant = -1033;
     734             :   int32_t f_constant = 825118;
     735             : 
     736             :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     737           4 :                                        MachineType::Int32());
     738           4 :   Node* a = m.Parameter(0);
     739           4 :   Node* b = m.Parameter(1);
     740           4 :   Node* add = m.Word32And(a, b);
     741           4 :   Node* compare = m.Int32GreaterThan(m.Int32Constant(0), add);
     742             : 
     743           4 :   RawMachineLabel blocka, blockb;
     744           4 :   m.Branch(compare, &blocka, &blockb);
     745           4 :   m.Bind(&blocka);
     746           4 :   m.Return(m.Int32Constant(t_constant));
     747           4 :   m.Bind(&blockb);
     748           4 :   m.Return(m.Int32Constant(f_constant));
     749             : 
     750         468 :   FOR_INT32_INPUTS(a) {
     751       27144 :     FOR_INT32_INPUTS(b) {
     752       13456 :       int32_t expect = (0 > (a & b)) ? t_constant : f_constant;
     753       13456 :       CHECK_EQ(expect, m.Call(a, b));
     754             :     }
     755             :   }
     756           4 : }
     757             : 
     758       26660 : TEST(BranchCombineInt32ZeroLessThanOrEqualAnd) {
     759             :   int32_t t_constant = -1033;
     760             :   int32_t f_constant = 825118;
     761             : 
     762             :   RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
     763           4 :                                        MachineType::Int32());
     764           4 :   Node* a = m.Parameter(0);
     765           4 :   Node* b = m.Parameter(1);
     766           4 :   Node* add = m.Word32And(a, b);
     767           4 :   Node* compare = m.Int32LessThanOrEqual(m.Int32Constant(0), add);
     768             : 
     769           4 :   RawMachineLabel blocka, blockb;
     770           4 :   m.Branch(compare, &blocka, &blockb);
     771           4 :   m.Bind(&blocka);
     772           4 :   m.Return(m.Int32Constant(t_constant));
     773           4 :   m.Bind(&blockb);
     774           4 :   m.Return(m.Int32Constant(f_constant));
     775             : 
     776         468 :   FOR_INT32_INPUTS(a) {
     777       27144 :     FOR_INT32_INPUTS(b) {
     778       13456 :       int32_t expect = (0 <= (a & b)) ? t_constant : f_constant;
     779       13456 :       CHECK_EQ(expect, m.Call(a, b));
     780             :     }
     781             :   }
     782           4 : }
     783             : 
     784       26660 : TEST(BranchCombineUint32AndLessThanOrEqualZero) {
     785             :   int32_t t_constant = -1033;
     786             :   int32_t f_constant = 825118;
     787             : 
     788             :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
     789           4 :                                        MachineType::Uint32());
     790           4 :   Node* a = m.Parameter(0);
     791           4 :   Node* b = m.Parameter(1);
     792           4 :   Node* add = m.Word32And(a, b);
     793           4 :   Node* compare = m.Uint32LessThanOrEqual(add, m.Int32Constant(0));
     794             : 
     795           4 :   RawMachineLabel blocka, blockb;
     796           4 :   m.Branch(compare, &blocka, &blockb);
     797           4 :   m.Bind(&blocka);
     798           4 :   m.Return(m.Int32Constant(t_constant));
     799           4 :   m.Bind(&blockb);
     800           4 :   m.Return(m.Int32Constant(f_constant));
     801             : 
     802         468 :   FOR_UINT32_INPUTS(a) {
     803       27144 :     FOR_UINT32_INPUTS(b) {
     804       13456 :       int32_t expect = ((a & b) <= 0) ? t_constant : f_constant;
     805       13456 :       CHECK_EQ(expect, m.Call(a, b));
     806             :     }
     807             :   }
     808           4 : }
     809             : 
     810       26660 : TEST(BranchCombineUint32AndGreaterThanZero) {
     811             :   int32_t t_constant = -1033;
     812             :   int32_t f_constant = 825118;
     813             : 
     814             :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
     815           4 :                                        MachineType::Uint32());
     816           4 :   Node* a = m.Parameter(0);
     817           4 :   Node* b = m.Parameter(1);
     818           4 :   Node* add = m.Word32And(a, b);
     819           4 :   Node* compare = m.Uint32GreaterThan(add, m.Int32Constant(0));
     820             : 
     821           4 :   RawMachineLabel blocka, blockb;
     822           4 :   m.Branch(compare, &blocka, &blockb);
     823           4 :   m.Bind(&blocka);
     824           4 :   m.Return(m.Int32Constant(t_constant));
     825           4 :   m.Bind(&blockb);
     826           4 :   m.Return(m.Int32Constant(f_constant));
     827             : 
     828         468 :   FOR_UINT32_INPUTS(a) {
     829       27144 :     FOR_UINT32_INPUTS(b) {
     830       13456 :       int32_t expect = ((a & b) > 0) ? t_constant : f_constant;
     831       13456 :       CHECK_EQ(expect, m.Call(a, b));
     832             :     }
     833             :   }
     834           4 : }
     835             : 
     836       26660 : TEST(BranchCombineUint32ZeroGreaterThanOrEqualAnd) {
     837             :   int32_t t_constant = -1033;
     838             :   int32_t f_constant = 825118;
     839             : 
     840             :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
     841           4 :                                        MachineType::Uint32());
     842           4 :   Node* a = m.Parameter(0);
     843           4 :   Node* b = m.Parameter(1);
     844           4 :   Node* add = m.Word32And(a, b);
     845           4 :   Node* compare = m.Uint32GreaterThanOrEqual(m.Int32Constant(0), add);
     846             : 
     847           4 :   RawMachineLabel blocka, blockb;
     848           4 :   m.Branch(compare, &blocka, &blockb);
     849           4 :   m.Bind(&blocka);
     850           4 :   m.Return(m.Int32Constant(t_constant));
     851           4 :   m.Bind(&blockb);
     852           4 :   m.Return(m.Int32Constant(f_constant));
     853             : 
     854         468 :   FOR_UINT32_INPUTS(a) {
     855       27144 :     FOR_UINT32_INPUTS(b) {
     856       13456 :       int32_t expect = (0 >= (a & b)) ? t_constant : f_constant;
     857       13456 :       CHECK_EQ(expect, m.Call(a, b));
     858             :     }
     859             :   }
     860           4 : }
     861             : 
     862       26660 : TEST(BranchCombineUint32ZeroLessThanAnd) {
     863             :   int32_t t_constant = -1033;
     864             :   int32_t f_constant = 825118;
     865             : 
     866             :   RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
     867           4 :                                        MachineType::Uint32());
     868           4 :   Node* a = m.Parameter(0);
     869           4 :   Node* b = m.Parameter(1);
     870           4 :   Node* add = m.Word32And(a, b);
     871           4 :   Node* compare = m.Uint32LessThan(m.Int32Constant(0), add);
     872             : 
     873           4 :   RawMachineLabel blocka, blockb;
     874           4 :   m.Branch(compare, &blocka, &blockb);
     875           4 :   m.Bind(&blocka);
     876           4 :   m.Return(m.Int32Constant(t_constant));
     877           4 :   m.Bind(&blockb);
     878           4 :   m.Return(m.Int32Constant(f_constant));
     879             : 
     880         468 :   FOR_UINT32_INPUTS(a) {
     881       27144 :     FOR_UINT32_INPUTS(b) {
     882       13456 :       int32_t expect = (0 < (a & b)) ? t_constant : f_constant;
     883       13456 :       CHECK_EQ(expect, m.Call(a, b));
     884             :     }
     885             :   }
     886           4 : }
     887             : 
     888             : }  // namespace compiler
     889             : }  // namespace internal
     890       79968 : }  // namespace v8

Generated by: LCOV version 1.10