| Index: src/hydrogen-instructions.cc
|
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
|
| index e362b95c60a81c0722e4a221e57ebd052271ada2..ddccbf3324d3950f2cea931667500b82037590ee 100644
|
| --- a/src/hydrogen-instructions.cc
|
| +++ b/src/hydrogen-instructions.cc
|
| @@ -1811,8 +1811,18 @@ Range* HMod::InferRange(Zone* zone) {
|
| if (representation().IsInteger32()) {
|
| Range* a = left()->range();
|
| Range* b = right()->range();
|
| - Range* result = new(zone) Range();
|
| - if (a->CanBeMinusZero() || a->CanBeNegative()) {
|
| +
|
| + // The magnitude of the modulus is bounded by the right operand. Note that
|
| + // apart for the cases involving kMinInt, the calculation below is the same
|
| + // as Max(Abs(b->lower()), Abs(b->upper())) - 1.
|
| + int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1);
|
| +
|
| + // The result of the modulo operation has the sign of its left operand.
|
| + bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative();
|
| + Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0,
|
| + a->CanBePositive() ? positive_bound : 0);
|
| +
|
| + if (left_can_be_negative) {
|
| result->set_can_be_minus_zero(true);
|
| }
|
|
|
|
|