Index: src/compiler/js-generic-lowering.cc |
diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc |
index 5ff3c718c1be42254645318868137abbea44bc76..0483c72c711eb2989c1e3074875c4f0fc229fde1 100644 |
--- a/src/compiler/js-generic-lowering.cc |
+++ b/src/compiler/js-generic-lowering.cc |
@@ -130,6 +130,8 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) { |
CallDescriptor* desc_compare = Linkage::GetStubCallDescriptor( |
isolate(), zone(), callable.descriptor(), 0, |
CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node)); |
+ |
+ // Create a new call node asking a CompareIC for help. |
NodeVector inputs(zone()); |
inputs.reserve(node->InputCount() + 1); |
inputs.push_back(jsgraph()->HeapConstant(callable.code())); |
@@ -153,16 +155,53 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) { |
Node* compare = |
graph()->NewNode(common()->Call(desc_compare), |
static_cast<int>(inputs.size()), &inputs.front()); |
- |
- node->ReplaceInput(0, compare); |
- node->ReplaceInput(1, jsgraph()->SmiConstant(token)); |
- |
- if (has_frame_state) { |
- // Remove the frame state from inputs. |
- node->RemoveInput(NodeProperties::FirstFrameStateIndex(node)); |
+ NodeProperties::SetBounds( |
+ compare, Bounds(Type::None(zone()), Type::UntaggedSigned(zone()))); |
+ |
+ // Decide how the return value from the above CompareIC can be converted into |
+ // a JavaScript boolean oddball depending on the given token. |
+ Node* false_value = jsgraph()->FalseConstant(); |
+ Node* true_value = jsgraph()->TrueConstant(); |
+ const Operator* op = nullptr; |
+ switch (token) { |
+ case Token::EQ: // a == 0 |
+ case Token::EQ_STRICT: |
+ op = machine()->WordEqual(); |
+ break; |
+ case Token::NE: // a != 0 becomes !(a == 0) |
+ case Token::NE_STRICT: |
+ op = machine()->WordEqual(); |
+ std::swap(true_value, false_value); |
+ break; |
+ case Token::LT: // a < 0 |
+ op = machine()->IntLessThan(); |
+ break; |
+ case Token::GT: // a > 0 becomes !(a <= 0) |
+ op = machine()->IntLessThanOrEqual(); |
+ std::swap(true_value, false_value); |
+ break; |
+ case Token::LTE: // a <= 0 |
+ op = machine()->IntLessThanOrEqual(); |
+ break; |
+ case Token::GTE: // a >= 0 becomes !(a < 0) |
+ op = machine()->IntLessThan(); |
+ std::swap(true_value, false_value); |
+ break; |
+ default: |
+ UNREACHABLE(); |
} |
- |
- ReplaceWithRuntimeCall(node, Runtime::kBooleanize); |
+ Node* booleanize = graph()->NewNode(op, compare, jsgraph()->ZeroConstant()); |
+ |
+ // Finally patch the original node to select a boolean. |
+ NodeProperties::ReplaceWithValue(node, node, compare); |
+ // TODO(mstarzinger): Just a work-around because SelectLowering might |
+ // otherwise introduce a Phi without any uses, making Scheduler unhappy. |
+ if (node->UseCount() == 0) return; |
+ node->TrimInputCount(3); |
+ node->ReplaceInput(0, booleanize); |
+ node->ReplaceInput(1, true_value); |
+ node->ReplaceInput(2, false_value); |
+ PatchOperator(node, common()->Select(kMachAnyTagged)); |
} |