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 |