diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc index eb2f67f669..5652c47d97 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. @@ -816,6 +844,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(); } @@ -975,6 +1007,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(); } @@ -1032,6 +1067,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(); }