| Index: src/compiler/js-typed-lowering.cc
|
| diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc
|
| index 27271fcdb3fb30b716dc2ba32c4f53e9c6021a06..fed84d43aa57f9be5f9bd2386fd4be5490fc3641 100644
|
| --- a/src/compiler/js-typed-lowering.cc
|
| +++ b/src/compiler/js-typed-lowering.cc
|
| @@ -840,6 +840,67 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
|
| return NoChange();
|
| }
|
|
|
| +Reduction JSTypedLowering::ReduceJSSameValueZero(Node* node) {
|
| + const bool invert = false;
|
| +
|
| + JSBinopReduction r(this, node);
|
| + if (r.left() == r.right()) {
|
| + // x === x is always true, even if x === NaN
|
| + Node* replacement = jsgraph()->BooleanConstant(!invert);
|
| + ReplaceWithValue(node, replacement);
|
| + return Replace(replacement);
|
| + }
|
| + if (r.OneInputCannotBe(Type::NumberOrSimdOrString())) {
|
| + // For values with canonical representation (i.e. neither String, nor
|
| + // Simd128Value nor Number) an empty type intersection means the values
|
| + // cannot be strictly equal.
|
| + if (!r.left_type()->Maybe(r.right_type())) {
|
| + Node* replacement = jsgraph()->BooleanConstant(invert);
|
| + ReplaceWithValue(node, replacement);
|
| + return Replace(replacement);
|
| + }
|
| + }
|
| + Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
|
| + if (reduction.Changed()) {
|
| + return reduction;
|
| + }
|
| + if (r.OneInputIs(the_hole_type_)) {
|
| + return r.ChangeToPureOperator(simplified()->ReferenceEqual(the_hole_type_),
|
| + invert);
|
| + }
|
| + if (r.OneInputIs(Type::Undefined())) {
|
| + return r.ChangeToPureOperator(
|
| + simplified()->ReferenceEqual(Type::Undefined()), invert);
|
| + }
|
| + if (r.OneInputIs(Type::Null())) {
|
| + return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Null()),
|
| + invert);
|
| + }
|
| + if (r.OneInputIs(Type::Boolean())) {
|
| + return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()),
|
| + invert);
|
| + }
|
| + if (r.OneInputIs(Type::Object())) {
|
| + return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Object()),
|
| + invert);
|
| + }
|
| + if (r.OneInputIs(Type::Receiver())) {
|
| + return r.ChangeToPureOperator(
|
| + simplified()->ReferenceEqual(Type::Receiver()), invert);
|
| + }
|
| + if (r.BothInputsAre(Type::Unique())) {
|
| + return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()),
|
| + invert);
|
| + }
|
| + if (r.BothInputsAre(Type::String())) {
|
| + return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
|
| + }
|
| + if (r.BothInputsAre(Type::Number())) {
|
| + return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
|
| + }
|
| + // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types)
|
| + return NoChange();
|
| +}
|
|
|
| Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
|
| Node* const input = node->InputAt(0);
|
| @@ -1956,6 +2017,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
|
| return ReduceJSStrictEqual(node, false);
|
| case IrOpcode::kJSStrictNotEqual:
|
| return ReduceJSStrictEqual(node, true);
|
| + case IrOpcode::kJSSameValueZero:
|
| + return ReduceJSSameValueZero(node);
|
| case IrOpcode::kJSLessThan: // fall through
|
| case IrOpcode::kJSGreaterThan: // fall through
|
| case IrOpcode::kJSLessThanOrEqual: // fall through
|
|
|