Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/hotspot/share/opto/addnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/hotspot/share/opto/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ public static void main(String[] args) {
"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();
Expand Down Expand Up @@ -82,6 +84,10 @@ public void assertResult(int a, int b, int c, int d) {
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
Expand Down Expand Up @@ -247,4 +253,44 @@ public int test18(int a, int b, int c) {
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public static void main(String[] args) {
"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();
Expand All @@ -61,26 +62,30 @@ public void runMethod() {

@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
Expand Down Expand Up @@ -238,4 +243,48 @@ public long test17(long a, long b, long c) {
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;
}
}
2 changes: 2 additions & 0 deletions test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down