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

Generated by: LCOV version 1.10