| Index: src/compiler/simplified-lowering.cc
|
| diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
|
| index 9b5b73f2059524262841eeba5f993decc41dc0c4..d1c56dd886b14a5d2cf967c4b1d18bbe2078e25e 100644
|
| --- a/src/compiler/simplified-lowering.cc
|
| +++ b/src/compiler/simplified-lowering.cc
|
| @@ -1382,8 +1382,13 @@ class RepresentationSelector {
|
| if (lower()) ChangeToPureOp(node, Float64Op(node));
|
| return;
|
| }
|
| - case IrOpcode::kSpeculativeNumberDivide:
|
| - case IrOpcode::kNumberDivide: {
|
| + case IrOpcode::kSpeculativeNumberDivide: {
|
| + if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
|
| + // => unsigned Uint32Div
|
| + VisitWord32TruncatingBinop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
|
| + return;
|
| + }
|
| if (BothInputsAreSigned32(node)) {
|
| if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
|
| // => signed Int32Div
|
| @@ -1398,12 +1403,67 @@ class RepresentationSelector {
|
| return;
|
| }
|
| }
|
| +
|
| + // Try to use type feedback.
|
| + BinaryOperationHints::Hint hint = BinaryOperationHintOf(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())) {
|
| + // If both the inputs the feedback are int32, use the overflow op.
|
| + if (hint == BinaryOperationHints::kSignedSmall ||
|
| + hint == BinaryOperationHints::kSigned32) {
|
| + VisitBinop(node, UseInfo::TruncatingWord32(),
|
| + MachineRepresentation::kWord32,
|
| + TypeCheckKind::kSigned32);
|
| + if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
|
| + return;
|
| + }
|
| + }
|
| +
|
| + if (hint == BinaryOperationHints::kSignedSmall ||
|
| + hint == BinaryOperationHints::kSigned32) {
|
| + // If the result is truncated, we only need to check the inputs.
|
| + if (truncation.TruncatesToWord32()) {
|
| + VisitBinop(node, UseInfo::CheckedSigned32AsWord32(),
|
| + MachineRepresentation::kWord32);
|
| + if (lower()) DeferReplacement(node, lowering->Int32Div(node));
|
| + } else {
|
| + VisitBinop(node, UseInfo::CheckedSigned32AsWord32(),
|
| + MachineRepresentation::kWord32,
|
| + TypeCheckKind::kSigned32);
|
| + if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
|
| + }
|
| + return;
|
| + }
|
| +
|
| + // default case => Float64Div
|
| + VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
|
| + MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
|
| + if (lower()) ChangeToPureOp(node, Float64Op(node));
|
| + return;
|
| + }
|
| + case IrOpcode::kNumberDivide: {
|
| if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
|
| // => unsigned Uint32Div
|
| VisitWord32TruncatingBinop(node);
|
| if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
|
| return;
|
| }
|
| + if (BothInputsAreSigned32(node)) {
|
| + if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
|
| + // => signed Int32Div
|
| + VisitInt32Binop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Int32Div(node));
|
| + return;
|
| + }
|
| + if (truncation.TruncatesToWord32()) {
|
| + // => signed Int32Div
|
| + VisitWord32TruncatingBinop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Int32Div(node));
|
| + return;
|
| + }
|
| + }
|
| // Number x Number => Float64Div
|
| if (BothInputsAre(node, Type::NumberOrUndefined())) {
|
| VisitFloat64Binop(node);
|
| @@ -1417,8 +1477,13 @@ class RepresentationSelector {
|
| if (lower()) ChangeToPureOp(node, Float64Op(node));
|
| return;
|
| }
|
| - case IrOpcode::kSpeculativeNumberModulus:
|
| - case IrOpcode::kNumberModulus: {
|
| + case IrOpcode::kSpeculativeNumberModulus: {
|
| + if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
|
| + // => unsigned Uint32Mod
|
| + VisitWord32TruncatingBinop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
|
| + return;
|
| + }
|
| if (BothInputsAreSigned32(node)) {
|
| if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
|
| // => signed Int32Mod
|
| @@ -1433,23 +1498,69 @@ class RepresentationSelector {
|
| return;
|
| }
|
| }
|
| +
|
| + // Try to use type feedback.
|
| + BinaryOperationHints::Hint hint = BinaryOperationHintOf(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())) {
|
| + // If both the inputs the feedback are int32, use the overflow op.
|
| + if (hint == BinaryOperationHints::kSignedSmall ||
|
| + hint == BinaryOperationHints::kSigned32) {
|
| + VisitBinop(node, UseInfo::TruncatingWord32(),
|
| + MachineRepresentation::kWord32,
|
| + TypeCheckKind::kSigned32);
|
| + if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
|
| + return;
|
| + }
|
| + }
|
| +
|
| + if (hint == BinaryOperationHints::kSignedSmall ||
|
| + hint == BinaryOperationHints::kSigned32) {
|
| + // If the result is truncated, we only need to check the inputs.
|
| + if (truncation.TruncatesToWord32()) {
|
| + VisitBinop(node, UseInfo::CheckedSigned32AsWord32(),
|
| + MachineRepresentation::kWord32);
|
| + if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
|
| + } else {
|
| + VisitBinop(node, UseInfo::CheckedSigned32AsWord32(),
|
| + MachineRepresentation::kWord32,
|
| + TypeCheckKind::kSigned32);
|
| + if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
|
| + }
|
| + return;
|
| + }
|
| +
|
| + // default case => Float64Mod
|
| + VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
|
| + MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
|
| + if (lower()) ChangeToPureOp(node, Float64Op(node));
|
| + return;
|
| + }
|
| + case IrOpcode::kNumberModulus: {
|
| if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
|
| // => unsigned Uint32Mod
|
| VisitWord32TruncatingBinop(node);
|
| if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
|
| return;
|
| }
|
| - // Number x Number => Float64Mod
|
| - if (BothInputsAre(node, Type::NumberOrUndefined())) {
|
| - // => Float64Mod
|
| - VisitFloat64Binop(node);
|
| - if (lower()) ChangeToPureOp(node, Float64Op(node));
|
| - return;
|
| + if (BothInputsAreSigned32(node)) {
|
| + if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
|
| + // => signed Int32Mod
|
| + VisitInt32Binop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
|
| + return;
|
| + }
|
| + if (truncation.TruncatesToWord32()) {
|
| + // => signed Int32Mod
|
| + VisitWord32TruncatingBinop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
|
| + return;
|
| + }
|
| }
|
| - // Checked float64 x float64 => float64
|
| - DCHECK_EQ(IrOpcode::kSpeculativeNumberModulus, node->opcode());
|
| - VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
|
| - MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
|
| + // => Float64Mod
|
| + VisitFloat64Binop(node);
|
| if (lower()) ChangeToPureOp(node, Float64Op(node));
|
| return;
|
| }
|
|
|