Commit 904ac0ae authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Make string comparisons effectful.

BUG=v8:4446
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#31006}
parent d06930fc
...@@ -181,6 +181,32 @@ class JSBinopReduction final { ...@@ -181,6 +181,32 @@ class JSBinopReduction final {
return lowering_->Changed(node_); return lowering_->Changed(node_);
} }
Reduction ChangeToStringComparisonOperator(const Operator* op,
bool invert = false) {
if (node_->op()->ControlInputCount() > 0) {
lowering_->RelaxControls(node_);
}
// String comparison operators need effect and control inputs, so copy them
// over.
Node* effect = NodeProperties::GetEffectInput(node_);
Node* control = NodeProperties::GetControlInput(node_);
node_->ReplaceInput(2, effect);
node_->ReplaceInput(3, control);
node_->TrimInputCount(4);
NodeProperties::ChangeOp(node_, op);
if (invert) {
// Insert a boolean-not to invert the value.
Node* value = graph()->NewNode(simplified()->BooleanNot(), node_);
node_->ReplaceUses(value);
// Note: ReplaceUses() smashes all uses, so smash it back here.
value->ReplaceInput(0, node_);
return lowering_->Replace(value);
}
return lowering_->Changed(node_);
}
Reduction ChangeToPureOperator(const Operator* op, Type* type) { Reduction ChangeToPureOperator(const Operator* op, Type* type) {
return ChangeToPureOperator(op, false, type); return ChangeToPureOperator(op, false, type);
} }
...@@ -503,7 +529,8 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) { ...@@ -503,7 +529,8 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
default: default:
return NoChange(); return NoChange();
} }
return r.ChangeToPureOperator(stringOp); r.ChangeToStringComparisonOperator(stringOp);
return Changed(node);
} }
if (r.OneInputCannotBe(Type::StringOrReceiver())) { if (r.OneInputCannotBe(Type::StringOrReceiver())) {
const Operator* less_than; const Operator* less_than;
...@@ -557,7 +584,8 @@ Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { ...@@ -557,7 +584,8 @@ Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) {
return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
} }
if (r.BothInputsAre(Type::String())) { if (r.BothInputsAre(Type::String())) {
return r.ChangeToPureOperator(simplified()->StringEqual(), invert); return r.ChangeToStringComparisonOperator(simplified()->StringEqual(),
invert);
} }
if (r.BothInputsAre(Type::Receiver())) { if (r.BothInputsAre(Type::Receiver())) {
return r.ChangeToPureOperator( return r.ChangeToPureOperator(
...@@ -614,7 +642,8 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { ...@@ -614,7 +642,8 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
invert); invert);
} }
if (r.BothInputsAre(Type::String())) { if (r.BothInputsAre(Type::String())) {
return r.ChangeToPureOperator(simplified()->StringEqual(), invert); return r.ChangeToStringComparisonOperator(simplified()->StringEqual(),
invert);
} }
if (r.BothInputsAre(Type::Number())) { if (r.BothInputsAre(Type::Number())) {
return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
......
...@@ -1363,7 +1363,9 @@ Node* SimplifiedLowering::StringComparison(Node* node) { ...@@ -1363,7 +1363,9 @@ Node* SimplifiedLowering::StringComparison(Node* node) {
return graph()->NewNode( return graph()->NewNode(
common()->Call(desc), jsgraph()->HeapConstant(callable.code()), common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
NodeProperties::GetValueInput(node, 0), NodeProperties::GetValueInput(node, 0),
NodeProperties::GetValueInput(node, 1), jsgraph()->NoContextConstant()); NodeProperties::GetValueInput(node, 1), jsgraph()->NoContextConstant(),
NodeProperties::GetEffectInput(node),
NodeProperties::GetControlInput(node));
} }
...@@ -1627,23 +1629,49 @@ void SimplifiedLowering::DoShift(Node* node, Operator const* op) { ...@@ -1627,23 +1629,49 @@ void SimplifiedLowering::DoShift(Node* node, Operator const* op) {
} }
namespace {
void ReplaceEffectUses(Node* node, Node* replacement) {
// Requires distinguishing between value and effect edges.
DCHECK(replacement->op()->EffectOutputCount() > 0);
for (Edge edge : node->use_edges()) {
if (NodeProperties::IsEffectEdge(edge)) {
edge.UpdateTo(replacement);
} else {
DCHECK(NodeProperties::IsValueEdge(edge));
}
}
}
} // namespace
void SimplifiedLowering::DoStringEqual(Node* node) { void SimplifiedLowering::DoStringEqual(Node* node) {
node->ReplaceInput(0, StringComparison(node)); Node* comparison = StringComparison(node);
ReplaceEffectUses(node, comparison);
node->ReplaceInput(0, comparison);
node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
node->TrimInputCount(2);
NodeProperties::ChangeOp(node, machine()->WordEqual()); NodeProperties::ChangeOp(node, machine()->WordEqual());
} }
void SimplifiedLowering::DoStringLessThan(Node* node) { void SimplifiedLowering::DoStringLessThan(Node* node) {
node->ReplaceInput(0, StringComparison(node)); Node* comparison = StringComparison(node);
ReplaceEffectUses(node, comparison);
node->ReplaceInput(0, comparison);
node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
node->TrimInputCount(2);
NodeProperties::ChangeOp(node, machine()->IntLessThan()); NodeProperties::ChangeOp(node, machine()->IntLessThan());
} }
void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
node->ReplaceInput(0, StringComparison(node)); Node* comparison = StringComparison(node);
ReplaceEffectUses(node, comparison);
node->ReplaceInput(0, comparison);
node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
node->TrimInputCount(2);
NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual());
} }
......
...@@ -174,9 +174,6 @@ const ElementAccess& ElementAccessOf(const Operator* op) { ...@@ -174,9 +174,6 @@ const ElementAccess& ElementAccessOf(const Operator* op) {
V(NumberToInt32, Operator::kNoProperties, 1) \ V(NumberToInt32, Operator::kNoProperties, 1) \
V(NumberToUint32, Operator::kNoProperties, 1) \ V(NumberToUint32, Operator::kNoProperties, 1) \
V(PlainPrimitiveToNumber, Operator::kNoProperties, 1) \ V(PlainPrimitiveToNumber, Operator::kNoProperties, 1) \
V(StringEqual, Operator::kCommutative, 2) \
V(StringLessThan, Operator::kNoProperties, 2) \
V(StringLessThanOrEqual, Operator::kNoProperties, 2) \
V(ChangeTaggedToInt32, Operator::kNoProperties, 1) \ V(ChangeTaggedToInt32, Operator::kNoProperties, 1) \
V(ChangeTaggedToUint32, Operator::kNoProperties, 1) \ V(ChangeTaggedToUint32, Operator::kNoProperties, 1) \
V(ChangeTaggedToFloat64, Operator::kNoProperties, 1) \ V(ChangeTaggedToFloat64, Operator::kNoProperties, 1) \
...@@ -187,6 +184,10 @@ const ElementAccess& ElementAccessOf(const Operator* op) { ...@@ -187,6 +184,10 @@ const ElementAccess& ElementAccessOf(const Operator* op) {
V(ChangeBitToBool, Operator::kNoProperties, 1) \ V(ChangeBitToBool, Operator::kNoProperties, 1) \
V(ObjectIsSmi, Operator::kNoProperties, 1) V(ObjectIsSmi, Operator::kNoProperties, 1)
#define NO_THROW_OP_LIST(V) \
V(StringEqual, Operator::kCommutative, 2) \
V(StringLessThan, Operator::kNoThrow, 2) \
V(StringLessThanOrEqual, Operator::kNoThrow, 2)
struct SimplifiedOperatorGlobalCache final { struct SimplifiedOperatorGlobalCache final {
#define PURE(Name, properties, input_count) \ #define PURE(Name, properties, input_count) \
...@@ -199,6 +200,16 @@ struct SimplifiedOperatorGlobalCache final { ...@@ -199,6 +200,16 @@ struct SimplifiedOperatorGlobalCache final {
PURE_OP_LIST(PURE) PURE_OP_LIST(PURE)
#undef PURE #undef PURE
#define NO_THROW(Name, properties, input_count) \
struct Name##Operator final : public Operator { \
Name##Operator() \
: Operator(IrOpcode::k##Name, Operator::kNoThrow | properties, #Name, \
input_count, 1, 1, 1, 1, 0) {} \
}; \
Name##Operator k##Name;
NO_THROW_OP_LIST(NO_THROW)
#undef NO_THROW
#define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \
struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \ struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \
LoadBuffer##Type##Operator() \ LoadBuffer##Type##Operator() \
...@@ -229,10 +240,11 @@ SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone) ...@@ -229,10 +240,11 @@ SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
: cache_(kCache.Get()), zone_(zone) {} : cache_(kCache.Get()), zone_(zone) {}
#define PURE(Name, properties, input_count) \ #define GET_FROM_CACHE(Name, properties, input_count) \
const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
PURE_OP_LIST(PURE) PURE_OP_LIST(GET_FROM_CACHE)
#undef PURE NO_THROW_OP_LIST(GET_FROM_CACHE)
#undef GET_FROM_CACHE
const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) { const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) {
......
...@@ -105,14 +105,12 @@ class JSTypedLoweringTester : public HandleAndZoneScope { ...@@ -105,14 +105,12 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
Node* control() { return start(); } Node* control() { return start(); }
void CheckPureBinop(IrOpcode::Value expected, Node* node) { void CheckBinop(IrOpcode::Value expected, Node* node) {
CHECK_EQ(expected, node->opcode()); CHECK_EQ(expected, node->opcode());
CHECK_EQ(2, node->InputCount()); // should not have context, effect, etc.
} }
void CheckPureBinop(const Operator* expected, Node* node) { void CheckBinop(const Operator* expected, Node* node) {
CHECK_EQ(expected->opcode(), node->op()->opcode()); CHECK_EQ(expected->opcode(), node->op()->opcode());
CHECK_EQ(2, node->InputCount()); // should not have context, effect, etc.
} }
Node* ReduceUnop(const Operator* op, Type* input_type) { Node* ReduceUnop(const Operator* op, Type* input_type) {
...@@ -249,7 +247,7 @@ TEST_WITH_STRONG(StringBinops) { ...@@ -249,7 +247,7 @@ TEST_WITH_STRONG(StringBinops) {
Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1); Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1);
Node* r = R.reduce(add); Node* r = R.reduce(add);
R.CheckPureBinop(IrOpcode::kStringAdd, r); R.CheckBinop(IrOpcode::kStringAdd, r);
CHECK_EQ(p0, r->InputAt(0)); CHECK_EQ(p0, r->InputAt(0));
CHECK_EQ(p1, r->InputAt(1)); CHECK_EQ(p1, r->InputAt(1));
} }
...@@ -266,7 +264,7 @@ TEST_WITH_STRONG(AddNumber1) { ...@@ -266,7 +264,7 @@ TEST_WITH_STRONG(AddNumber1) {
Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1); Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1);
Node* r = R.reduce(add); Node* r = R.reduce(add);
R.CheckPureBinop(IrOpcode::kNumberAdd, r); R.CheckBinop(IrOpcode::kNumberAdd, r);
CHECK_EQ(p0, r->InputAt(0)); CHECK_EQ(p0, r->InputAt(0));
CHECK_EQ(p1, r->InputAt(1)); CHECK_EQ(p1, r->InputAt(1));
} }
...@@ -293,7 +291,7 @@ TEST_WITH_STRONG(NumberBinops) { ...@@ -293,7 +291,7 @@ TEST_WITH_STRONG(NumberBinops) {
Node* add = R.Binop(ops[k], p0, p1); Node* add = R.Binop(ops[k], p0, p1);
Node* r = R.reduce(add); Node* r = R.reduce(add);
R.CheckPureBinop(ops[k + 1], r); R.CheckBinop(ops[k + 1], r);
CHECK_EQ(p0, r->InputAt(0)); CHECK_EQ(p0, r->InputAt(0));
CHECK_EQ(p1, r->InputAt(1)); CHECK_EQ(p1, r->InputAt(1));
} }
...@@ -363,7 +361,7 @@ TEST(Int32BitwiseShifts) { ...@@ -363,7 +361,7 @@ TEST(Int32BitwiseShifts) {
Node* add = R.Binop(R.ops[k], p0, p1); Node* add = R.Binop(R.ops[k], p0, p1);
Node* r = R.reduce(add); Node* r = R.reduce(add);
R.CheckPureBinop(R.ops[k + 1], r); R.CheckBinop(R.ops[k + 1], r);
Node* r0 = r->InputAt(0); Node* r0 = r->InputAt(0);
Node* r1 = r->InputAt(1); Node* r1 = r->InputAt(1);
...@@ -421,7 +419,7 @@ TEST(Int32BitwiseBinops) { ...@@ -421,7 +419,7 @@ TEST(Int32BitwiseBinops) {
Node* add = R.Binop(R.ops[k], p0, p1); Node* add = R.Binop(R.ops[k], p0, p1);
Node* r = R.reduce(add); Node* r = R.reduce(add);
R.CheckPureBinop(R.ops[k + 1], r); R.CheckBinop(R.ops[k + 1], r);
CheckToI32(p0, r->InputAt(0), R.signedness[k]); CheckToI32(p0, r->InputAt(0), R.signedness[k]);
CheckToI32(p1, r->InputAt(1), R.signedness[k + 1]); CheckToI32(p1, r->InputAt(1), R.signedness[k + 1]);
...@@ -614,7 +612,7 @@ TEST_WITH_STRONG(StringComparison) { ...@@ -614,7 +612,7 @@ TEST_WITH_STRONG(StringComparison) {
Node* cmp = R.Binop(ops[k], p0, p1); Node* cmp = R.Binop(ops[k], p0, p1);
Node* r = R.reduce(cmp); Node* r = R.reduce(cmp);
R.CheckPureBinop(ops[k + 1], r); R.CheckBinop(ops[k + 1], r);
if (k >= 4) { if (k >= 4) {
// GreaterThan and GreaterThanOrEqual commute the inputs // GreaterThan and GreaterThanOrEqual commute the inputs
// and use the LessThan and LessThanOrEqual operators. // and use the LessThan and LessThanOrEqual operators.
...@@ -662,7 +660,7 @@ TEST_WITH_STRONG(NumberComparison) { ...@@ -662,7 +660,7 @@ TEST_WITH_STRONG(NumberComparison) {
Node* cmp = R.Binop(ops[k], p0, p1); Node* cmp = R.Binop(ops[k], p0, p1);
Node* r = R.reduce(cmp); Node* r = R.reduce(cmp);
R.CheckPureBinop(ops[k + 1], r); R.CheckBinop(ops[k + 1], r);
if (k >= 4) { if (k >= 4) {
// GreaterThan and GreaterThanOrEqual commute the inputs // GreaterThan and GreaterThanOrEqual commute the inputs
// and use the LessThan and LessThanOrEqual operators. // and use the LessThan and LessThanOrEqual operators.
...@@ -692,13 +690,13 @@ TEST_WITH_STRONG(MixedComparison1) { ...@@ -692,13 +690,13 @@ TEST_WITH_STRONG(MixedComparison1) {
Node* cmp = R.Binop(less_than, p0, p1); Node* cmp = R.Binop(less_than, p0, p1);
Node* r = R.reduce(cmp); Node* r = R.reduce(cmp);
if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) { if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
R.CheckPureBinop(R.simplified.StringLessThan(), r); R.CheckBinop(R.simplified.StringLessThan(), r);
} else if ((types[i]->Is(Type::Number()) && } else if ((types[i]->Is(Type::Number()) &&
types[j]->Is(Type::Number())) || types[j]->Is(Type::Number())) ||
(!is_strong(language_mode) && (!is_strong(language_mode) &&
(!types[i]->Maybe(Type::String()) || (!types[i]->Maybe(Type::String()) ||
!types[j]->Maybe(Type::String())))) { !types[j]->Maybe(Type::String())))) {
R.CheckPureBinop(R.simplified.NumberLessThan(), r); R.CheckBinop(R.simplified.NumberLessThan(), r);
} else { } else {
// No reduction of mixed types. // No reduction of mixed types.
CHECK_EQ(r->op(), less_than); CHECK_EQ(r->op(), less_than);
...@@ -839,7 +837,7 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l, ...@@ -839,7 +837,7 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l,
strict ? R->javascript.StrictEqual() : R->javascript.Equal(); strict ? R->javascript.StrictEqual() : R->javascript.Equal();
Node* eq = R->Binop(op, p0, p1); Node* eq = R->Binop(op, p0, p1);
Node* r = R->reduce(eq); Node* r = R->reduce(eq);
R->CheckPureBinop(expected, r); R->CheckBinop(expected, r);
} }
{ {
...@@ -849,7 +847,7 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l, ...@@ -849,7 +847,7 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l,
Node* n = R->reduce(ne); Node* n = R->reduce(ne);
CHECK_EQ(IrOpcode::kBooleanNot, n->opcode()); CHECK_EQ(IrOpcode::kBooleanNot, n->opcode());
Node* r = n->InputAt(0); Node* r = n->InputAt(0);
R->CheckPureBinop(expected, r); R->CheckBinop(expected, r);
} }
} }
} }
...@@ -920,7 +918,7 @@ TEST_WITH_STRONG(RemovePureNumberBinopEffects) { ...@@ -920,7 +918,7 @@ TEST_WITH_STRONG(RemovePureNumberBinopEffects) {
BinopEffectsTester B(ops[j], Type::Number(), Type::Number()); BinopEffectsTester B(ops[j], Type::Number(), Type::Number());
CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
B.R.CheckPureBinop(B.result->opcode(), B.result); B.R.CheckBinop(B.result->opcode(), B.result);
B.CheckNoOp(0); B.CheckNoOp(0);
B.CheckNoOp(1); B.CheckNoOp(1);
...@@ -1060,7 +1058,7 @@ TEST(Int32BinopEffects) { ...@@ -1060,7 +1058,7 @@ TEST(Int32BinopEffects) {
BinopEffectsTester B(R.ops[j], I32Type(signed_left), I32Type(signed_right)); BinopEffectsTester B(R.ops[j], I32Type(signed_left), I32Type(signed_right));
CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode()); CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode());
B.R.CheckPureBinop(B.result->opcode(), B.result); B.R.CheckBinop(B.result->opcode(), B.result);
B.CheckNoOp(0); B.CheckNoOp(0);
B.CheckNoOp(1); B.CheckNoOp(1);
...@@ -1073,7 +1071,7 @@ TEST(Int32BinopEffects) { ...@@ -1073,7 +1071,7 @@ TEST(Int32BinopEffects) {
BinopEffectsTester B(R.ops[j], Type::Number(), Type::Number()); BinopEffectsTester B(R.ops[j], Type::Number(), Type::Number());
CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode()); CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode());
B.R.CheckPureBinop(B.result->opcode(), B.result); B.R.CheckBinop(B.result->opcode(), B.result);
B.CheckConvertedInput(NumberToI32(signed_left), 0, false); B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
B.CheckConvertedInput(NumberToI32(signed_right), 1, false); B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
...@@ -1085,7 +1083,7 @@ TEST(Int32BinopEffects) { ...@@ -1085,7 +1083,7 @@ TEST(Int32BinopEffects) {
bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
BinopEffectsTester B(R.ops[j], Type::Number(), Type::Primitive()); BinopEffectsTester B(R.ops[j], Type::Number(), Type::Primitive());
B.R.CheckPureBinop(B.result->opcode(), B.result); B.R.CheckBinop(B.result->opcode(), B.result);
Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false); Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false); Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
...@@ -1102,7 +1100,7 @@ TEST(Int32BinopEffects) { ...@@ -1102,7 +1100,7 @@ TEST(Int32BinopEffects) {
bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Number()); BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Number());
B.R.CheckPureBinop(B.result->opcode(), B.result); B.R.CheckBinop(B.result->opcode(), B.result);
Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false); Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false); Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
...@@ -1119,7 +1117,7 @@ TEST(Int32BinopEffects) { ...@@ -1119,7 +1117,7 @@ TEST(Int32BinopEffects) {
bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Primitive()); BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Primitive());
B.R.CheckPureBinop(B.result->opcode(), B.result); B.R.CheckBinop(B.result->opcode(), B.result);
Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false); Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false);
Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false); Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false);
...@@ -1251,7 +1249,7 @@ TEST_WITH_STRONG(Int32Comparisons) { ...@@ -1251,7 +1249,7 @@ TEST_WITH_STRONG(Int32Comparisons) {
} else { } else {
expected = ops[o].num_op; expected = ops[o].num_op;
} }
R.CheckPureBinop(expected, r); R.CheckBinop(expected, r);
if (ops[o].commute) { if (ops[o].commute) {
CHECK_EQ(p1, r->InputAt(0)); CHECK_EQ(p1, r->InputAt(0));
CHECK_EQ(p0, r->InputAt(1)); CHECK_EQ(p0, r->InputAt(1));
......
...@@ -698,6 +698,13 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { ...@@ -698,6 +698,13 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
CHECK_EQ(expected, node->opcode()); CHECK_EQ(expected, node->opcode());
} }
void CheckLoweringStringBinop(IrOpcode::Value expected, const Operator* op) {
Node* node = Return(
graph()->NewNode(op, p0, p1, graph()->start(), graph()->start()));
Lower();
CHECK_EQ(expected, node->opcode());
}
void CheckLoweringTruncatedBinop(IrOpcode::Value expected, const Operator* op, void CheckLoweringTruncatedBinop(IrOpcode::Value expected, const Operator* op,
const Operator* trunc) { const Operator* trunc) {
Node* node = graph()->NewNode(op, p0, p1); Node* node = graph()->NewNode(op, p0, p1);
...@@ -1173,9 +1180,10 @@ TEST(LowerStringOps_to_call_and_compare) { ...@@ -1173,9 +1180,10 @@ TEST(LowerStringOps_to_call_and_compare) {
static_cast<IrOpcode::Value>(t.machine()->IntLessThan()->opcode()); static_cast<IrOpcode::Value>(t.machine()->IntLessThan()->opcode());
IrOpcode::Value compare_le = static_cast<IrOpcode::Value>( IrOpcode::Value compare_le = static_cast<IrOpcode::Value>(
t.machine()->IntLessThanOrEqual()->opcode()); t.machine()->IntLessThanOrEqual()->opcode());
t.CheckLoweringBinop(compare_eq, t.simplified()->StringEqual()); t.CheckLoweringStringBinop(compare_eq, t.simplified()->StringEqual());
t.CheckLoweringBinop(compare_lt, t.simplified()->StringLessThan()); t.CheckLoweringStringBinop(compare_lt, t.simplified()->StringLessThan());
t.CheckLoweringBinop(compare_le, t.simplified()->StringLessThanOrEqual()); t.CheckLoweringStringBinop(compare_le,
t.simplified()->StringLessThanOrEqual());
} }
......
...@@ -51,9 +51,6 @@ const PureOperator kPureOperators[] = { ...@@ -51,9 +51,6 @@ const PureOperator kPureOperators[] = {
PURE(NumberToInt32, Operator::kNoProperties, 1), PURE(NumberToInt32, Operator::kNoProperties, 1),
PURE(NumberToUint32, Operator::kNoProperties, 1), PURE(NumberToUint32, Operator::kNoProperties, 1),
PURE(PlainPrimitiveToNumber, Operator::kNoProperties, 1), PURE(PlainPrimitiveToNumber, Operator::kNoProperties, 1),
PURE(StringEqual, Operator::kCommutative, 2),
PURE(StringLessThan, Operator::kNoProperties, 2),
PURE(StringLessThanOrEqual, Operator::kNoProperties, 2),
PURE(ChangeTaggedToInt32, Operator::kNoProperties, 1), PURE(ChangeTaggedToInt32, Operator::kNoProperties, 1),
PURE(ChangeTaggedToUint32, Operator::kNoProperties, 1), PURE(ChangeTaggedToUint32, Operator::kNoProperties, 1),
PURE(ChangeTaggedToFloat64, Operator::kNoProperties, 1), PURE(ChangeTaggedToFloat64, Operator::kNoProperties, 1),
......
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