[turbofan] Slightly improve truncations for CheckBounds.

For CheckBounds(index,length) we know that the length must be in
Unsigned31 range. Thus there's no observable difference for index
values in the range [-2^31,-1] and the range [2^31,2^32-1], both
are considered out-of-bounds; also it's safe to truncate -0 to 0
wrt. CheckBounds. Thus we can safely pass Word32 truncation if the
index is in Integral32 \/ MinusZero. Usually this generates the same
code, but some index computations can benefit from the Word32 truncation
and avoid going to double because the result would be outside the valid
Signed32 or Unsigned32 ranges.

R=jarin@chromium.org
BUG=v8:5267

Review-Url: https://codereview.chromium.org/2760213003
Cr-Commit-Position: refs/heads/master@{#43969}
This commit is contained in:
bmeurer 2017-03-21 03:11:51 -07:00 committed by Commit bot
parent 5c227a2033
commit 17d932c06b
2 changed files with 13 additions and 6 deletions

View File

@ -2295,13 +2295,19 @@ class RepresentationSelector {
case IrOpcode::kCheckBounds: {
Type* index_type = TypeOf(node->InputAt(0));
Type* length_type = TypeOf(node->InputAt(1));
if (index_type->Is(Type::Unsigned32())) {
if (index_type->Is(Type::Integral32OrMinusZero())) {
// Map -0 to 0, and the values in the [-2^31,-1] range to the
// [2^31,2^32-1] range, which will be considered out-of-bounds
// as well, because the {length_type} is limited to Unsigned31.
VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower() && index_type->Max() < length_type->Min()) {
// The bounds check is redundant if we already know that
// the index is within the bounds of [0.0, length[.
DeferReplacement(node, node->InputAt(0));
if (lower()) {
if (index_type->Min() >= 0.0 &&
index_type->Max() < length_type->Min()) {
// The bounds check is redundant if we already know that
// the index is within the bounds of [0.0, length[.
DeferReplacement(node, node->InputAt(0));
}
}
} else {
VisitBinop(node, UseInfo::CheckedSigned32AsWord32(kIdentifyZeros),

View File

@ -139,7 +139,8 @@ namespace compiler {
V(Unsigned32OrMinusZero, kUnsigned32 | kMinusZero) \
V(Unsigned32OrMinusZeroOrNaN, kUnsigned32 | kMinusZero | kNaN) \
V(Integral32, kSigned32 | kUnsigned32) \
V(Integral32OrMinusZeroOrNaN, kIntegral32 | kMinusZero | kNaN) \
V(Integral32OrMinusZero, kIntegral32 | kMinusZero) \
V(Integral32OrMinusZeroOrNaN, kIntegral32OrMinusZero | kNaN) \
V(PlainNumber, kIntegral32 | kOtherNumber) \
V(OrderedNumber, kPlainNumber | kMinusZero) \
V(MinusZeroOrNaN, kMinusZero | kNaN) \