Commit a75e4cea authored by Benedikt Meurer's avatar Benedikt Meurer

[turbofan] Remove indirection in JSToBoolean/JSUnaryNot lowering.

This reduces the overhead of typed lowering, because we lower
JSToBoolean/JSUnaryNot directly if possible, instead of first lowering
to AnyToBoolean, and then letting the SimplifiedOperatorReducer do the
further lowering.

Also remove some obsolete tests from the cctest suite that have since
been removed by proper unittests. And improve unitttest coverage for the
typed lowering cases.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/999173003

Cr-Commit-Position: refs/heads/master@{#27295}
parent 5383257e
...@@ -526,39 +526,64 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { ...@@ -526,39 +526,64 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) { Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) {
Node* input = node->InputAt(0); Node* const input = node->InputAt(0);
Type* input_type = NodeProperties::GetBounds(input).upper; Type* const input_type = NodeProperties::GetBounds(input).upper;
if (input_type->Is(Type::Boolean())) { if (input_type->Is(Type::Boolean())) {
// JSUnaryNot(x:boolean,context) => BooleanNot(x) // JSUnaryNot(x:boolean) => BooleanNot(x)
node->set_op(simplified()->BooleanNot()); node->set_op(simplified()->BooleanNot());
node->TrimInputCount(1); node->TrimInputCount(1);
return Changed(node); return Changed(node);
} else if (input_type->Is(Type::OrderedNumber())) { } else if (input_type->Is(Type::OrderedNumber())) {
// JSUnaryNot(x:number,context) => NumberEqual(x,#0) // JSUnaryNot(x:number) => NumberEqual(x,#0)
node->set_op(simplified()->NumberEqual()); node->set_op(simplified()->NumberEqual());
node->ReplaceInput(1, jsgraph()->ZeroConstant()); node->ReplaceInput(1, jsgraph()->ZeroConstant());
DCHECK_EQ(2, node->InputCount()); node->TrimInputCount(2);
return Changed(node); return Changed(node);
} } else if (input_type->Is(Type::String())) {
// JSUnaryNot(x,context) => BooleanNot(AnyToBoolean(x)) // JSUnaryNot(x:string) => NumberEqual(x.length,#0)
node->set_op(simplified()->BooleanNot()); FieldAccess const access = AccessBuilder::ForStringLength();
node->ReplaceInput(0, graph()->NewNode(simplified()->AnyToBoolean(), input)); // It is safe for the load to be effect-free (i.e. not linked into effect
node->TrimInputCount(1); // chain) because we assume String::length to be immutable.
Node* length = graph()->NewNode(simplified()->LoadField(access), input,
graph()->start(), graph()->start());
node->set_op(simplified()->NumberEqual());
node->ReplaceInput(0, length);
node->ReplaceInput(1, jsgraph()->ZeroConstant());
node->TrimInputCount(2);
NodeProperties::ReplaceWithValue(node, node, length);
return Changed(node); return Changed(node);
}
return NoChange();
} }
Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
Node* input = node->InputAt(0); Node* const input = node->InputAt(0);
Type* input_type = NodeProperties::GetBounds(input).upper; Type* const input_type = NodeProperties::GetBounds(input).upper;
if (input_type->Is(Type::Boolean())) { if (input_type->Is(Type::Boolean())) {
// JSToBoolean(x:boolean,context) => x // JSToBoolean(x:boolean) => x
return Replace(input); return Replace(input);
} } else if (input_type->Is(Type::OrderedNumber())) {
// JSToBoolean(x,context) => AnyToBoolean(x) // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0))
node->set_op(simplified()->AnyToBoolean()); node->set_op(simplified()->BooleanNot());
node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input,
jsgraph()->ZeroConstant()));
node->TrimInputCount(1); node->TrimInputCount(1);
return Changed(node); return Changed(node);
} else if (input_type->Is(Type::String())) {
// JSToBoolean(x:string) => NumberLessThan(#0,x.length)
FieldAccess const access = AccessBuilder::ForStringLength();
// It is safe for the load to be effect-free (i.e. not linked into effect
// chain) because we assume String::length to be immutable.
Node* length = graph()->NewNode(simplified()->LoadField(access), input,
graph()->start(), graph()->start());
node->set_op(simplified()->NumberLessThan());
node->ReplaceInput(0, jsgraph()->ZeroConstant());
node->ReplaceInput(1, length);
node->TrimInputCount(2);
return Changed(node);
}
return NoChange();
} }
......
...@@ -153,7 +153,6 @@ ...@@ -153,7 +153,6 @@
#define SIMPLIFIED_OP_LIST(V) \ #define SIMPLIFIED_OP_LIST(V) \
SIMPLIFIED_COMPARE_BINOP_LIST(V) \ SIMPLIFIED_COMPARE_BINOP_LIST(V) \
V(AnyToBoolean) \
V(BooleanNot) \ V(BooleanNot) \
V(BooleanToNumber) \ V(BooleanToNumber) \
V(NumberAdd) \ V(NumberAdd) \
......
...@@ -538,24 +538,6 @@ class RepresentationSelector { ...@@ -538,24 +538,6 @@ class RepresentationSelector {
//------------------------------------------------------------------ //------------------------------------------------------------------
// Simplified operators. // Simplified operators.
//------------------------------------------------------------------ //------------------------------------------------------------------
case IrOpcode::kAnyToBoolean: {
VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged);
if (lower()) {
// AnyToBoolean(x) => Call(ToBooleanStub, x, no-context)
Operator::Properties properties = node->op()->properties();
Callable callable = CodeFactory::ToBoolean(
jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL);
CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
flags, properties);
node->set_op(jsgraph_->common()->Call(desc));
node->InsertInput(jsgraph_->zone(), 0,
jsgraph_->HeapConstant(callable.code()));
node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
}
break;
}
case IrOpcode::kBooleanNot: { case IrOpcode::kBooleanNot: {
if (lower()) { if (lower()) {
MachineTypeUnion input = GetInfo(node->InputAt(0))->output; MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
......
...@@ -4,11 +4,9 @@ ...@@ -4,11 +4,9 @@
#include "src/compiler/simplified-operator-reducer.h" #include "src/compiler/simplified-operator-reducer.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/js-graph.h" #include "src/compiler/js-graph.h"
#include "src/compiler/machine-operator.h" #include "src/compiler/machine-operator.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/operator-properties.h" #include "src/compiler/operator-properties.h"
namespace v8 { namespace v8 {
...@@ -24,8 +22,6 @@ SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {} ...@@ -24,8 +22,6 @@ SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
Reduction SimplifiedOperatorReducer::Reduce(Node* node) { Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kAnyToBoolean:
return ReduceAnyToBoolean(node);
case IrOpcode::kBooleanNot: { case IrOpcode::kBooleanNot: {
HeapObjectMatcher<HeapObject> m(node->InputAt(0)); HeapObjectMatcher<HeapObject> m(node->InputAt(0));
if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->false_value()))) { if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->false_value()))) {
...@@ -111,32 +107,6 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -111,32 +107,6 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
} }
Reduction SimplifiedOperatorReducer::ReduceAnyToBoolean(Node* node) {
Node* const input = NodeProperties::GetValueInput(node, 0);
Type* const input_type = NodeProperties::GetBounds(input).upper;
if (input_type->Is(Type::Boolean())) {
// AnyToBoolean(x:boolean) => x
return Replace(input);
}
if (input_type->Is(Type::OrderedNumber())) {
// AnyToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
Node* compare = graph()->NewNode(simplified()->NumberEqual(), input,
jsgraph()->ZeroConstant());
return Change(node, simplified()->BooleanNot(), compare);
}
if (input_type->Is(Type::String())) {
// AnyToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0))
FieldAccess const access = AccessBuilder::ForStringLength();
Node* length = graph()->NewNode(simplified()->LoadField(access), input,
graph()->start(), graph()->start());
Node* compare = graph()->NewNode(simplified()->NumberEqual(), length,
jsgraph()->ZeroConstant());
return Change(node, simplified()->BooleanNot(), compare);
}
return NoChange();
}
Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op, Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
Node* a) { Node* a) {
DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op)); DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
...@@ -175,11 +145,6 @@ Factory* SimplifiedOperatorReducer::factory() const { ...@@ -175,11 +145,6 @@ Factory* SimplifiedOperatorReducer::factory() const {
} }
CommonOperatorBuilder* SimplifiedOperatorReducer::common() const {
return jsgraph()->common();
}
MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const { MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const {
return jsgraph()->machine(); return jsgraph()->machine();
} }
......
...@@ -18,7 +18,6 @@ class Heap; ...@@ -18,7 +18,6 @@ class Heap;
namespace compiler { namespace compiler {
// Forward declarations. // Forward declarations.
class CommonOperatorBuilder;
class JSGraph; class JSGraph;
class MachineOperatorBuilder; class MachineOperatorBuilder;
...@@ -30,8 +29,6 @@ class SimplifiedOperatorReducer FINAL : public Reducer { ...@@ -30,8 +29,6 @@ class SimplifiedOperatorReducer FINAL : public Reducer {
Reduction Reduce(Node* node) FINAL; Reduction Reduce(Node* node) FINAL;
private: private:
Reduction ReduceAnyToBoolean(Node* node);
Reduction Change(Node* node, const Operator* op, Node* a); Reduction Change(Node* node, const Operator* op, Node* a);
Reduction ReplaceFloat64(double value); Reduction ReplaceFloat64(double value);
Reduction ReplaceInt32(int32_t value); Reduction ReplaceInt32(int32_t value);
...@@ -44,7 +41,6 @@ class SimplifiedOperatorReducer FINAL : public Reducer { ...@@ -44,7 +41,6 @@ class SimplifiedOperatorReducer FINAL : public Reducer {
Graph* graph() const; Graph* graph() const;
Factory* factory() const; Factory* factory() const;
JSGraph* jsgraph() const { return jsgraph_; } JSGraph* jsgraph() const { return jsgraph_; }
CommonOperatorBuilder* common() const;
MachineOperatorBuilder* machine() const; MachineOperatorBuilder* machine() const;
SimplifiedOperatorBuilder* simplified() { return &simplified_; } SimplifiedOperatorBuilder* simplified() { return &simplified_; }
......
...@@ -158,7 +158,6 @@ const ElementAccess& ElementAccessOf(const Operator* op) { ...@@ -158,7 +158,6 @@ const ElementAccess& ElementAccessOf(const Operator* op) {
#define PURE_OP_LIST(V) \ #define PURE_OP_LIST(V) \
V(AnyToBoolean, Operator::kNoProperties, 1) \
V(BooleanNot, Operator::kNoProperties, 1) \ V(BooleanNot, Operator::kNoProperties, 1) \
V(BooleanToNumber, Operator::kNoProperties, 1) \ V(BooleanToNumber, Operator::kNoProperties, 1) \
V(NumberEqual, Operator::kCommutative, 2) \ V(NumberEqual, Operator::kCommutative, 2) \
......
...@@ -128,8 +128,6 @@ class SimplifiedOperatorBuilder FINAL { ...@@ -128,8 +128,6 @@ class SimplifiedOperatorBuilder FINAL {
public: public:
explicit SimplifiedOperatorBuilder(Zone* zone); explicit SimplifiedOperatorBuilder(Zone* zone);
const Operator* AnyToBoolean();
const Operator* BooleanNot(); const Operator* BooleanNot();
const Operator* BooleanToNumber(); const Operator* BooleanToNumber();
......
...@@ -1534,11 +1534,6 @@ Bounds Typer::Visitor::TypeJSStackCheck(Node* node) { ...@@ -1534,11 +1534,6 @@ Bounds Typer::Visitor::TypeJSStackCheck(Node* node) {
// Simplified operators. // Simplified operators.
Bounds Typer::Visitor::TypeAnyToBoolean(Node* node) {
return TypeUnaryOp(node, ToBoolean);
}
Bounds Typer::Visitor::TypeBooleanNot(Node* node) { Bounds Typer::Visitor::TypeBooleanNot(Node* node) {
return Bounds(Type::None(zone()), Type::Boolean(zone())); return Bounds(Type::None(zone()), Type::Boolean(zone()));
} }
......
...@@ -557,10 +557,6 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -557,10 +557,6 @@ void Verifier::Visitor::Check(Node* node) {
// Simplified operators // Simplified operators
// ------------------------------- // -------------------------------
case IrOpcode::kAnyToBoolean:
// Type is Boolean.
CheckUpperIs(node, Type::Boolean());
break;
case IrOpcode::kBooleanNot: case IrOpcode::kBooleanNot:
// Boolean -> Boolean // Boolean -> Boolean
CheckValueInputIs(node, 0, Type::Boolean()); CheckValueInputIs(node, 0, Type::Boolean());
......
...@@ -507,42 +507,6 @@ TEST(JSToNumberOfNumberOrOtherPrimitive) { ...@@ -507,42 +507,6 @@ TEST(JSToNumberOfNumberOrOtherPrimitive) {
} }
TEST(JSToBoolean) {
JSTypedLoweringTester R;
const Operator* op = R.javascript.ToBoolean();
{ // ToBoolean(undefined)
Node* r = R.ReduceUnop(op, Type::Undefined());
R.CheckFalse(r);
}
{ // ToBoolean(null)
Node* r = R.ReduceUnop(op, Type::Null());
R.CheckFalse(r);
}
{ // ToBoolean(boolean)
Node* r = R.ReduceUnop(op, Type::Boolean());
CHECK_EQ(IrOpcode::kParameter, r->opcode());
}
{ // ToBoolean(object)
Node* r = R.ReduceUnop(op, Type::DetectableObject());
R.CheckTrue(r);
}
{ // ToBoolean(undetectable)
Node* r = R.ReduceUnop(op, Type::Undetectable());
R.CheckFalse(r);
}
{ // ToBoolean(object)
Node* r = R.ReduceUnop(op, Type::Object());
CHECK_EQ(IrOpcode::kAnyToBoolean, r->opcode());
}
}
TEST(JSToString1) { TEST(JSToString1) {
JSTypedLoweringTester R; JSTypedLoweringTester R;
...@@ -724,24 +688,6 @@ TEST(MixedComparison1) { ...@@ -724,24 +688,6 @@ TEST(MixedComparison1) {
} }
TEST(UnaryNot) {
JSTypedLoweringTester R;
const Operator* opnot = R.javascript.UnaryNot();
for (size_t i = 0; i < arraysize(kJSTypes); i++) {
Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i]));
Node* r = R.reduce(orig);
if (r == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
// The original node was turned into a ToBoolean.
CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
} else if (r->opcode() != IrOpcode::kHeapConstant) {
CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
}
}
}
TEST(RemoveToNumberEffects) { TEST(RemoveToNumberEffects) {
FLAG_turbo_deoptimization = true; FLAG_turbo_deoptimization = true;
......
...@@ -790,25 +790,6 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { ...@@ -790,25 +790,6 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
}; };
#if V8_TURBOFAN_TARGET
TEST(LowerAnyToBoolean_tagged_tagged) {
// AnyToBoolean(x: kRepTagged) used as kRepTagged
TestingGraph t(Type::Any());
Node* x = t.p0;
Node* cnv = t.graph()->NewNode(t.simplified()->AnyToBoolean(), x);
Node* use = t.Use(cnv, kRepTagged);
t.Return(use);
t.Lower();
CHECK_EQ(IrOpcode::kCall, cnv->opcode());
CHECK_EQ(IrOpcode::kHeapConstant, cnv->InputAt(0)->opcode());
CHECK_EQ(x, cnv->InputAt(1));
CHECK_EQ(t.jsgraph.NoContextConstant(), cnv->InputAt(2));
}
#endif
TEST(LowerBooleanNot_bit_bit) { TEST(LowerBooleanNot_bit_bit) {
// BooleanNot(x: kRepBit) used as kRepBit // BooleanNot(x: kRepBit) used as kRepBit
TestingGraph t(Type::Boolean()); TestingGraph t(Type::Boolean());
......
...@@ -184,13 +184,25 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithNonZeroPlainNumber) { ...@@ -184,13 +184,25 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithNonZeroPlainNumber) {
} }
TEST_F(JSTypedLoweringTest, JSUnaryNotWithString) {
Node* input = Parameter(Type::String(), 0);
Node* context = Parameter(Type::Any(), 1);
Reduction r =
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(), input,
graph()->start(), graph()->start()),
IsNumberConstant(0.0)));
}
TEST_F(JSTypedLoweringTest, JSUnaryNotWithAny) { TEST_F(JSTypedLoweringTest, JSUnaryNotWithAny) {
Node* input = Parameter(Type::Any(), 0); Node* input = Parameter(Type::Any(), 0);
Node* context = Parameter(Type::Any(), 1); Node* context = Parameter(Type::Any(), 1);
Reduction r = Reduction r =
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context)); Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
ASSERT_TRUE(r.Changed()); ASSERT_FALSE(r.Changed());
EXPECT_THAT(r.replacement(), IsBooleanNot(IsAnyToBoolean(input)));
} }
...@@ -360,13 +372,37 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithNonZeroPlainNumber) { ...@@ -360,13 +372,37 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithNonZeroPlainNumber) {
} }
TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) {
Node* input = Parameter(Type::OrderedNumber(), 0);
Node* context = Parameter(Type::Any(), 1);
Reduction r =
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsBooleanNot(IsNumberEqual(input, IsNumberConstant(0.0))));
}
TEST_F(JSTypedLoweringTest, JSToBooleanWithString) {
Node* input = Parameter(Type::String(), 0);
Node* context = Parameter(Type::Any(), 1);
Reduction r =
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(
r.replacement(),
IsNumberLessThan(IsNumberConstant(0.0),
IsLoadField(AccessBuilder::ForStringLength(), input,
graph()->start(), graph()->start())));
}
TEST_F(JSTypedLoweringTest, JSToBooleanWithAny) { TEST_F(JSTypedLoweringTest, JSToBooleanWithAny) {
Node* input = Parameter(Type::Any(), 0); Node* input = Parameter(Type::Any(), 0);
Node* context = Parameter(Type::Any(), 1); Node* context = Parameter(Type::Any(), 1);
Reduction r = Reduction r =
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context)); Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
ASSERT_TRUE(r.Changed()); ASSERT_FALSE(r.Changed());
EXPECT_THAT(r.replacement(), IsAnyToBoolean(input));
} }
......
...@@ -1602,7 +1602,6 @@ IS_BINOP_MATCHER(Float64InsertHighWord32) ...@@ -1602,7 +1602,6 @@ IS_BINOP_MATCHER(Float64InsertHighWord32)
Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \ Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \
return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \ return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
} }
IS_UNOP_MATCHER(AnyToBoolean)
IS_UNOP_MATCHER(BooleanNot) IS_UNOP_MATCHER(BooleanNot)
IS_UNOP_MATCHER(ChangeFloat64ToInt32) IS_UNOP_MATCHER(ChangeFloat64ToInt32)
IS_UNOP_MATCHER(ChangeFloat64ToUint32) IS_UNOP_MATCHER(ChangeFloat64ToUint32)
......
...@@ -101,7 +101,6 @@ Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher, ...@@ -101,7 +101,6 @@ Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
const Matcher<Node*>& effect_matcher, const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher); const Matcher<Node*>& control_matcher);
Matcher<Node*> IsAnyToBoolean(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher); Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsNumberEqual(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsNumberEqual(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher); const Matcher<Node*>& rhs_matcher);
......
...@@ -118,39 +118,6 @@ const double kNaNs[] = {-std::numeric_limits<double>::quiet_NaN(), ...@@ -118,39 +118,6 @@ const double kNaNs[] = {-std::numeric_limits<double>::quiet_NaN(),
} // namespace } // namespace
// -----------------------------------------------------------------------------
// AnyToBoolean
TEST_F(SimplifiedOperatorReducerTest, AnyToBooleanWithBoolean) {
Node* p = Parameter(Type::Boolean());
Reduction r = Reduce(graph()->NewNode(simplified()->AnyToBoolean(), p));
ASSERT_TRUE(r.Changed());
EXPECT_EQ(p, r.replacement());
}
TEST_F(SimplifiedOperatorReducerTest, AnyToBooleanWithOrderedNumber) {
Node* p = Parameter(Type::OrderedNumber());
Reduction r = Reduce(graph()->NewNode(simplified()->AnyToBoolean(), p));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsBooleanNot(IsNumberEqual(p, IsNumberConstant(0))));
}
TEST_F(SimplifiedOperatorReducerTest, AnyToBooleanWithString) {
Node* p = Parameter(Type::String());
Reduction r = Reduce(graph()->NewNode(simplified()->AnyToBoolean(), p));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsBooleanNot(
IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(), p,
graph()->start(), graph()->start()),
IsNumberConstant(0))));
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// BooleanNot // BooleanNot
......
...@@ -38,7 +38,6 @@ const PureOperator kPureOperators[] = { ...@@ -38,7 +38,6 @@ const PureOperator kPureOperators[] = {
&SimplifiedOperatorBuilder::Name, IrOpcode::k##Name, \ &SimplifiedOperatorBuilder::Name, IrOpcode::k##Name, \
Operator::kPure | properties, input_count \ Operator::kPure | properties, input_count \
} }
PURE(AnyToBoolean, Operator::kNoProperties, 1),
PURE(BooleanNot, Operator::kNoProperties, 1), PURE(BooleanNot, Operator::kNoProperties, 1),
PURE(BooleanToNumber, Operator::kNoProperties, 1), PURE(BooleanToNumber, Operator::kNoProperties, 1),
PURE(NumberEqual, Operator::kCommutative, 2), PURE(NumberEqual, Operator::kCommutative, 2),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment