| Index: src/compiler/js-typed-lowering.cc
 | 
| diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc
 | 
| index ccdf13879ad7d9b6174c481f8cc77a83f80c91fc..43397996a07aa1b9c0b7e622785fa36c7c54c97e 100644
 | 
| --- a/src/compiler/js-typed-lowering.cc
 | 
| +++ b/src/compiler/js-typed-lowering.cc
 | 
| @@ -70,6 +70,7 @@ class JSBinopReduction final {
 | 
|          case CompareOperationHint::kAny:
 | 
|          case CompareOperationHint::kNone:
 | 
|          case CompareOperationHint::kString:
 | 
| +        case CompareOperationHint::kReceiver:
 | 
|          case CompareOperationHint::kInternalizedString:
 | 
|            break;
 | 
|        }
 | 
| @@ -87,6 +88,16 @@ class JSBinopReduction final {
 | 
|      return false;
 | 
|    }
 | 
|  
 | 
| +  bool IsReceiverCompareOperation() {
 | 
| +    if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
 | 
| +      DCHECK_EQ(1, node_->op()->EffectOutputCount());
 | 
| +      return (CompareOperationHintOf(node_->op()) ==
 | 
| +              CompareOperationHint::kReceiver) &&
 | 
| +             BothInputsMaybe(Type::Receiver());
 | 
| +    }
 | 
| +    return false;
 | 
| +  }
 | 
| +
 | 
|    // Check if a string addition will definitely result in creating a ConsString,
 | 
|    // i.e. if the combined length of the resulting string exceeds the ConsString
 | 
|    // minimum length.
 | 
| @@ -115,6 +126,29 @@ class JSBinopReduction final {
 | 
|      return false;
 | 
|    }
 | 
|  
 | 
| +  // Inserts a CheckReceiver for the left input.
 | 
| +  void CheckLeftInputToReceiver() {
 | 
| +    Node* left_input = graph()->NewNode(simplified()->CheckReceiver(), left(),
 | 
| +                                        effect(), control());
 | 
| +    node_->ReplaceInput(0, left_input);
 | 
| +    update_effect(left_input);
 | 
| +  }
 | 
| +
 | 
| +  // Checks that both inputs are Receiver, and if we don't know
 | 
| +  // statically that one side is already a Receiver, insert a
 | 
| +  // CheckReceiver node.
 | 
| +  void CheckInputsToReceiver() {
 | 
| +    if (!left_type()->Is(Type::Receiver())) {
 | 
| +      CheckLeftInputToReceiver();
 | 
| +    }
 | 
| +    if (!right_type()->Is(Type::Receiver())) {
 | 
| +      Node* right_input = graph()->NewNode(simplified()->CheckReceiver(),
 | 
| +                                           right(), effect(), control());
 | 
| +      node_->ReplaceInput(1, right_input);
 | 
| +      update_effect(right_input);
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
|    // Checks that both inputs are InternalizedString, and if we don't know
 | 
|    // statically that one side is already an InternalizedString, insert a
 | 
|    // CheckInternalizedString node.
 | 
| @@ -924,6 +958,9 @@ Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) {
 | 
|          simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
 | 
|    } else if (r.BothInputsAre(Type::Number())) {
 | 
|      return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
 | 
| +  } else if (r.IsReceiverCompareOperation()) {
 | 
| +    r.CheckInputsToReceiver();
 | 
| +    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
 | 
|    }
 | 
|    return NoChange();
 | 
|  }
 | 
| @@ -975,6 +1012,12 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
 | 
|          simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
 | 
|    } else if (r.BothInputsAre(Type::Number())) {
 | 
|      return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
 | 
| +  } else if (r.IsReceiverCompareOperation()) {
 | 
| +    // For strict equality, it's enough to know that one input is a Receiver,
 | 
| +    // as a strict equality comparison with a Receiver can only yield true if
 | 
| +    // both sides refer to the same Receiver than.
 | 
| +    r.CheckLeftInputToReceiver();
 | 
| +    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
 | 
|    }
 | 
|    return NoChange();
 | 
|  }
 | 
| 
 |