v8/test/unittests/compiler/constant-folding-reducer-unittest.cc
Jakob Gruber f30b53bdae [nci] Add native_context_independent flags
... to OptimizedCompilationInfo, BytecodeGraphBuilder, and
JSHeapBroker.

Also add first uses of these flags in pipeline.cc by skipping certain
phases when nci is enabled. With this change, tests in the NCI variant
will start to fail since generic lowering is not fully implemented.
These implementations will follow incrementally in the next days.

Bug: v8:8888
Change-Id: I3f570fb92f09059d1f1f4015f88ffe80ccf746ad
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2239572
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68339}
2020-06-15 11:09:38 +00:00

266 lines
9.6 KiB
C++

// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/constant-folding-reducer.h"
#include "src/codegen/code-factory.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/compilation-dependencies.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/operator-properties.h"
#include "src/execution/isolate-inl.h"
#include "test/unittests/compiler/compiler-test-utils.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
#include "testing/gmock-support.h"
using testing::IsNaN;
namespace v8 {
namespace internal {
namespace compiler {
namespace constant_folding_reducer_unittest {
namespace {
const double kFloat64Values[] = {
-V8_INFINITY, -4.23878e+275, -5.82632e+265, -6.60355e+220,
-6.26172e+212, -2.56222e+211, -4.82408e+201, -1.84106e+157,
-1.63662e+127, -1.55772e+100, -1.67813e+72, -2.3382e+55,
-3.179e+30, -1.441e+09, -1.0647e+09, -7.99361e+08,
-5.77375e+08, -2.20984e+08, -32757, -13171,
-9970, -3984, -107, -105,
-92, -77, -61, -0.000208163,
-1.86685e-06, -1.17296e-10, -9.26358e-11, -5.08004e-60,
-1.74753e-65, -1.06561e-71, -5.67879e-79, -5.78459e-130,
-2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
-4.40497e-267, -2.19666e-273, -4.9998e-276, -5.59821e-278,
-2.03855e-282, -5.99335e-283, -7.17554e-284, -3.11744e-309,
-0.0, 0.0, 2.22507e-308, 1.30127e-270,
7.62898e-260, 4.00313e-249, 3.16829e-233, 1.85244e-228,
2.03544e-129, 1.35126e-110, 1.01182e-106, 5.26333e-94,
1.35292e-90, 2.85394e-83, 1.78323e-77, 5.4967e-57,
1.03207e-25, 4.57401e-25, 1.58738e-05, 2,
125, 2310, 9636, 14802,
17168, 28945, 29305, 4.81336e+07,
1.41207e+08, 4.65962e+08, 1.40499e+09, 2.12648e+09,
8.80006e+30, 1.4446e+45, 1.12164e+54, 2.48188e+89,
6.71121e+102, 3.074e+112, 4.9699e+152, 5.58383e+166,
4.30654e+172, 7.08824e+185, 9.6586e+214, 2.028e+223,
6.63277e+243, 1.56192e+261, 1.23202e+269, 5.72883e+289,
8.5798e+290, 1.40256e+294, 1.79769e+308, V8_INFINITY};
const double kIntegerValues[] = {-V8_INFINITY, INT_MIN, -1000.0, -42.0,
-1.0, 0.0, 1.0, 42.0,
1000.0, INT_MAX, UINT_MAX, V8_INFINITY};
} // namespace
class ConstantFoldingReducerTest : public TypedGraphTest {
public:
ConstantFoldingReducerTest()
: TypedGraphTest(3),
broker_(isolate(), zone()),
simplified_(zone()),
deps_(&broker_, zone()) {}
~ConstantFoldingReducerTest() override = default;
protected:
Reduction Reduce(Node* node) {
MachineOperatorBuilder machine(zone());
JSOperatorBuilder javascript(zone());
JSGraph jsgraph(isolate(), graph(), common(), &javascript, simplified(),
&machine);
// TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph(), tick_counter());
ConstantFoldingReducer reducer(&graph_reducer, &jsgraph, broker());
return reducer.Reduce(node);
}
Node* UseValue(Node* node) {
Node* start = graph()->NewNode(common()->Start(1));
Node* zero = graph()->NewNode(common()->NumberConstant(0));
return graph()->NewNode(common()->Return(), zero, node, start, start);
}
SimplifiedOperatorBuilder* simplified() { return &simplified_; }
JSHeapBroker* broker() { return &broker_; }
private:
JSHeapBroker broker_;
SimplifiedOperatorBuilder simplified_;
CompilationDependencies deps_;
};
TEST_F(ConstantFoldingReducerTest, ParameterWithMinusZero) {
{
Node* node = Parameter(
Type::Constant(broker(), factory()->minus_zero_value(), zone()));
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(-0.0));
}
{
Node* node = Parameter(Type::MinusZero());
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(-0.0));
}
{
Node* node = Parameter(Type::Union(
Type::MinusZero(),
Type::Constant(broker(), factory()->NewNumber(0), zone()), zone()));
UseValue(node);
Reduction r = Reduce(node);
EXPECT_FALSE(r.Changed());
}
}
TEST_F(ConstantFoldingReducerTest, ParameterWithNull) {
Handle<HeapObject> null = factory()->null_value();
{
Node* node = Parameter(Type::Constant(broker(), null, zone()));
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsHeapConstant(null));
}
{
Node* node = Parameter(Type::Null());
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsHeapConstant(null));
}
}
TEST_F(ConstantFoldingReducerTest, ParameterWithNaN) {
const double kNaNs[] = {-std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::signaling_NaN()};
TRACED_FOREACH(double, nan, kNaNs) {
Handle<Object> constant = factory()->NewNumber(nan);
Node* node = Parameter(Type::Constant(broker(), constant, zone()));
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(IsNaN()));
}
{
Node* node =
Parameter(Type::Constant(broker(), factory()->nan_value(), zone()));
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(IsNaN()));
}
{
Node* node = Parameter(Type::NaN());
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(IsNaN()));
}
}
TEST_F(ConstantFoldingReducerTest, ParameterWithPlainNumber) {
TRACED_FOREACH(double, value, kFloat64Values) {
Handle<Object> constant = factory()->NewNumber(value);
Node* node = Parameter(Type::Constant(broker(), constant, zone()));
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(value));
}
TRACED_FOREACH(double, value, kIntegerValues) {
Node* node = Parameter(Type::Range(value, value, zone()));
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(value));
}
}
TEST_F(ConstantFoldingReducerTest, ParameterWithUndefined) {
Handle<HeapObject> undefined = factory()->undefined_value();
{
Node* node = Parameter(Type::Undefined());
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsUndefinedConstant());
}
{
Node* node = Parameter(Type::Constant(broker(), undefined, zone()));
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsUndefinedConstant());
}
}
// -----------------------------------------------------------------------------
// ToBoolean
TEST_F(ConstantFoldingReducerTest, ToBooleanWithFalsish) {
Node* input = Parameter(
Type::Union(
Type::MinusZero(),
Type::Union(
Type::NaN(),
Type::Union(
Type::Null(),
Type::Union(
Type::Undefined(),
Type::Union(
Type::Undetectable(),
Type::Union(
Type::Constant(broker(), factory()->false_value(),
zone()),
Type::Range(0.0, 0.0, zone()), zone()),
zone()),
zone()),
zone()),
zone()),
zone()),
0);
Node* node = graph()->NewNode(simplified()->ToBoolean(), input);
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsFalseConstant());
}
TEST_F(ConstantFoldingReducerTest, ToBooleanWithTruish) {
Node* input = Parameter(
Type::Union(
Type::Constant(broker(), factory()->true_value(), zone()),
Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()),
zone()),
0);
Node* node = graph()->NewNode(simplified()->ToBoolean(), input);
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsTrueConstant());
}
TEST_F(ConstantFoldingReducerTest, ToBooleanWithNonZeroPlainNumber) {
Node* input = Parameter(Type::Range(1, V8_INFINITY, zone()), 0);
Node* node = graph()->NewNode(simplified()->ToBoolean(), input);
Node* use_value = UseValue(node);
Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(use_value->InputAt(1), IsTrueConstant());
}
} // namespace constant_folding_reducer_unittest
} // namespace compiler
} // namespace internal
} // namespace v8