mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-02 22:48:35 +00:00
8369435: C2: transform (LShiftX (SubX con0 a), con1) into (SubX con0<<con1 (LShiftX a con1))
Reviewed-by: epeter, qamai
This commit is contained in:
parent
87e5341d78
commit
80fcfaf41a
@ -1080,6 +1080,19 @@ Node* LShiftNode::IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check for "(con0 - X) << con1"
|
||||
// Transform is legal, but check for profit. Avoid breaking 'i2s'
|
||||
// and 'i2b' patterns which typically fold into 'StoreC/StoreB'.
|
||||
if (add1_op == Op_Sub(bt) && (bt != T_INT || con < 16)) { // Left input is a sub?
|
||||
// Left input is a sub from a constant?
|
||||
const TypeInteger* t11 = phase->type(add1->in(1))->isa_integer(bt);
|
||||
if (t11 != nullptr && t11->is_con()) {
|
||||
// Compute X << con0
|
||||
Node* lsh = phase->transform(LShiftNode::make(add1->in(2), in(2), bt));
|
||||
// Compute (con1<<con0) - (X<<con0)
|
||||
return SubNode::make(phase->integercon(java_shift_left(t11->get_con_as_long(bt), con, bt), bt), lsh, bt);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for "(x >> C1) << C2"
|
||||
if (add1_op == Op_RShift(bt) || add1_op == Op_URShift(bt)) {
|
||||
|
||||
@ -65,6 +65,7 @@ public class LShiftINodeIdealizationTests {
|
||||
"testLShiftOfAndOfRShift",
|
||||
"testLShiftOfAndOfURShift",
|
||||
"testLShiftOfAndOfCon",
|
||||
"testShiftOfSubConstant",
|
||||
})
|
||||
public void runMethod() {
|
||||
int a = RunInfo.getRandom().nextInt();
|
||||
@ -122,6 +123,7 @@ public class LShiftINodeIdealizationTests {
|
||||
Asserts.assertEQ((a + a) << 31, testLargeShiftOfAddSameInput(a));
|
||||
Asserts.assertEQ(((a + 1) << 1) + 1, testShiftOfAddConstant(a));
|
||||
Asserts.assertEQ((a & ((1 << (32 - 10)) -1)) << 10, testLShiftOfAndOfCon(a));
|
||||
Asserts.assertEQ(((1 - a) << 1) + 1, testShiftOfSubConstant(a));
|
||||
|
||||
assertDoubleShiftResult(a);
|
||||
}
|
||||
@ -359,17 +361,45 @@ public class LShiftINodeIdealizationTests {
|
||||
@Test
|
||||
@IR(counts = { IRNode.ADD_I, "1"} , failOn = { IRNode.LSHIFT_I, IRNode.RSHIFT_I } )
|
||||
@Arguments( values = { Argument.NUMBER_42 })
|
||||
public void testStoreShort(int x) {
|
||||
public void testStoreShort1(int x) {
|
||||
shortField = (short)(x + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.ADD_I, "1"} , failOn = { IRNode.LSHIFT_I, IRNode.RSHIFT_I } )
|
||||
@Arguments( values = { Argument.NUMBER_42 })
|
||||
public void testStoreByte(int x) {
|
||||
public void testStoreByte1(int x) {
|
||||
byteField = (byte)(x + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.ADD_I, "1"} , failOn = { IRNode.LSHIFT_I, IRNode.RSHIFT_I } )
|
||||
@Arguments( values = { Argument.NUMBER_42 })
|
||||
public void testStoreShort2(int x) {
|
||||
shortField = (short)(x + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.ADD_I, "1"} , failOn = { IRNode.LSHIFT_I, IRNode.RSHIFT_I } )
|
||||
@Arguments( values = { Argument.NUMBER_42 })
|
||||
public void testStoreByte2(int x) {
|
||||
byteField = (byte)(x + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.SUB_I, "1"} , failOn = { IRNode.LSHIFT_I, IRNode.RSHIFT_I } )
|
||||
@Arguments( values = { Argument.NUMBER_42 })
|
||||
public void testStoreShort3(int x) {
|
||||
shortField = (short)(1 - x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.SUB_I, "1"} , failOn = { IRNode.LSHIFT_I, IRNode.RSHIFT_I } )
|
||||
@Arguments( values = { Argument.NUMBER_42 })
|
||||
public void testStoreByte3(int x) {
|
||||
byteField = (byte)(1 - x);
|
||||
}
|
||||
|
||||
static int otherInput;
|
||||
|
||||
@Test
|
||||
@ -409,4 +439,10 @@ public class LShiftINodeIdealizationTests {
|
||||
public int testLShiftOfAndOfCon(int x) {
|
||||
return (x & ((1 << (32 - 10)) -1)) << 10;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LSHIFT_I, "1", IRNode.SUB_I, "1" }, failOn = { IRNode.ADD_I })
|
||||
public int testShiftOfSubConstant(int x) {
|
||||
return ((1 - x) << 1) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,6 +63,7 @@ public class LShiftLNodeIdealizationTests {
|
||||
"testLShiftOfAndOfRShift",
|
||||
"testLShiftOfAndOfURShift",
|
||||
"testLShiftOfAndOfCon",
|
||||
"testShiftOfSubConstant",
|
||||
})
|
||||
public void runMethod() {
|
||||
long a = RunInfo.getRandom().nextLong();
|
||||
@ -118,6 +119,7 @@ public class LShiftLNodeIdealizationTests {
|
||||
Asserts.assertEQ((a + a) << 63, testLargeShiftOfAddSameInput(a));
|
||||
Asserts.assertEQ(((a + 1) << 1) + 1, testShiftOfAddConstant(a));
|
||||
Asserts.assertEQ((a & ((1L << (64 - 10)) -1)) << 10, testLShiftOfAndOfCon(a));
|
||||
Asserts.assertEQ(((1L - a) << 1) + 1, testShiftOfSubConstant(a));
|
||||
|
||||
assertDoubleShiftResult(a);
|
||||
}
|
||||
@ -358,4 +360,10 @@ public class LShiftLNodeIdealizationTests {
|
||||
public long testLShiftOfAndOfCon(long x) {
|
||||
return (x & ((1L << (64 - 10)) -1)) << 10;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LSHIFT_L, "1", IRNode.SUB_L, "1" }, failOn = { IRNode.ADD_L })
|
||||
public long testShiftOfSubConstant(long x) {
|
||||
return ((1 - x) << 1) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,17 +30,17 @@ import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8324751
|
||||
* @bug 8324751 8369435
|
||||
* @summary Reported issue: JDK-8359688: C2 SuperWord: missing RCE with MemorySegment
|
||||
* The examples are generated from TestAliasingFuzzer.java
|
||||
* So if you see something change here, you may want to investigate if we
|
||||
* can also tighten up the IR rules there.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.loopopts.superword.TestMemorySegment_8359688
|
||||
* @run driver compiler.loopopts.superword.TestMemorySegment_SubOfShift
|
||||
*/
|
||||
|
||||
|
||||
public class TestMemorySegment_8359688 {
|
||||
public class TestMemorySegment_SubOfShift {
|
||||
|
||||
public static MemorySegment b = MemorySegment.ofArray(new long[4 * 30_000]);
|
||||
|
||||
@ -61,17 +61,13 @@ public class TestMemorySegment_8359688 {
|
||||
|
||||
@Test
|
||||
@Arguments(setup = "setup")
|
||||
@IR(counts = {IRNode.STORE_VECTOR, "= 0",
|
||||
IRNode.REPLICATE_L, "= 0",
|
||||
@IR(counts = {IRNode.STORE_VECTOR, "> 0",
|
||||
IRNode.REPLICATE_L, "= 1",
|
||||
".*multiversion.*", "= 0"}, // AutoVectorization Predicate SUFFICES, there is no aliasing
|
||||
phase = CompilePhase.PRINT_IDEAL,
|
||||
applyIfPlatform = {"64-bit", "true"},
|
||||
applyIf = {"AlignVector", "false"},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
// Does not manage to remove all RangeChecks -> no vectorization
|
||||
// If you see this IR rule fail: investigate JDK-8359688, possibly close it and fix this IR rule!
|
||||
// Also: consider renaming the file to something more descriptive: what have you fixed with this?
|
||||
// And: you may now be able to tighten IR rules in TestAliasingFuzzer.java
|
||||
public static void test1(MemorySegment b, int ivLo, int ivHi, int invar) {
|
||||
for (int i = ivLo; i < ivHi; i++) {
|
||||
b.setAtIndex(ValueLayout.JAVA_LONG_UNALIGNED, 30_000L - (long)i + (long)invar, 42);
|
||||
Loading…
x
Reference in New Issue
Block a user