| Index: src/compiler/js-typed-lowering.cc | 
| diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc | 
| index 8920f4f16538472bc598f9ff98cf713a8b58eb1b..03576d8612ed632161cd74e47e38a679d6338410 100644 | 
| --- a/src/compiler/js-typed-lowering.cc | 
| +++ b/src/compiler/js-typed-lowering.cc | 
| @@ -98,6 +98,16 @@ class JSBinopReduction final { | 
| return false; | 
| } | 
|  | 
| +  bool IsStringCompareOperation() { | 
| +    if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { | 
| +      DCHECK_EQ(1, node_->op()->EffectOutputCount()); | 
| +      return (CompareOperationHintOf(node_->op()) == | 
| +              CompareOperationHint::kString) && | 
| +             BothInputsMaybe(Type::String()); | 
| +    } | 
| +    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. | 
| @@ -149,6 +159,24 @@ class JSBinopReduction final { | 
| } | 
| } | 
|  | 
| +  // Checks that both inputs are String, and if we don't know | 
| +  // statically that one side is already a String, insert a | 
| +  // CheckString node. | 
| +  void CheckInputsToString() { | 
| +    if (!left_type()->Is(Type::String())) { | 
| +      Node* left_input = graph()->NewNode(simplified()->CheckString(), left(), | 
| +                                          effect(), control()); | 
| +      node_->ReplaceInput(0, left_input); | 
| +      update_effect(left_input); | 
| +    } | 
| +    if (!right_type()->Is(Type::String())) { | 
| +      Node* right_input = graph()->NewNode(simplified()->CheckString(), 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. | 
| @@ -827,6 +855,10 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) { | 
| r.ConvertInputsToNumber(); | 
| less_than = simplified()->NumberLessThan(); | 
| less_than_or_equal = simplified()->NumberLessThanOrEqual(); | 
| +  } else if (r.IsStringCompareOperation()) { | 
| +    r.CheckInputsToString(); | 
| +    less_than = simplified()->StringLessThan(); | 
| +    less_than_or_equal = simplified()->StringLessThanOrEqual(); | 
| } else { | 
| return NoChange(); | 
| } | 
| @@ -986,6 +1018,9 @@ Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { | 
| } else if (r.IsReceiverCompareOperation()) { | 
| r.CheckInputsToReceiver(); | 
| return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); | 
| +  } else if (r.IsStringCompareOperation()) { | 
| +    r.CheckInputsToString(); | 
| +    return r.ChangeToPureOperator(simplified()->StringEqual(), invert); | 
| } | 
| return NoChange(); | 
| } | 
| @@ -1043,6 +1078,9 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { | 
| // both sides refer to the same Receiver than. | 
| r.CheckLeftInputToReceiver(); | 
| return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); | 
| +  } else if (r.IsStringCompareOperation()) { | 
| +    r.CheckInputsToString(); | 
| +    return r.ChangeToPureOperator(simplified()->StringEqual(), invert); | 
| } | 
| return NoChange(); | 
| } | 
|  |