| Index: src/compiler/simplified-lowering.cc
|
| diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
|
| index 9a1565656bf227f2175d097b4e8b1424d5f1a3e1..cb32fc9ae35967c59bffa9e412f9cf7b1d5d30ad 100644
|
| --- a/src/compiler/simplified-lowering.cc
|
| +++ b/src/compiler/simplified-lowering.cc
|
| @@ -209,8 +209,30 @@ class InputUseInfos {
|
|
|
| #endif // DEBUG
|
|
|
| -} // namespace
|
| +bool CanOverflowSigned32(const Operator* op, Type* left, Type* right,
|
| + Zone* type_zone) {
|
| + // We assume the inputs are checked Signed32 (or known statically
|
| + // to be Signed32). Technically, theinputs could also be minus zero, but
|
| + // that cannot cause overflow.
|
| + left = Type::Intersect(left, Type::Signed32(), type_zone);
|
| + right = Type::Intersect(right, Type::Signed32(), type_zone);
|
| + if (!left->IsInhabited() || !right->IsInhabited()) return false;
|
| + switch (op->opcode()) {
|
| + case IrOpcode::kSpeculativeNumberAdd:
|
| + return (left->Max() + right->Max() > kMaxInt) ||
|
| + (left->Min() + right->Min() < kMinInt);
|
| +
|
| + case IrOpcode::kSpeculativeNumberSubtract:
|
| + return (left->Max() - right->Min() > kMaxInt) ||
|
| + (left->Min() - right->Max() < kMinInt);
|
| +
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + return true;
|
| +}
|
|
|
| +} // namespace
|
|
|
| class RepresentationSelector {
|
| public:
|
| @@ -1164,6 +1186,7 @@ class RepresentationSelector {
|
| if (BothInputsAre(node, Type::PlainPrimitive())) {
|
| if (truncation.IsUnused()) return VisitUnused(node);
|
| }
|
| +
|
| if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
|
| (GetUpperBound(node)->Is(Type::Signed32()) ||
|
| GetUpperBound(node)->Is(Type::Unsigned32()) ||
|
| @@ -1177,33 +1200,38 @@ class RepresentationSelector {
|
| // Try to use type feedback.
|
| NumberOperationHint hint = NumberOperationHintOf(node->op());
|
|
|
| - // Handle the case when no int32 checks on inputs are necessary
|
| - // (but an overflow check is needed on the output).
|
| - if (BothInputsAre(node, Type::Signed32()) ||
|
| - (BothInputsAre(node, Type::Signed32OrMinusZero()) &&
|
| - NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) {
|
| - // If both the inputs the feedback are int32, use the overflow op.
|
| - if (hint == NumberOperationHint::kSignedSmall ||
|
| - hint == NumberOperationHint::kSigned32) {
|
| + if (hint == NumberOperationHint::kSignedSmall ||
|
| + hint == NumberOperationHint::kSigned32) {
|
| + Type* left_feedback_type = TypeOf(node->InputAt(0));
|
| + Type* right_feedback_type = TypeOf(node->InputAt(1));
|
| + // Handle the case when no int32 checks on inputs are necessary (but
|
| + // an overflow check is needed on the output).
|
| + // TODO(jarin) We should not look at the upper bound because the typer
|
| + // could have already baked in some feedback into the upper bound.
|
| + if (BothInputsAre(node, Type::Signed32()) ||
|
| + (BothInputsAre(node, Type::Signed32OrMinusZero()) &&
|
| + GetUpperBound(node)->Is(type_cache_.kSafeInteger))) {
|
| VisitBinop(node, UseInfo::TruncatingWord32(),
|
| MachineRepresentation::kWord32, Type::Signed32());
|
| - if (lower()) ChangeToInt32OverflowOp(node);
|
| - return;
|
| + } else {
|
| + UseInfo left_use = CheckedUseInfoAsWord32FromHint(hint);
|
| + // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
|
| + // a minus zero check for the right hand side, since we already
|
| + // know that the left hand side is a proper Signed32 value,
|
| + // potentially guarded by a check.
|
| + UseInfo right_use = CheckedUseInfoAsWord32FromHint(
|
| + hint, CheckForMinusZeroMode::kDontCheckForMinusZero);
|
| + VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
|
| + Type::Signed32());
|
| + }
|
| + if (lower()) {
|
| + if (CanOverflowSigned32(node->op(), left_feedback_type,
|
| + right_feedback_type, graph_zone())) {
|
| + ChangeToInt32OverflowOp(node);
|
| + } else {
|
| + ChangeToPureOp(node, Int32Op(node));
|
| + }
|
| }
|
| - }
|
| -
|
| - if (hint == NumberOperationHint::kSignedSmall ||
|
| - hint == NumberOperationHint::kSigned32) {
|
| - UseInfo left_use = CheckedUseInfoAsWord32FromHint(hint);
|
| - // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
|
| - // a minus zero check for the right hand side, since we already
|
| - // know that the left hand side is a proper Signed32 value,
|
| - // potentially guarded by a check.
|
| - UseInfo right_use = CheckedUseInfoAsWord32FromHint(
|
| - hint, CheckForMinusZeroMode::kDontCheckForMinusZero);
|
| - VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
|
| - Type::Signed32());
|
| - if (lower()) ChangeToInt32OverflowOp(node);
|
| return;
|
| }
|
|
|
|
|