Commit 0a36b5cd authored by mvstanton's avatar mvstanton Committed by Commit bot

[Turbofan] Make the -0 deopt case more efficient in multiplication.

After multiplying two integers we emit code like:

  if (result == 0) {
    if (OR_OPERATION(rhs, lhs) < 0) {
      DEOPT;
    }
  }

This CL allows us to eliminate the OR and comparison if either rhs or
lhs is a negative number, reducing the code to:

  if (result == 0) DEOPT;

BUG=

Review-Url: https://codereview.chromium.org/2167643002
Cr-Commit-Position: refs/heads/master@{#38016}
parent a2ad4c8f
......@@ -264,6 +264,14 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
return ReplaceBool(m.left().Value() < m.right().Value());
}
if (m.LeftEqualsRight()) return ReplaceBool(false); // x < x => false
if (m.left().IsWord32Or() && m.right().Is(0)) {
// (x | K) < 0 => true or (K | x) < 0 => true iff K < 0
Int32BinopMatcher mleftmatcher(m.left().node());
if (mleftmatcher.left().IsNegative() ||
mleftmatcher.right().IsNegative()) {
return ReplaceBool(true);
}
}
break;
}
case IrOpcode::kInt32LessThanOrEqual: {
......
......@@ -128,6 +128,7 @@ struct IntMatcher final : public ValueMatcher<T, kOpcode> {
return this->HasValue() && this->Value() < 0 &&
(-this->Value() & (-this->Value() - 1)) == 0;
}
bool IsNegative() const { return this->HasValue() && this->Value() < 0; }
};
typedef IntMatcher<int32_t, IrOpcode::kInt32Constant> Int32Matcher;
......
......@@ -35,3 +35,11 @@ const SMI_MIN = -SMI_MAX - 1; // Create without overflowing.
// multiply by 3 to avoid compiler optimizations that convert 2*x to x + x.
assertEquals(SMI_MAX + SMI_MAX + SMI_MAX, test(SMI_MAX, 3));
// Verify that strength reduction will reduce the -0 check quite a bit
// if we have a negative integer constant.
function negtest(y) { return -3 * y; }
assertEquals(-12, negtest(4));
assertEquals(-12, negtest(4));
%OptimizeFunctionOnNextCall(negtest);
negtest(4);
......@@ -289,7 +289,6 @@ TEST_F(MachineOperatorReducerTest,
EXPECT_EQ(value, reduction.replacement());
}
TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt32WithConstant) {
TRACED_FOREACH(int32_t, x, kInt32Values) {
Reduction reduction = Reduce(graph()->NewNode(
......@@ -1505,6 +1504,26 @@ TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithConstant) {
}
}
// -----------------------------------------------------------------------------
// Int32LessThan
TEST_F(MachineOperatorReducerTest, Int32LessThanWithWord32Or) {
Node* const p0 = Parameter(0);
TRACED_FOREACH(int32_t, x, kInt32Values) {
Node* word32_or =
graph()->NewNode(machine()->Word32Or(), p0, Int32Constant(x));
Node* less_than = graph()->NewNode(machine()->Int32LessThan(), word32_or,
Int32Constant(0));
Reduction r = Reduce(less_than);
if (x < 0) {
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt32Constant(1));
} else {
ASSERT_FALSE(r.Changed());
}
}
}
// -----------------------------------------------------------------------------
// Uint32LessThan
......
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