Index: src/compiler/simplified-lowering.cc |
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc |
index 05b3f254deaffc1a7c2b17bb5bd56fe2f8831d33..2c1d596b283925552b11d69dc2cba5eea6392f85 100644 |
--- a/src/compiler/simplified-lowering.cc |
+++ b/src/compiler/simplified-lowering.cc |
@@ -677,6 +677,12 @@ class RepresentationSelector { |
GetUpperBound(node->InputAt(1))->Is(type); |
} |
+ bool OneInputCannotBe(Node* node, Type* type) { |
+ DCHECK_EQ(2, node->op()->ValueInputCount()); |
+ return !GetUpperBound(node->InputAt(0))->Maybe(type) || |
+ !GetUpperBound(node->InputAt(1))->Maybe(type); |
+ } |
+ |
void ConvertInput(Node* node, int index, UseInfo use) { |
Node* input = node->InputAt(index); |
// In the change phase, insert a change before the use if necessary. |
@@ -1127,7 +1133,7 @@ class RepresentationSelector { |
if (BothInputsAre(node, Type::PlainPrimitive())) { |
if (truncation.IsUnused()) return VisitUnused(node); |
} |
- if (BothInputsAre(node, type_cache_.kSigned32OrMinusZero) && |
+ if (BothInputsAre(node, Type::Signed32OrMinusZero()) && |
NodeProperties::GetType(node)->Is(Type::Signed32())) { |
// int32 + int32 = int32 ==> signed Int32Add/Sub |
VisitInt32Binop(node); |
@@ -1151,7 +1157,7 @@ class RepresentationSelector { |
// 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_cache_.kSigned32OrMinusZero) && |
+ (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 == BinaryOperationHints::kSignedSmall || |
@@ -1290,7 +1296,35 @@ class RepresentationSelector { |
} |
return; |
} |
- case IrOpcode::kNumberEqual: |
+ case IrOpcode::kNumberEqual: { |
+ Type* const lhs_type = TypeOf(node->InputAt(0)); |
+ Type* const rhs_type = TypeOf(node->InputAt(1)); |
+ // Number comparisons reduce to integer comparisons for integer inputs. |
+ if ((lhs_type->Is(Type::Unsigned32()) && |
+ rhs_type->Is(Type::Unsigned32())) || |
+ (lhs_type->Is(Type::Unsigned32OrMinusZeroOrNaN()) && |
+ rhs_type->Is(Type::Unsigned32OrMinusZeroOrNaN()) && |
+ OneInputCannotBe(node, type_cache_.kZeroish))) { |
+ // => unsigned Int32Cmp |
+ VisitUint32Cmp(node); |
+ if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
+ return; |
+ } |
+ if ((lhs_type->Is(Type::Signed32()) && |
+ rhs_type->Is(Type::Signed32())) || |
+ (lhs_type->Is(Type::Signed32OrMinusZeroOrNaN()) && |
+ rhs_type->Is(Type::Signed32OrMinusZeroOrNaN()) && |
+ OneInputCannotBe(node, type_cache_.kZeroish))) { |
+ // => signed Int32Cmp |
+ VisitInt32Cmp(node); |
+ if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
+ return; |
+ } |
+ // => Float64Cmp |
+ VisitFloat64Cmp(node); |
+ if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
+ return; |
+ } |
case IrOpcode::kNumberLessThan: |
case IrOpcode::kNumberLessThanOrEqual: { |
// Number comparisons reduce to integer comparisons for integer inputs. |
@@ -1580,25 +1614,21 @@ class RepresentationSelector { |
if (BothInputsAre(node, Type::PlainPrimitive())) { |
if (truncation.IsUnused()) return VisitUnused(node); |
} |
- if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) { |
+ 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 (BothInputsAreSigned32(node)) { |
- if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
- // => signed Int32Mod |
- VisitInt32Binop(node); |
- if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
- return; |
- } |
- if (truncation.IsUsedAsWord32()) { |
- // => signed Int32Mod |
- VisitWord32TruncatingBinop(node); |
- if (lower()) DeferReplacement(node, lowering->Int32Mod(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. |
@@ -1644,6 +1674,30 @@ class RepresentationSelector { |
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()); |
@@ -1651,27 +1705,47 @@ class RepresentationSelector { |
return; |
} |
case IrOpcode::kNumberModulus: { |
- if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) { |
+ 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 (BothInputsAreSigned32(node)) { |
- if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
- // => signed Int32Mod |
- VisitInt32Binop(node); |
- if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
- return; |
- } |
- if (truncation.IsUsedAsWord32()) { |
- // => signed Int32Mod |
- VisitWord32TruncatingBinop(node); |
- if (lower()) DeferReplacement(node, lowering->Int32Mod(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; |
} |
- // => Float64Mod |
+ 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 |
VisitFloat64Binop(node); |
if (lower()) ChangeToPureOp(node, Float64Op(node)); |
return; |