| Index: src/compiler/simplified-lowering.cc | 
| diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc | 
| index d886cf02a702a9b69e4c2c573e6b08be62f6e597..f5a541d1443b031b2d23123f7d994c98382869f0 100644 | 
| --- a/src/compiler/simplified-lowering.cc | 
| +++ b/src/compiler/simplified-lowering.cc | 
| @@ -1175,6 +1175,110 @@ class RepresentationSelector { | 
| return; | 
| } | 
|  | 
| +  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()))) { | 
| +      // => unsigned Uint32Mod | 
| +      VisitWord32TruncatingBinop(node); | 
| +      if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 
| +      return; | 
| +    } | 
| +    if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) && | 
| +        (truncation.IsUsedAsWord32() || | 
| +         NodeProperties::GetType(node)->Is(Type::Signed32()))) { | 
| +      // => signed Int32Mod | 
| +      VisitWord32TruncatingBinop(node); | 
| +      if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 
| +      return; | 
| +    } | 
| + | 
| +    // Try to use type feedback. | 
| +    NumberOperationHint hint = NumberOperationHintOf(node->op()); | 
| + | 
| +    // Handle the case when no uint32 checks on inputs are necessary | 
| +    // (but an overflow check is needed on the output). | 
| +    if (BothInputsAreUnsigned32(node)) { | 
| +      if (hint == NumberOperationHint::kSignedSmall || | 
| +          hint == NumberOperationHint::kSigned32) { | 
| +        VisitBinop(node, UseInfo::TruncatingWord32(), | 
| +                   MachineRepresentation::kWord32, Type::Unsigned32()); | 
| +        if (lower()) ChangeToUint32OverflowOp(node); | 
| +        return; | 
| +      } | 
| +    } | 
| + | 
| +    // 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())) { | 
| +      // If both the inputs the feedback are int32, use the overflow op. | 
| +      if (hint == NumberOperationHint::kSignedSmall || | 
| +          hint == NumberOperationHint::kSigned32) { | 
| +        VisitBinop(node, UseInfo::TruncatingWord32(), | 
| +                   MachineRepresentation::kWord32, Type::Signed32()); | 
| +        if (lower()) ChangeToInt32OverflowOp(node); | 
| +        return; | 
| +      } | 
| +    } | 
| + | 
| +    if (hint == NumberOperationHint::kSignedSmall || | 
| +        hint == NumberOperationHint::kSigned32) { | 
| +      // If the result is truncated, we only need to check the inputs. | 
| +      if (truncation.IsUsedAsWord32()) { | 
| +        VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), | 
| +                   MachineRepresentation::kWord32); | 
| +        if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 
| +      } else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) { | 
| +        VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), | 
| +                   MachineRepresentation::kWord32, Type::Unsigned32()); | 
| +        if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 
| +      } else { | 
| +        VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), | 
| +                   MachineRepresentation::kWord32, Type::Signed32()); | 
| +        if (lower()) ChangeToInt32OverflowOp(node); | 
| +      } | 
| +      return; | 
| +    } | 
| + | 
| +    if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) && | 
| +        TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) && | 
| +        (truncation.IsUsedAsWord32() || | 
| +         NodeProperties::GetType(node)->Is(Type::Unsigned32()))) { | 
| +      // We can only promise Float64 truncation here, as the decision is | 
| +      // based on the feedback types of the inputs. | 
| +      VisitBinop(node, | 
| +                 UseInfo(MachineRepresentation::kWord32, Truncation::Float64()), | 
| +                 MachineRepresentation::kWord32); | 
| +      if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 
| +      return; | 
| +    } | 
| +    if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) && | 
| +        TypeOf(node->InputAt(1))->Is(Type::Signed32()) && | 
| +        (truncation.IsUsedAsWord32() || | 
| +         NodeProperties::GetType(node)->Is(Type::Signed32()))) { | 
| +      // We can only promise Float64 truncation here, as the decision is | 
| +      // based on the feedback types of the inputs. | 
| +      VisitBinop(node, | 
| +                 UseInfo(MachineRepresentation::kWord32, Truncation::Float64()), | 
| +                 MachineRepresentation::kWord32); | 
| +      if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 
| +      return; | 
| +    } | 
| +    // default case => Float64Mod | 
| +    VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), | 
| +               MachineRepresentation::kFloat64, Type::Number()); | 
| +    if (lower()) ChangeToPureOp(node, Float64Op(node)); | 
| +    return; | 
| +  } | 
| + | 
| // Dispatching routine for visiting the node {node} with the usage {use}. | 
| // Depending on the operator, propagate new usage info to the inputs. | 
| void VisitNode(Node* node, Truncation truncation, | 
| @@ -1592,104 +1696,8 @@ class RepresentationSelector { | 
| if (lower()) ChangeToPureOp(node, Float64Op(node)); | 
| return; | 
| } | 
| -      case IrOpcode::kSpeculativeNumberModulus: { | 
| -        // 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()))) { | 
| -          // => unsigned Uint32Mod | 
| -          VisitWord32TruncatingBinop(node); | 
| -          if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 
| -          return; | 
| -        } | 
| -        if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) && | 
| -            (truncation.IsUsedAsWord32() || | 
| -             NodeProperties::GetType(node)->Is(Type::Signed32()))) { | 
| -          // => signed Int32Mod | 
| -          VisitWord32TruncatingBinop(node); | 
| -          if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 
| -          return; | 
| -        } | 
| - | 
| -        // Try to use type feedback. | 
| -        NumberOperationHint hint = NumberOperationHintOf(node->op()); | 
| - | 
| -        // Handle the case when no uint32 checks on inputs are necessary | 
| -        // (but an overflow check is needed on the output). | 
| -        if (BothInputsAreUnsigned32(node)) { | 
| -          if (hint == NumberOperationHint::kSignedSmall || | 
| -              hint == NumberOperationHint::kSigned32) { | 
| -            VisitBinop(node, UseInfo::TruncatingWord32(), | 
| -                       MachineRepresentation::kWord32, Type::Unsigned32()); | 
| -            if (lower()) ChangeToUint32OverflowOp(node); | 
| -            return; | 
| -          } | 
| -        } | 
| - | 
| -        // 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())) { | 
| -          // If both the inputs the feedback are int32, use the overflow op. | 
| -          if (hint == NumberOperationHint::kSignedSmall || | 
| -              hint == NumberOperationHint::kSigned32) { | 
| -            VisitBinop(node, UseInfo::TruncatingWord32(), | 
| -                       MachineRepresentation::kWord32, Type::Signed32()); | 
| -            if (lower()) ChangeToInt32OverflowOp(node); | 
| -            return; | 
| -          } | 
| -        } | 
| - | 
| -        if (hint == NumberOperationHint::kSignedSmall || | 
| -            hint == NumberOperationHint::kSigned32) { | 
| -          // If the result is truncated, we only need to check the inputs. | 
| -          if (truncation.IsUsedAsWord32()) { | 
| -            VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), | 
| -                       MachineRepresentation::kWord32); | 
| -            if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 
| -          } else { | 
| -            VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), | 
| -                       MachineRepresentation::kWord32, Type::Signed32()); | 
| -            if (lower()) ChangeToInt32OverflowOp(node); | 
| -          } | 
| -          return; | 
| -        } | 
| - | 
| -        if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) && | 
| -            TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) && | 
| -            (truncation.IsUsedAsWord32() || | 
| -             NodeProperties::GetType(node)->Is(Type::Unsigned32()))) { | 
| -          // We can only promise Float64 truncation here, as the decision is | 
| -          // based on the feedback types of the inputs. | 
| -          VisitBinop(node, UseInfo(MachineRepresentation::kWord32, | 
| -                                   Truncation::Float64()), | 
| -                     MachineRepresentation::kWord32); | 
| -          if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 
| -          return; | 
| -        } | 
| -        if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) && | 
| -            TypeOf(node->InputAt(1))->Is(Type::Signed32()) && | 
| -            (truncation.IsUsedAsWord32() || | 
| -             NodeProperties::GetType(node)->Is(Type::Signed32()))) { | 
| -          // We can only promise Float64 truncation here, as the decision is | 
| -          // based on the feedback types of the inputs. | 
| -          VisitBinop(node, UseInfo(MachineRepresentation::kWord32, | 
| -                                   Truncation::Float64()), | 
| -                     MachineRepresentation::kWord32); | 
| -          if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 
| -          return; | 
| -        } | 
| -        // default case => Float64Mod | 
| -        VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), | 
| -                   MachineRepresentation::kFloat64, Type::Number()); | 
| -        if (lower()) ChangeToPureOp(node, Float64Op(node)); | 
| -        return; | 
| -      } | 
| +      case IrOpcode::kSpeculativeNumberModulus: | 
| +        return VisitSpeculativeNumberModulus(node, truncation, lowering); | 
| case IrOpcode::kNumberModulus: { | 
| if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) && | 
| (truncation.IsUsedAsWord32() || | 
|  |