8283094: Add Ideal transformation: x + (con - y) -> (x - y) + con

Reviewed-by: kvn, thartmann
This commit is contained in:
Zhiqiang Zang 2022-04-13 16:01:10 +00:00 committed by Vladimir Kozlov
parent e245f9d200
commit c7755b815d
5 changed files with 135 additions and 28 deletions

View File

@ -304,14 +304,16 @@ Node* AddNode::IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt) {
}
}
// Convert "x+(0-y)" into "(x-y)"
if (op2 == Op_Sub(bt) && phase->type(in2->in(1)) == TypeInteger::zero(bt)) {
return SubNode::make(in1, in2->in(2), bt);
// Convert (con - y) + x into "(x - y) + con"
if (op1 == Op_Sub(bt) && in1->in(1)->Opcode() == Op_ConIL(bt)
&& in1 != in1->in(2) && !(in1->in(2)->is_Phi() && in1->in(2)->as_Phi()->is_tripcount(bt))) {
return AddNode::make(phase->transform(SubNode::make(in2, in1->in(2), bt)), in1->in(1), bt);
}
// Convert "(0-y)+x" into "(x-y)"
if (op1 == Op_Sub(bt) && phase->type(in1->in(1)) == TypeInteger::zero(bt)) {
return SubNode::make(in2, in1->in(2), bt);
// Convert x + (con - y) into "(x - y) + con"
if (op2 == Op_Sub(bt) && in2->in(1)->Opcode() == Op_ConIL(bt)
&& in2 != in2->in(2) && !(in2->in(2)->is_Phi() && in2->in(2)->as_Phi()->is_tripcount(bt))) {
return AddNode::make(phase->transform(SubNode::make(in1, in2->in(2), bt)), in2->in(1), bt);
}
// Associative

View File

@ -1853,6 +1853,14 @@ Op_IL(LShift)
Op_IL(Xor)
Op_IL(Cmp)
inline int Op_ConIL(BasicType bt) {
assert(bt == T_INT || bt == T_LONG, "only for int or longs");
if (bt == T_INT) {
return Op_ConI;
}
return Op_ConL;
}
inline int Op_Cmp_unsigned(BasicType bt) {
assert(bt == T_INT || bt == T_LONG, "only for int or longs");
if (bt == T_INT) {

View File

@ -43,7 +43,9 @@ public class AddINodeIdealizationTests {
"test8", "test9", "test10",
"test11", "test12", "test13",
"test14", "test15", "test16",
"test17", "test18", "test19"})
"test17", "test18", "test19",
"test20", "test21", "test22",
"test23"})
public void runMethod() {
int a = RunInfo.getRandom().nextInt();
int b = RunInfo.getRandom().nextInt();
@ -82,6 +84,10 @@ public class AddINodeIdealizationTests {
Asserts.assertEQ(a*b + b*c , test17(a, b, c));
Asserts.assertEQ(a*c + b*c , test18(a, b, c));
Asserts.assertEQ(a*b + c*a , test19(a, b, c));
Asserts.assertEQ((a - b) + 210 , test20(a, b));
Asserts.assertEQ((a - b) + 190 , test21(a, b));
Asserts.assertEQ((a - b) + 210 , test22(a, b));
Asserts.assertEQ((a - b) + 190 , test23(a, b));
}
@Test
@ -247,4 +253,44 @@ public class AddINodeIdealizationTests {
public int test19(int a, int b, int c) {
return a*b + c*a;
}
@Test
@IR(counts = {IRNode.SUB_I, "1",
IRNode.ADD_I, "1",
IRNode.CON_I, "1"})
// Checks x + (con - y) => (x - y) + con
// where con > 0
public int test20(int x, int y) {
return x + (10 - y) + 200; // transformed to (x - y) + 210;
}
@Test
@IR(counts = {IRNode.SUB_I, "1",
IRNode.ADD_I, "1",
IRNode.CON_I, "1"})
// Checks x + (con - y) => (x - y) + con
// where con < 0
public int test21(int x, int y) {
return x + (-10 - y) + 200; // transformed to (x - y) + 190;
}
@Test
@IR(counts = {IRNode.SUB_I, "1",
IRNode.ADD_I, "1",
IRNode.CON_I, "1"})
// Checks (con - y) + x => (x - y) + con
// where con > 0
public int test22(int x, int y) {
return (10 - y) + x + 200; // transformed to (x - y) + 210;
}
@Test
@IR(counts = {IRNode.SUB_I, "1",
IRNode.ADD_I, "1",
IRNode.CON_I, "1"})
// Checks (con - y) + x => (x - y) + con
// where con < 0
public int test23(int x, int y) {
return x + (-10 - y) + 200; // transformed to (x - y) + 190;
}
}

View File

@ -43,7 +43,8 @@ public class AddLNodeIdealizationTests {
"test8", "test9", "test10",
"test11", "test12", "test13",
"test14", "test15", "test16",
"test17", "test18"})
"test17", "test18", "test19",
"test20","test21", "test22"})
public void runMethod() {
long a = RunInfo.getRandom().nextLong();
long b = RunInfo.getRandom().nextLong();
@ -61,26 +62,30 @@ public class AddLNodeIdealizationTests {
@DontCompile
public void assertResult(long a, long b, long c, long d) {
Asserts.assertEQ(((a+a) + (a+a)) , additions(a));
Asserts.assertEQ(0L , xMinusX(a));
Asserts.assertEQ(a + 1 + 2 , test1(a));
Asserts.assertEQ((a + 2021) + b , test2(a, b));
Asserts.assertEQ(a + (b + 2021) , test3(a, b));
Asserts.assertEQ((1 - a) + 2 , test4(a));
Asserts.assertEQ((a - b) + (c - d), test5(a, b, c, d));
Asserts.assertEQ((a - b) + (b + c), test6(a, b, c));
Asserts.assertEQ((a - b) + (c + b), test7(a, b, c));
Asserts.assertEQ((a - b) + (c - a), test8(a, b, c));
Asserts.assertEQ(a + (0 - b) , test9(a, b));
Asserts.assertEQ((0 - b) + a , test10(a, b));
Asserts.assertEQ((a - b) + b , test11(a, b));
Asserts.assertEQ(b + (a - b) , test12(a, b));
Asserts.assertEQ(a + 0 , test13(a));
Asserts.assertEQ(0 + a , test14(a));
Asserts.assertEQ(a*b + a*c , test15(a, b, c));
Asserts.assertEQ(a*b + b*c , test16(a, b, c));
Asserts.assertEQ(a*c + b*c , test17(a, b, c));
Asserts.assertEQ(a*b + c*a , test18(a, b, c));
Asserts.assertEQ(((a+a) + (a+a)) , additions(a));
Asserts.assertEQ(0L , xMinusX(a));
Asserts.assertEQ(a + 1 + 2 , test1(a));
Asserts.assertEQ((a + 2021) + b , test2(a, b));
Asserts.assertEQ(a + (b + 2021) , test3(a, b));
Asserts.assertEQ((1 - a) + 2 , test4(a));
Asserts.assertEQ((a - b) + (c - d) , test5(a, b, c, d));
Asserts.assertEQ((a - b) + (b + c) , test6(a, b, c));
Asserts.assertEQ((a - b) + (c + b) , test7(a, b, c));
Asserts.assertEQ((a - b) + (c - a) , test8(a, b, c));
Asserts.assertEQ(a + (0 - b) , test9(a, b));
Asserts.assertEQ((0 - b) + a , test10(a, b));
Asserts.assertEQ((a - b) + b , test11(a, b));
Asserts.assertEQ(b + (a - b) , test12(a, b));
Asserts.assertEQ(a + 0 , test13(a));
Asserts.assertEQ(0 + a , test14(a));
Asserts.assertEQ(a*b + a*c , test15(a, b, c));
Asserts.assertEQ(a*b + b*c , test16(a, b, c));
Asserts.assertEQ(a*c + b*c , test17(a, b, c));
Asserts.assertEQ(a*b + c*a , test18(a, b, c));
Asserts.assertEQ((a - b) + 123_456_789_123L , test19(a, b));
Asserts.assertEQ((a - b) + -123_456_788_877L , test20(a, b));
Asserts.assertEQ((a - b) + 123_456_789_123L , test21(a, b));
Asserts.assertEQ((a - b) + -123_456_788_877L , test22(a, b));
}
@Test
@ -238,4 +243,48 @@ public class AddLNodeIdealizationTests {
public long test18(long a, long b, long c) {
return a*b + c*a;
}
@Test
@IR(counts = {IRNode.SUB_L, "1",
IRNode.ADD_L, "1",
IRNode.CON_L, "1"})
// Checks x + (con - y) => (x - y) + con
// where con > 0
public long test19(long x, long y) {
return x + (123_456_789_000L - y) + 123;
// transformed to (x - y) + 123_456_789_123L;
}
@Test
@IR(counts = {IRNode.SUB_L, "1",
IRNode.ADD_L, "1",
IRNode.CON_L, "1"})
// Checks x + (con - y) => (x - y) + con
// where con < 0
public long test20(long x, long y) {
return x + (-123_456_789_000L - y) + 123;
// transformed to (x - y) + -123_456_788_877L;
}
@Test
@IR(counts = {IRNode.SUB_L, "1",
IRNode.ADD_L, "1",
IRNode.CON_L, "1"})
// Checks (con - y) + x => (x - y) + con
// where con > 0
public long test21(long x, long y) {
return x + (123_456_789_000L - y) + 123;
// transformed to (x - y) + 123_456_789_123L;
}
@Test
@IR(counts = {IRNode.SUB_L, "1",
IRNode.ADD_L, "1",
IRNode.CON_L, "1"})
// Checks (con - y) + x => (x - y) + con
// where con < 0
public long test22(long x, long y) {
return x + (-123_456_789_000L - y) + 123;
// transformed to (x - y) + -123_456_788_877L;
}
}

View File

@ -171,6 +171,8 @@ public class IRNode {
public static final String MUL_L = START + "MulL" + MID + END;
public static final String DIV = START + "Div(I|L|F|D)" + MID + END;
public static final String DIV_L = START + "DivL" + MID + END;
public static final String CON_I = START + "ConI" + MID + END;
public static final String CON_L = START + "ConL" + MID + END;
public static final String CONV_I2L = START + "ConvI2L" + MID + END;
public static final String CONV_L2I = START + "ConvL2I" + MID + END;
public static final String POPCOUNT_L = START + "PopCountL" + MID + END;