Commit 3485a51d authored by Seth Brenith's avatar Seth Brenith Committed by Commit Bot

[compiler] Fold constants for kInt64Mul

I noticed that the generated code from the Torque macro
EnsureArrayLengthWritable included an imul instruction, even though the
inputs to that instruction are both constants. This change adds the
ability for MachineOperatorReducer to get rid of that operation.

Change-Id: Ia2050c888d76f110d1290fd9eab13853c3353a63
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1941138
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65310}
parent 91ee5f04
......@@ -243,6 +243,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
}
break;
}
case IrOpcode::kInt64Mul:
return ReduceInt64Mul(node);
case IrOpcode::kInt32Div:
return ReduceInt32Div(node);
case IrOpcode::kUint32Div:
......@@ -821,6 +823,31 @@ Reduction MachineOperatorReducer::ReduceInt64Sub(Node* node) {
return NoChange();
}
Reduction MachineOperatorReducer::ReduceInt64Mul(Node* node) {
DCHECK_EQ(IrOpcode::kInt64Mul, node->opcode());
Int64BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0
if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x
if (m.IsFoldable()) { // K * K => K
return ReplaceInt64(
base::MulWithWraparound(m.left().Value(), m.right().Value()));
}
if (m.right().Is(-1)) { // x * -1 => 0 - x
node->ReplaceInput(0, Int64Constant(0));
node->ReplaceInput(1, m.left().node());
NodeProperties::ChangeOp(node, machine()->Int64Sub());
return Changed(node);
}
if (m.right().IsPowerOf2()) { // x * 2^n => x << n
node->ReplaceInput(
1, Int64Constant(base::bits::WhichPowerOfTwo(m.right().Value())));
NodeProperties::ChangeOp(node, machine()->Word64Shl());
Reduction reduction = ReduceWord64Shl(node);
return reduction.Changed() ? reduction : Changed(node);
}
return NoChange();
}
Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
Int32BinopMatcher m(node);
if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0
......
......@@ -78,6 +78,7 @@ class V8_EXPORT_PRIVATE MachineOperatorReducer final
Reduction ReduceInt64Add(Node* node);
Reduction ReduceInt32Sub(Node* node);
Reduction ReduceInt64Sub(Node* node);
Reduction ReduceInt64Mul(Node* node);
Reduction ReduceInt32Div(Node* node);
Reduction ReduceUint32Div(Node* node);
Reduction ReduceInt32Mod(Node* node);
......
......@@ -1674,6 +1674,95 @@ TEST_F(MachineOperatorReducerTest, Int32MulWithOverflowWithConstant) {
}
}
// -----------------------------------------------------------------------------
// Int64Mul
TEST_F(MachineOperatorReducerTest, Int64MulWithZero) {
Node* p0 = Parameter(0);
{
Node* mul = graph()->NewNode(machine()->Int64Mul(), Int64Constant(0), p0);
Reduction r = Reduce(mul);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt64Constant(0));
}
{
Node* mul = graph()->NewNode(machine()->Int64Mul(), p0, Int64Constant(0));
Reduction r = Reduce(mul);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt64Constant(0));
}
}
TEST_F(MachineOperatorReducerTest, Int64MulWithOne) {
Node* p0 = Parameter(0);
{
Node* mul = graph()->NewNode(machine()->Int64Mul(), Int64Constant(1), p0);
Reduction r = Reduce(mul);
ASSERT_TRUE(r.Changed());
EXPECT_EQ(p0, r.replacement());
}
{
Node* mul = graph()->NewNode(machine()->Int64Mul(), p0, Int64Constant(1));
Reduction r = Reduce(mul);
ASSERT_TRUE(r.Changed());
EXPECT_EQ(p0, r.replacement());
}
}
TEST_F(MachineOperatorReducerTest, Int64MulWithMinusOne) {
Node* p0 = Parameter(0);
{
Reduction r =
Reduce(graph()->NewNode(machine()->Int64Mul(), Int64Constant(-1), p0));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt64Sub(IsInt64Constant(0), p0));
}
{
Reduction r =
Reduce(graph()->NewNode(machine()->Int64Mul(), p0, Int64Constant(-1)));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt64Sub(IsInt64Constant(0), p0));
}
}
TEST_F(MachineOperatorReducerTest, Int64MulWithPowerOfTwo) {
Node* p0 = Parameter(0);
{
Reduction r =
Reduce(graph()->NewNode(machine()->Int64Mul(), Int64Constant(8), p0));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsWord64Shl(p0, IsInt64Constant(3)));
}
{
Reduction r =
Reduce(graph()->NewNode(machine()->Int64Mul(), p0, Int64Constant(8)));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsWord64Shl(p0, IsInt64Constant(3)));
}
}
TEST_F(MachineOperatorReducerTest, Int64MulWithConstant) {
TRACED_FOREACH(int64_t, x, kInt64Values) {
TRACED_FOREACH(int64_t, y, kInt64Values) {
Node* mul = graph()->NewNode(machine()->Int64Mul(), Int64Constant(x),
Int64Constant(y));
Reduction r = Reduce(mul);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsInt64Constant(base::MulWithWraparound(x, y)));
}
}
}
// -----------------------------------------------------------------------------
// Int32LessThan
......
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