LCOV - code coverage report
Current view: top level - test/unittests/compiler - constant-folding-reducer-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 76 76 100.0 %
Date: 2019-04-18 Functions: 21 30 70.0 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/compiler/constant-folding-reducer.h"
       6             : #include "src/code-factory.h"
       7             : #include "src/compiler/access-builder.h"
       8             : #include "src/compiler/compilation-dependencies.h"
       9             : #include "src/compiler/js-graph.h"
      10             : #include "src/compiler/js-operator.h"
      11             : #include "src/compiler/machine-operator.h"
      12             : #include "src/compiler/node-properties.h"
      13             : #include "src/compiler/operator-properties.h"
      14             : #include "src/isolate-inl.h"
      15             : #include "test/unittests/compiler/compiler-test-utils.h"
      16             : #include "test/unittests/compiler/graph-unittest.h"
      17             : #include "test/unittests/compiler/node-test-utils.h"
      18             : #include "testing/gmock-support.h"
      19             : 
      20             : using testing::IsNaN;
      21             : 
      22             : namespace v8 {
      23             : namespace internal {
      24             : namespace compiler {
      25             : namespace constant_folding_reducer_unittest {
      26             : 
      27             : namespace {
      28             : 
      29             : const double kFloat64Values[] = {
      30             :     -V8_INFINITY,  -4.23878e+275, -5.82632e+265, -6.60355e+220,
      31             :     -6.26172e+212, -2.56222e+211, -4.82408e+201, -1.84106e+157,
      32             :     -1.63662e+127, -1.55772e+100, -1.67813e+72,  -2.3382e+55,
      33             :     -3.179e+30,    -1.441e+09,    -1.0647e+09,   -7.99361e+08,
      34             :     -5.77375e+08,  -2.20984e+08,  -32757,        -13171,
      35             :     -9970,         -3984,         -107,          -105,
      36             :     -92,           -77,           -61,           -0.000208163,
      37             :     -1.86685e-06,  -1.17296e-10,  -9.26358e-11,  -5.08004e-60,
      38             :     -1.74753e-65,  -1.06561e-71,  -5.67879e-79,  -5.78459e-130,
      39             :     -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
      40             :     -4.40497e-267, -2.19666e-273, -4.9998e-276,  -5.59821e-278,
      41             :     -2.03855e-282, -5.99335e-283, -7.17554e-284, -3.11744e-309,
      42             :     -0.0,          0.0,           2.22507e-308,  1.30127e-270,
      43             :     7.62898e-260,  4.00313e-249,  3.16829e-233,  1.85244e-228,
      44             :     2.03544e-129,  1.35126e-110,  1.01182e-106,  5.26333e-94,
      45             :     1.35292e-90,   2.85394e-83,   1.78323e-77,   5.4967e-57,
      46             :     1.03207e-25,   4.57401e-25,   1.58738e-05,   2,
      47             :     125,           2310,          9636,          14802,
      48             :     17168,         28945,         29305,         4.81336e+07,
      49             :     1.41207e+08,   4.65962e+08,   1.40499e+09,   2.12648e+09,
      50             :     8.80006e+30,   1.4446e+45,    1.12164e+54,   2.48188e+89,
      51             :     6.71121e+102,  3.074e+112,    4.9699e+152,   5.58383e+166,
      52             :     4.30654e+172,  7.08824e+185,  9.6586e+214,   2.028e+223,
      53             :     6.63277e+243,  1.56192e+261,  1.23202e+269,  5.72883e+289,
      54             :     8.5798e+290,   1.40256e+294,  1.79769e+308,  V8_INFINITY};
      55             : 
      56             : const double kIntegerValues[] = {-V8_INFINITY, INT_MIN, -1000.0,  -42.0,
      57             :                                  -1.0,         0.0,     1.0,      42.0,
      58             :                                  1000.0,       INT_MAX, UINT_MAX, V8_INFINITY};
      59             : 
      60             : }  // namespace
      61             : 
      62             : class ConstantFoldingReducerTest : public TypedGraphTest {
      63             :  public:
      64           8 :   ConstantFoldingReducerTest()
      65             :       : TypedGraphTest(3),
      66             :         broker_(isolate(), zone()),
      67             :         simplified_(zone()),
      68          16 :         deps_(&broker_, zone()) {}
      69          16 :   ~ConstantFoldingReducerTest() override = default;
      70             : 
      71             :  protected:
      72         127 :   Reduction Reduce(Node* node) {
      73         127 :     MachineOperatorBuilder machine(zone());
      74         127 :     JSOperatorBuilder javascript(zone());
      75             :     JSGraph jsgraph(isolate(), graph(), common(), &javascript, simplified(),
      76         127 :                     &machine);
      77             :     // TODO(titzer): mock the GraphReducer here for better unit testing.
      78         254 :     GraphReducer graph_reducer(zone(), graph());
      79         254 :     ConstantFoldingReducer reducer(&graph_reducer, &jsgraph, broker());
      80         254 :     return reducer.Reduce(node);
      81             :   }
      82             : 
      83         130 :   SimplifiedOperatorBuilder* simplified() { return &simplified_; }
      84         236 :   JSHeapBroker* broker() { return &broker_; }
      85             : 
      86             :  private:
      87             :   JSHeapBroker broker_;
      88             :   SimplifiedOperatorBuilder simplified_;
      89             :   CompilationDependencies deps_;
      90             : };
      91             : 
      92       15418 : TEST_F(ConstantFoldingReducerTest, ParameterWithMinusZero) {
      93             :   {
      94             :     Reduction r = Reduce(Parameter(
      95           1 :         Type::NewConstant(broker(), factory()->minus_zero_value(), zone())));
      96           1 :     ASSERT_TRUE(r.Changed());
      97           5 :     EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
      98             :   }
      99             :   {
     100           1 :     Reduction r = Reduce(Parameter(Type::MinusZero()));
     101           1 :     ASSERT_TRUE(r.Changed());
     102           5 :     EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
     103             :   }
     104             :   {
     105             :     Reduction r = Reduce(Parameter(Type::Union(
     106             :         Type::MinusZero(),
     107           1 :         Type::NewConstant(broker(), factory()->NewNumber(0), zone()), zone())));
     108           2 :     EXPECT_FALSE(r.Changed());
     109             :   }
     110             : }
     111             : 
     112       15418 : TEST_F(ConstantFoldingReducerTest, ParameterWithNull) {
     113             :   Handle<HeapObject> null = factory()->null_value();
     114             :   {
     115           1 :     Reduction r = Reduce(Parameter(Type::NewConstant(broker(), null, zone())));
     116           1 :     ASSERT_TRUE(r.Changed());
     117           4 :     EXPECT_THAT(r.replacement(), IsHeapConstant(null));
     118             :   }
     119             :   {
     120           1 :     Reduction r = Reduce(Parameter(Type::Null()));
     121           1 :     ASSERT_TRUE(r.Changed());
     122           4 :     EXPECT_THAT(r.replacement(), IsHeapConstant(null));
     123             :   }
     124             : }
     125             : 
     126       15418 : TEST_F(ConstantFoldingReducerTest, ParameterWithNaN) {
     127             :   const double kNaNs[] = {-std::numeric_limits<double>::quiet_NaN(),
     128             :                           std::numeric_limits<double>::quiet_NaN(),
     129           1 :                           std::numeric_limits<double>::signaling_NaN()};
     130          13 :   TRACED_FOREACH(double, nan, kNaNs) {
     131           3 :     Handle<Object> constant = factory()->NewNumber(nan);
     132             :     Reduction r =
     133           3 :         Reduce(Parameter(Type::NewConstant(broker(), constant, zone())));
     134           3 :     ASSERT_TRUE(r.Changed());
     135          15 :     EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
     136             :   }
     137             :   {
     138             :     Reduction r = Reduce(
     139           1 :         Parameter(Type::NewConstant(broker(), factory()->nan_value(), zone())));
     140           1 :     ASSERT_TRUE(r.Changed());
     141           5 :     EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
     142             :   }
     143             :   {
     144           1 :     Reduction r = Reduce(Parameter(Type::NaN()));
     145           1 :     ASSERT_TRUE(r.Changed());
     146           5 :     EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
     147             :   }
     148             : }
     149             : 
     150       15418 : TEST_F(ConstantFoldingReducerTest, ParameterWithPlainNumber) {
     151         401 :   TRACED_FOREACH(double, value, kFloat64Values) {
     152         100 :     Handle<Object> constant = factory()->NewNumber(value);
     153             :     Reduction r =
     154         100 :         Reduce(Parameter(Type::NewConstant(broker(), constant, zone())));
     155         100 :     ASSERT_TRUE(r.Changed());
     156         500 :     EXPECT_THAT(r.replacement(), IsNumberConstant(value));
     157             :   }
     158          49 :   TRACED_FOREACH(double, value, kIntegerValues) {
     159          12 :     Reduction r = Reduce(Parameter(Type::Range(value, value, zone())));
     160          12 :     ASSERT_TRUE(r.Changed());
     161          60 :     EXPECT_THAT(r.replacement(), IsNumberConstant(value));
     162             :   }
     163             : }
     164             : 
     165       15418 : TEST_F(ConstantFoldingReducerTest, ParameterWithUndefined) {
     166             :   Handle<HeapObject> undefined = factory()->undefined_value();
     167             :   {
     168           1 :     Reduction r = Reduce(Parameter(Type::Undefined()));
     169           1 :     ASSERT_TRUE(r.Changed());
     170           4 :     EXPECT_THAT(r.replacement(), IsHeapConstant(undefined));
     171             :   }
     172             :   {
     173             :     Reduction r =
     174           1 :         Reduce(Parameter(Type::NewConstant(broker(), undefined, zone())));
     175           1 :     ASSERT_TRUE(r.Changed());
     176           4 :     EXPECT_THAT(r.replacement(), IsHeapConstant(undefined));
     177             :   }
     178             : }
     179             : 
     180             : // -----------------------------------------------------------------------------
     181             : // ToBoolean
     182             : 
     183       15418 : TEST_F(ConstantFoldingReducerTest, ToBooleanWithFalsish) {
     184           3 :   Node* input = Parameter(
     185             :       Type::Union(
     186             :           Type::MinusZero(),
     187             :           Type::Union(
     188             :               Type::NaN(),
     189             :               Type::Union(
     190             :                   Type::Null(),
     191             :                   Type::Union(
     192             :                       Type::Undefined(),
     193             :                       Type::Union(
     194             :                           Type::Undetectable(),
     195             :                           Type::Union(
     196             :                               Type::NewConstant(
     197             :                                   broker(), factory()->false_value(), zone()),
     198             :                               Type::Range(0.0, 0.0, zone()), zone()),
     199             :                           zone()),
     200             :                       zone()),
     201             :                   zone()),
     202             :               zone()),
     203             :           zone()),
     204           1 :       0);
     205           2 :   Reduction r = Reduce(graph()->NewNode(simplified()->ToBoolean(), input));
     206           1 :   ASSERT_TRUE(r.Changed());
     207           4 :   EXPECT_THAT(r.replacement(), IsFalseConstant());
     208             : }
     209             : 
     210       15418 : TEST_F(ConstantFoldingReducerTest, ToBooleanWithTruish) {
     211           3 :   Node* input = Parameter(
     212             :       Type::Union(
     213             :           Type::NewConstant(broker(), factory()->true_value(), zone()),
     214             :           Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()),
     215             :           zone()),
     216           1 :       0);
     217           2 :   Reduction r = Reduce(graph()->NewNode(simplified()->ToBoolean(), input));
     218           1 :   ASSERT_TRUE(r.Changed());
     219           4 :   EXPECT_THAT(r.replacement(), IsTrueConstant());
     220             : }
     221             : 
     222       15418 : TEST_F(ConstantFoldingReducerTest, ToBooleanWithNonZeroPlainNumber) {
     223           1 :   Node* input = Parameter(Type::Range(1, V8_INFINITY, zone()), 0);
     224           2 :   Reduction r = Reduce(graph()->NewNode(simplified()->ToBoolean(), input));
     225           1 :   ASSERT_TRUE(r.Changed());
     226           4 :   EXPECT_THAT(r.replacement(), IsTrueConstant());
     227             : }
     228             : 
     229             : }  // namespace constant_folding_reducer_unittest
     230             : }  // namespace compiler
     231             : }  // namespace internal
     232        9249 : }  // namespace v8

Generated by: LCOV version 1.10