Commit 2290ad8b authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[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/793043Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49882}
parent a6790e0d
......@@ -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) &&
......
// 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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment