[turbofan] do not remove speculative Number operations when they can deopt
We cannot remove a speculative operation when it's type relies on it to deopt. Fix this by only relying on the lowering to remove operations. Bug: chromium:786521 Change-Id: I2cf45e8d45b76cfeb06e6329f323cade74719124 Reviewed-on: https://chromium-review.googlesource.com/793043 Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#49882}
This commit is contained in:
parent
a6790e0d64
commit
2290ad8b55
@ -1345,17 +1345,6 @@ class RepresentationSelector {
|
||||
|
||||
void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
|
||||
SimplifiedLowering* lowering) {
|
||||
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can
|
||||
// only eliminate an unused speculative number operation if we know that
|
||||
// the inputs are PlainPrimitive, which excludes everything that's might
|
||||
// have side effects or throws during a ToNumber conversion. We are only
|
||||
// allowed to perform a number addition if neither input is a String, even
|
||||
// if the value is never used, so we further limit to NumberOrOddball in
|
||||
// order to explicitly exclude String inputs.
|
||||
if (BothInputsAre(node, Type::NumberOrOddball())) {
|
||||
if (truncation.IsUnused()) return VisitUnused(node);
|
||||
}
|
||||
|
||||
if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
|
||||
(GetUpperBound(node)->Is(Type::Signed32()) ||
|
||||
GetUpperBound(node)->Is(Type::Unsigned32()) ||
|
||||
@ -1377,13 +1366,6 @@ class RepresentationSelector {
|
||||
|
||||
void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
|
||||
SimplifiedLowering* lowering) {
|
||||
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
|
||||
// can only eliminate an unused speculative number operation if we know
|
||||
// that the inputs are PlainPrimitive, which excludes everything that's
|
||||
// might have side effects or throws during a ToNumber conversion.
|
||||
if (BothInputsAre(node, Type::PlainPrimitive())) {
|
||||
if (truncation.IsUnused()) return VisitUnused(node);
|
||||
}
|
||||
if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
|
||||
(truncation.IsUsedAsWord32() ||
|
||||
NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
|
||||
@ -1668,13 +1650,6 @@ class RepresentationSelector {
|
||||
case IrOpcode::kSpeculativeNumberLessThan:
|
||||
case IrOpcode::kSpeculativeNumberLessThanOrEqual:
|
||||
case IrOpcode::kSpeculativeNumberEqual: {
|
||||
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
|
||||
// can only eliminate an unused speculative number operation if we know
|
||||
// that the inputs are PlainPrimitive, which excludes everything that's
|
||||
// might have side effects or throws during a ToNumber conversion.
|
||||
if (BothInputsAre(node, Type::PlainPrimitive())) {
|
||||
if (truncation.IsUnused()) return VisitUnused(node);
|
||||
}
|
||||
// Number comparisons reduce to integer comparisons for integer inputs.
|
||||
if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
|
||||
TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
|
||||
@ -1755,13 +1730,6 @@ class RepresentationSelector {
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kSpeculativeNumberMultiply: {
|
||||
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
|
||||
// can only eliminate an unused speculative number operation if we know
|
||||
// that the inputs are PlainPrimitive, which excludes everything that's
|
||||
// might have side effects or throws during a ToNumber conversion.
|
||||
if (BothInputsAre(node, Type::PlainPrimitive())) {
|
||||
if (truncation.IsUnused()) return VisitUnused(node);
|
||||
}
|
||||
if (BothInputsAre(node, Type::Integral32()) &&
|
||||
(NodeProperties::GetType(node)->Is(Type::Signed32()) ||
|
||||
NodeProperties::GetType(node)->Is(Type::Unsigned32()) ||
|
||||
@ -1836,13 +1804,6 @@ class RepresentationSelector {
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kSpeculativeNumberDivide: {
|
||||
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
|
||||
// can only eliminate an unused speculative number operation if we know
|
||||
// that the inputs are PlainPrimitive, which excludes everything that's
|
||||
// might have side effects or throws during a ToNumber conversion.
|
||||
if (BothInputsAre(node, Type::PlainPrimitive())) {
|
||||
if (truncation.IsUnused()) return VisitUnused(node);
|
||||
}
|
||||
if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
|
||||
// => unsigned Uint32Div
|
||||
VisitWord32TruncatingBinop(node);
|
||||
@ -2014,13 +1975,6 @@ class RepresentationSelector {
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kSpeculativeNumberShiftLeft: {
|
||||
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
|
||||
// can only eliminate an unused speculative number operation if we know
|
||||
// that the inputs are PlainPrimitive, which excludes everything that's
|
||||
// might have side effects or throws during a ToNumber conversion.
|
||||
if (BothInputsAre(node, Type::PlainPrimitive())) {
|
||||
if (truncation.IsUnused()) return VisitUnused(node);
|
||||
}
|
||||
if (BothInputsAre(node, Type::NumberOrOddball())) {
|
||||
Type* rhs_type = GetUpperBound(node->InputAt(1));
|
||||
VisitBinop(node, UseInfo::TruncatingWord32(),
|
||||
@ -2050,13 +2004,6 @@ class RepresentationSelector {
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kSpeculativeNumberShiftRight: {
|
||||
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
|
||||
// can only eliminate an unused speculative number operation if we know
|
||||
// that the inputs are PlainPrimitive, which excludes everything that's
|
||||
// might have side effects or throws during a ToNumber conversion.
|
||||
if (BothInputsAre(node, Type::PlainPrimitive())) {
|
||||
if (truncation.IsUnused()) return VisitUnused(node);
|
||||
}
|
||||
if (BothInputsAre(node, Type::NumberOrOddball())) {
|
||||
Type* rhs_type = GetUpperBound(node->InputAt(1));
|
||||
VisitBinop(node, UseInfo::TruncatingWord32(),
|
||||
@ -2086,13 +2033,6 @@ class RepresentationSelector {
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kSpeculativeNumberShiftRightLogical: {
|
||||
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
|
||||
// can only eliminate an unused speculative number operation if we know
|
||||
// that the inputs are PlainPrimitive, which excludes everything that
|
||||
// might have side effects or throw during a ToNumber conversion.
|
||||
if (BothInputsAre(node, Type::PlainPrimitive())) {
|
||||
if (truncation.IsUnused()) return VisitUnused(node);
|
||||
}
|
||||
NumberOperationHint hint = NumberOperationHintOf(node->op());
|
||||
Type* rhs_type = GetUpperBound(node->InputAt(1));
|
||||
if (rhs_type->Is(type_cache_.kZeroish) &&
|
||||
|
23
test/mjsunit/compiler/regress-786521.js
Normal file
23
test/mjsunit/compiler/regress-786521.js
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
// Provoke type None as result of a SpeculativeNumberMultiply to
|
||||
// ensure that Turbofan can handle this.
|
||||
|
||||
function inlined(b, x) {
|
||||
if (b) {
|
||||
x * 2 * 2
|
||||
}
|
||||
}
|
||||
|
||||
inlined(true, 1);
|
||||
inlined(true, 2);
|
||||
inlined(false, 1);
|
||||
|
||||
function foo(b) { inlined(b, "") }
|
||||
foo(false); foo(false);
|
||||
%OptimizeFunctionOnNextCall(foo);
|
||||
foo(true);
|
Loading…
Reference in New Issue
Block a user