Commit ca386a4b authored by Georg Neis's avatar Georg Neis Committed by V8 LUCI CQ

[compiler] Fix bug in MachineOperatorReducer::TryMatchWord32Ror

Bug: chromium:1234764
Change-Id: Ie899f00e9247bdf67b59aa3ebb7def2948ccdb6a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3067332Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76050}
parent f0219877
...@@ -1836,17 +1836,20 @@ Reduction MachineOperatorReducer::ReduceWord64And(Node* node) { ...@@ -1836,17 +1836,20 @@ Reduction MachineOperatorReducer::ReduceWord64And(Node* node) {
} }
Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) { Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) {
// Recognize rotation, we are matching and transforming as follows:
// x << y | x >>> (32 - y) => x ror (32 - y)
// x << (32 - y) | x >>> y => x ror y
// x << y ^ x >>> (32 - y) => x ror (32 - y) if y & 31 != 0
// x << (32 - y) ^ x >>> y => x ror y if y & 31 != 0
// (As well as the commuted forms.)
// Note the side condition for XOR: the optimization doesn't hold for
// multiples of 32.
DCHECK(IrOpcode::kWord32Or == node->opcode() || DCHECK(IrOpcode::kWord32Or == node->opcode() ||
IrOpcode::kWord32Xor == node->opcode()); IrOpcode::kWord32Xor == node->opcode());
Int32BinopMatcher m(node); Int32BinopMatcher m(node);
Node* shl = nullptr; Node* shl = nullptr;
Node* shr = nullptr; Node* shr = nullptr;
// Recognize rotation, we are matching:
// * x << y | x >>> (32 - y) => x ror (32 - y), i.e x rol y
// * x << (32 - y) | x >>> y => x ror y
// * x << y ^ x >>> (32 - y) => x ror (32 - y), i.e. x rol y
// * x << (32 - y) ^ x >>> y => x ror y
// as well as their commuted form.
if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) {
shl = m.left().node(); shl = m.left().node();
shr = m.right().node(); shr = m.right().node();
...@@ -1863,8 +1866,13 @@ Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) { ...@@ -1863,8 +1866,13 @@ Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) {
if (mshl.right().HasResolvedValue() && mshr.right().HasResolvedValue()) { if (mshl.right().HasResolvedValue() && mshr.right().HasResolvedValue()) {
// Case where y is a constant. // Case where y is a constant.
if (mshl.right().ResolvedValue() + mshr.right().ResolvedValue() != 32) if (mshl.right().ResolvedValue() + mshr.right().ResolvedValue() != 32) {
return NoChange();
}
if (node->opcode() == IrOpcode::kWord32Xor &&
(mshl.right().ResolvedValue() & 31) == 0) {
return NoChange(); return NoChange();
}
} else { } else {
Node* sub = nullptr; Node* sub = nullptr;
Node* y = nullptr; Node* y = nullptr;
...@@ -1880,6 +1888,9 @@ Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) { ...@@ -1880,6 +1888,9 @@ Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) {
Int32BinopMatcher msub(sub); Int32BinopMatcher msub(sub);
if (!msub.left().Is(32) || msub.right().node() != y) return NoChange(); if (!msub.left().Is(32) || msub.right().node() != y) return NoChange();
if (node->opcode() == IrOpcode::kWord32Xor) {
return NoChange(); // Can't guarantee y & 31 != 0.
}
} }
node->ReplaceInput(0, mshl.left().node()); node->ReplaceInput(0, mshl.left().node());
......
...@@ -956,16 +956,12 @@ TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) { ...@@ -956,16 +956,12 @@ TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
// (x << y) ^ (x >>> (32 - y)) => x ror (32 - y) // (x << y) ^ (x >>> (32 - y)) => x ror (32 - y)
Node* node3 = graph()->NewNode(machine()->Word32Xor(), shl_l, shr_l); Node* node3 = graph()->NewNode(machine()->Word32Xor(), shl_l, shr_l);
Reduction reduction3 = Reduce(node3); Reduction reduction3 = Reduce(node3);
EXPECT_TRUE(reduction3.Changed()); EXPECT_FALSE(reduction3.Changed());
EXPECT_EQ(reduction3.replacement(), node3);
EXPECT_THAT(reduction3.replacement(), IsWord32Ror(value, sub));
// (x >>> (32 - y)) ^ (x << y) => x ror (32 - y) // (x >>> (32 - y)) ^ (x << y) => x ror (32 - y)
Node* node4 = graph()->NewNode(machine()->Word32Xor(), shr_l, shl_l); Node* node4 = graph()->NewNode(machine()->Word32Xor(), shr_l, shl_l);
Reduction reduction4 = Reduce(node4); Reduction reduction4 = Reduce(node4);
EXPECT_TRUE(reduction4.Changed()); EXPECT_FALSE(reduction4.Changed());
EXPECT_EQ(reduction4.replacement(), node4);
EXPECT_THAT(reduction4.replacement(), IsWord32Ror(value, sub));
// Testing rotate right. // Testing rotate right.
Node* shl_r = graph()->NewNode(machine()->Word32Shl(), value, sub); Node* shl_r = graph()->NewNode(machine()->Word32Shl(), value, sub);
...@@ -988,16 +984,12 @@ TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) { ...@@ -988,16 +984,12 @@ TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
// (x << (32 - y)) ^ (x >>> y) => x ror y // (x << (32 - y)) ^ (x >>> y) => x ror y
Node* node7 = graph()->NewNode(machine()->Word32Xor(), shl_r, shr_r); Node* node7 = graph()->NewNode(machine()->Word32Xor(), shl_r, shr_r);
Reduction reduction7 = Reduce(node7); Reduction reduction7 = Reduce(node7);
EXPECT_TRUE(reduction7.Changed()); EXPECT_FALSE(reduction7.Changed());
EXPECT_EQ(reduction7.replacement(), node7);
EXPECT_THAT(reduction7.replacement(), IsWord32Ror(value, shift));
// (x >>> y) ^ (x << (32 - y)) => x ror y // (x >>> y) ^ (x << (32 - y)) => x ror y
Node* node8 = graph()->NewNode(machine()->Word32Xor(), shr_r, shl_r); Node* node8 = graph()->NewNode(machine()->Word32Xor(), shr_r, shl_r);
Reduction reduction8 = Reduce(node8); Reduction reduction8 = Reduce(node8);
EXPECT_TRUE(reduction8.Changed()); EXPECT_FALSE(reduction8.Changed());
EXPECT_EQ(reduction8.replacement(), node8);
EXPECT_THAT(reduction8.replacement(), IsWord32Ror(value, shift));
} }
TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) { TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
......
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