Commit f0e7a317 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Extend optimization of flooring integer division.

So far we only recognize the special

  NumberFloor(NumberDivide(lhs, rhs))

subgraph when both lhs and rhs are in the Unsigned32 range, and the
result is a PlainNumber. Extend this pattern matching to also cover

  NumberFloor(SpeculativeNumberDivide(lhs, rhs))

and to replace the NumberFloor with NumberToInt32 truncation if the
lhs value is in Signed32 range and the rhs is in Unsigned32 range.

R=jarin@chromium.org
BUG=v8:5267

Review-Url: https://codereview.chromium.org/2739573004
Cr-Commit-Position: refs/heads/master@{#43642}
parent f489f7ab
......@@ -625,13 +625,20 @@ Type* OperationTyper::NumberDivide(Type* lhs, Type* rhs) {
}
if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
// Division is tricky, so all we do is try ruling out -0 and NaN.
bool maybe_minuszero = !lhs->Is(cache_.kPositiveIntegerOrNaN) ||
!rhs->Is(cache_.kPositiveIntegerOrNaN);
bool maybe_nan =
lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
(rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone());
rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone());
// Try to rule out -0.
bool maybe_minuszero =
!lhs->Is(cache_.kInteger) ||
(lhs->Maybe(cache_.kZeroish) && rhs->Min() < 0.0) ||
(rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY);
// Take into account the -0 and NaN information computed earlier.
Type* type = Type::PlainNumber();
......
......@@ -195,7 +195,8 @@ Reduction TypedOptimization::ReduceNumberFloor(Node* node) {
return Replace(input);
}
if (input_type->Is(Type::PlainNumber()) &&
input->opcode() == IrOpcode::kNumberDivide) {
(input->opcode() == IrOpcode::kNumberDivide ||
input->opcode() == IrOpcode::kSpeculativeNumberDivide)) {
Node* const lhs = NodeProperties::GetValueInput(input, 0);
Type* const lhs_type = NodeProperties::GetType(lhs);
Node* const rhs = NodeProperties::GetValueInput(input, 1);
......@@ -218,6 +219,11 @@ Reduction TypedOptimization::ReduceNumberFloor(Node* node) {
NodeProperties::SetType(node, lhs_type);
return Changed(node);
}
if (lhs_type->Is(Type::Signed32()) && rhs_type->Is(Type::Unsigned32())) {
NodeProperties::ChangeOp(node, simplified()->NumberToInt32());
NodeProperties::SetType(node, lhs_type);
return Changed(node);
}
}
return NoChange();
}
......
......@@ -165,6 +165,16 @@ class TyperTest : public TypedGraphTest {
EXPECT_TRUE(result_type->Is(expected_type));
}
}
// Test extreme cases.
double x1 = +1e-308;
double x2 = -1e-308;
Type* r1 = Type::NewConstant(isolate()->factory()->NewNumber(x1), zone());
Type* r2 = Type::NewConstant(isolate()->factory()->NewNumber(x2), zone());
Type* expected_type = TypeBinaryOp(op, r1, r2);
double result_value = opfun(x1, x2);
Type* result_type = Type::NewConstant(
isolate()->factory()->NewNumber(result_value), zone());
EXPECT_TRUE(result_type->Is(expected_type));
}
template <class BinaryFunction>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment