[compiler] Speculate a little more in SpeculativeShiftRightLogical.

If the RHS is 0 and we have Smi feedback, speculate that the result (the LHS)
will continue to be in the Unsigned31 range.  This helps us avoid converting
the result to double when merging with Signed32.

R=jarin@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/2709423002
Cr-Commit-Position: refs/heads/master@{#43415}
This commit is contained in:
neis 2017-02-24 06:39:38 -08:00 committed by Commit bot
parent 2ab2bda50d
commit 42ded33b5b
2 changed files with 48 additions and 3 deletions

View File

@ -1986,8 +1986,26 @@ class RepresentationSelector {
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) &&
(hint == NumberOperationHint::kSignedSmall ||
hint == NumberOperationHint::kSigned32) &&
!truncation.IsUsedAsWord32()) {
// The SignedSmall or Signed32 feedback means that the results that we
// have seen so far were of type Unsigned31. We speculate that this
// will continue to hold. Moreover, since the RHS is 0, the result
// will just be the (converted) LHS.
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Unsigned31());
if (lower()) {
node->RemoveInput(1);
NodeProperties::ChangeOp(node,
simplified()->CheckedUint32ToInt32());
}
return;
}
if (BothInputsAre(node, Type::NumberOrOddball())) {
Type* rhs_type = GetUpperBound(node->InputAt(1));
VisitBinop(node, UseInfo::TruncatingWord32(),
UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
@ -1996,8 +2014,6 @@ class RepresentationSelector {
}
return;
}
NumberOperationHint hint = NumberOperationHintOf(node->op());
Type* rhs_type = GetUpperBound(node->InputAt(1));
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Unsigned32());
if (lower()) {

View File

@ -24,3 +24,32 @@ assertEquals(0, test_shr(1));
for (var i = 5; i >= -5; i--) {
assertEquals(0, test_shr(i));
}
(function () {
function foo(x, b, array) {
var y;
x = x >>> 0;
b ? (y = x | 0) : (y = x);
return array[y];
}
foo(111, true, new Array(42));
foo(111, true, new Array(42));
%OptimizeFunctionOnNextCall(foo);
foo(-111, true, new Array(42));
})();
(function () {
function foo(x, b, array) {
var y;
x = x >>> 0;
b ? (y = x | 0) : (y = x);
return array[y];
}
foo(111, true, new Array(42));
foo(111, true, new Array(42));
%OptimizeFunctionOnNextCall(foo);
foo(111, true, new Array(42));
})();