8267265: Use new IR Test Framework to create tests for C2 Ideal transformations
Reviewed-by: chagedorn
This commit is contained in:
parent
86723d4892
commit
efd3967b54
test/hotspot/jtreg/compiler
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Test that Ideal transformations of AddINode* are being performed as expected.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.AddINodeIdealizationTests
|
||||
*/
|
||||
public class AddINodeIdealizationTests {
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@Run(test = {"additions", "xMinusX", "test1",
|
||||
"test2", "test3", "test4",
|
||||
"test5", "test6", "test7",
|
||||
"test8", "test9", "test10",
|
||||
"test11", "test12", "test13",
|
||||
"test14", "test15", "test16",
|
||||
"test17", "test18", "test19"})
|
||||
public void runMethod() {
|
||||
int a = RunInfo.getRandom().nextInt();
|
||||
int b = RunInfo.getRandom().nextInt();
|
||||
int c = RunInfo.getRandom().nextInt();
|
||||
int d = RunInfo.getRandom().nextInt();
|
||||
|
||||
int min = Integer.MIN_VALUE;
|
||||
int max = Integer.MAX_VALUE;
|
||||
|
||||
assertResult(0, 0, 0, 0);
|
||||
assertResult(a, b, c, d);
|
||||
assertResult(min, min, min, min);
|
||||
assertResult(max, max, max, max);
|
||||
}
|
||||
|
||||
@DontCompile
|
||||
public void assertResult(int a, int b, int c, int d) {
|
||||
Asserts.assertEQ(((a+a) + (a+a)) , additions(a));
|
||||
Asserts.assertEQ(0 , 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) + (b - c), test8(a, b, c));
|
||||
Asserts.assertEQ((a - b) + (c - a), test9(a, b, c));
|
||||
Asserts.assertEQ(a + (0 - b) , test10(a, b));
|
||||
Asserts.assertEQ((0 - b) + a , test11(a, b));
|
||||
Asserts.assertEQ((a - b) + b , test12(a, b));
|
||||
Asserts.assertEQ(b + (a - b) , test13(a, b));
|
||||
Asserts.assertEQ(a + 0 , test14(a));
|
||||
Asserts.assertEQ(0 + a , test15(a));
|
||||
Asserts.assertEQ(a*b + a*c , test16(a, b, c));
|
||||
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));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "2"})
|
||||
// Checks (x + x) + (x + x) => a=(x + x); r=a+a
|
||||
public int additions(int x) {
|
||||
return (x + x) + (x + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.SUB})
|
||||
// Checks (x - x) + (x - x) => 0
|
||||
public int xMinusX(int x) {
|
||||
return (x - x) + (x - x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "1"})
|
||||
// Checks (x + c1) + c2 => x + c3 where c3 = c1 + c2
|
||||
public int test1(int x) {
|
||||
return (x + 1) + 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "2"})
|
||||
// Checks (x + c1) + y => (x + y) + c1
|
||||
public int test2(int x, int y) {
|
||||
return (x + 2021) + y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "2"})
|
||||
// Checks x + (y + c1) => (x + y) + c1
|
||||
public int test3(int x, int y) {
|
||||
return x + (y + 2021);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (c1 - x) + c2 => c3 - x where c3 = c1 + c2
|
||||
public int test4(int x) {
|
||||
return (1 - x) + 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SUB, "1",
|
||||
IRNode.ADD, "2",
|
||||
})
|
||||
// Checks (a - b) + (c - d) => (a + c) - (b + d)
|
||||
public int test5(int a, int b, int c, int d) {
|
||||
return (a - b) + (c - d);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB})
|
||||
@IR(counts = {IRNode.ADD, "1"})
|
||||
// Checks (a - b) + (b + c) => (a + c)
|
||||
public int test6(int a, int b, int c) {
|
||||
return (a - b) + (b + c);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB})
|
||||
@IR(counts = {IRNode.ADD, "1"})
|
||||
// Checks (a - b) + (c + b) => (a + c)
|
||||
public int test7(int a, int b, int c) {
|
||||
return (a - b) + (c + b);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (a - b) + (b - c) => (a - c)
|
||||
public int test8(int a, int b, int c) {
|
||||
return (a - b) + (b - c);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (a - b) + (c - a) => (c - b)
|
||||
public int test9(int a, int b, int c) {
|
||||
return (a - b) + (c - a);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks x + (0 - y) => (x - y)
|
||||
public int test10(int x, int y) {
|
||||
return x + (0 - y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (0 - y) + x => (x - y)
|
||||
public int test11(int x, int y) {
|
||||
return (0 - y) + x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.SUB})
|
||||
// Checks (x - y) + y => x
|
||||
public int test12(int x, int y) {
|
||||
return (x - y) + y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.SUB})
|
||||
// Checks y + (x - y) => x
|
||||
public int test13(int x, int y) {
|
||||
return y + (x - y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
// Checks x + 0 => x
|
||||
public int test14(int x) {
|
||||
return x + 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
// Checks 0 + x => x
|
||||
public int test15(int x) {
|
||||
return 0 + x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks "a*b + a*c => a*(b+c)
|
||||
public int test16(int a, int b, int c) {
|
||||
return a*b + a*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks a*b + b*c => b*(a+c)
|
||||
public int test17(int a, int b, int c) {
|
||||
return a*b + b*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks a*c + b*c => (a+b)*c
|
||||
public int test18(int a, int b, int c) {
|
||||
return a*c + b*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks a*b + c*a => a*(b+c)
|
||||
public int test19(int a, int b, int c) {
|
||||
return a*b + c*a;
|
||||
}
|
||||
}
|
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Test that Ideal transformations of AddLNode* are being performed as expected.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.AddLNodeIdealizationTests
|
||||
*/
|
||||
public class AddLNodeIdealizationTests {
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@Run(test = {"additions", "xMinusX", "test1",
|
||||
"test2", "test3", "test4",
|
||||
"test5", "test6", "test7",
|
||||
"test8", "test9", "test10",
|
||||
"test11", "test12", "test13",
|
||||
"test14", "test15", "test16",
|
||||
"test17", "test18"})
|
||||
public void runMethod() {
|
||||
long a = RunInfo.getRandom().nextLong();
|
||||
long b = RunInfo.getRandom().nextLong();
|
||||
long c = RunInfo.getRandom().nextLong();
|
||||
long d = RunInfo.getRandom().nextLong();
|
||||
|
||||
long min = Long.MIN_VALUE;
|
||||
long max = Long.MAX_VALUE;
|
||||
|
||||
assertResult(0, 0, 0, 0);
|
||||
assertResult(a, b, c, d);
|
||||
assertResult(min, min, min, min);
|
||||
assertResult(max, max, max, max);
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "2"})
|
||||
// Checks (x + x) + (x + x) => a=(x + x); r=a+a
|
||||
public long additions(long x) {
|
||||
return (x + x) + (x + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.SUB})
|
||||
// Checks (x - x) => 0 and 0 - 0 => 0
|
||||
public long xMinusX(long x) {
|
||||
return (x - x) + (x - x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "1"})
|
||||
// Checks (x + c1) + c2 => x + c3 where c3 = c1 + c2
|
||||
public long test1(long x) {
|
||||
return (x + 1) + 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "2"})
|
||||
// Checks (x + c1) + y => (x + y) + c1
|
||||
public long test2(long x, long y) {
|
||||
return (x + 2021) + y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "2"})
|
||||
// Checks x + (y + c1) => (x + y) + c1
|
||||
public long test3(long x, long y) {
|
||||
return x + (y + 2021);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (c1 - x) + c2 => c3 - x where c3 = c1 + c2
|
||||
public long test4(long x) {
|
||||
return (1 - x) + 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SUB, "1",
|
||||
IRNode.ADD, "2",
|
||||
})
|
||||
// Checks (a - b) + (c - d) => (a + c) - (b + d)
|
||||
public long test5(long a, long b, long c, long d) {
|
||||
return (a - b) + (c - d);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB})
|
||||
@IR(counts = {IRNode.ADD, "1"})
|
||||
// Checks (a - b) + (b + c) => (a + c)
|
||||
public long test6(long a, long b, long c) {
|
||||
return (a - b) + (b + c);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB})
|
||||
@IR(counts = {IRNode.ADD, "1"})
|
||||
// Checks (a - b) + (c + b) => (a + c)
|
||||
public long test7(long a, long b, long c) {
|
||||
return (a - b) + (c + b);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (a - b) + (c - a) => (c - b)
|
||||
public long test8(long a, long b, long c) {
|
||||
return (a - b) + (c - a);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks x + (0 - y) => (x - y)
|
||||
public long test9(long x, long y) {
|
||||
return x + (0 - y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (0 - y) + x => (x - y)
|
||||
public long test10(long x, long y) {
|
||||
return (0 - y) + x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.SUB})
|
||||
// Checks (x - y) + y => x
|
||||
public long test11(long x, long y) {
|
||||
return (x - y) + y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.SUB})
|
||||
// Checks y + (x - y) => x
|
||||
public long test12(long x, long y) {
|
||||
return y + (x - y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
// Checks x + 0 => x
|
||||
public long test13(long x) {
|
||||
return x + 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
// Checks 0 + x => x
|
||||
public long test14(long x) {
|
||||
return 0 + x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks "a*b + a*c => a*(b+c)
|
||||
public long test15(long a, long b, long c) {
|
||||
return a*b + a*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks a*b + b*c => b*(a+c)
|
||||
public long test16(long a, long b, long c) {
|
||||
return a*b + b*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks a*c + b*c => (a+b)*c
|
||||
public long test17(long a, long b, long c) {
|
||||
return a*c + b*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks a*b + c*a => a*(b+c)
|
||||
public long test18(long a, long b, long c) {
|
||||
return a*b + c*a;
|
||||
}
|
||||
}
|
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Test that Ideal transformations of DivINode* are being performed as expected.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.DivINodeIdealizationTests
|
||||
*/
|
||||
public class DivINodeIdealizationTests {
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@Run(test = {"constant", "identity", "identityAgain", "identityThird",
|
||||
"retainDenominator", "divByNegOne", "divByPow2And",
|
||||
"divByPow2And1", "divByPow2", "divByNegPow2",
|
||||
"magicDiv"})
|
||||
public void runMethod() {
|
||||
int a = RunInfo.getRandom().nextInt();
|
||||
a = (a == 0) ? 1 : a;
|
||||
int b = RunInfo.getRandom().nextInt();
|
||||
b = (b == 0) ? 1 : b;
|
||||
|
||||
int min = Integer.MIN_VALUE;
|
||||
int max = Integer.MAX_VALUE;
|
||||
|
||||
assertResult(0, 0, true);
|
||||
assertResult(a, b, false);
|
||||
assertResult(min, min, false);
|
||||
assertResult(max, max, false);
|
||||
}
|
||||
|
||||
@DontCompile
|
||||
public void assertResult(int a, int b, boolean shouldThrow) {
|
||||
try {
|
||||
Asserts.assertEQ(a / a, constant(a));
|
||||
Asserts.assertFalse(shouldThrow, "Expected an exception to be thrown.");
|
||||
}
|
||||
catch (ArithmeticException e) {
|
||||
Asserts.assertTrue(shouldThrow, "Did not expected an exception to be thrown.");
|
||||
}
|
||||
|
||||
try {
|
||||
Asserts.assertEQ(a / (b / b), identityThird(a, b));
|
||||
Asserts.assertFalse(shouldThrow, "Expected an exception to be thrown.");
|
||||
}
|
||||
catch (ArithmeticException e) {
|
||||
Asserts.assertTrue(shouldThrow, "Did not expected an exception to be thrown.");
|
||||
}
|
||||
|
||||
try {
|
||||
Asserts.assertEQ((a * b) / b, retainDenominator(a, b));
|
||||
Asserts.assertFalse(shouldThrow, "Expected an exception to be thrown.");
|
||||
}
|
||||
catch (ArithmeticException e) {
|
||||
Asserts.assertTrue(shouldThrow, "Did not expected an exception to be thrown.");
|
||||
}
|
||||
|
||||
Asserts.assertEQ(a / 1 , identity(a));
|
||||
Asserts.assertEQ(a / (13 / 13), identityAgain(a));
|
||||
Asserts.assertEQ(a / -1 , divByNegOne(a));
|
||||
Asserts.assertEQ((a & -4) / 2 , divByPow2And(a));
|
||||
Asserts.assertEQ((a & -2) / 2 , divByPow2And1(a));
|
||||
Asserts.assertEQ(a / 8 , divByPow2(a));
|
||||
Asserts.assertEQ(a / -8 , divByNegPow2(a));
|
||||
Asserts.assertEQ(a / 13 , magicDiv(a));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.DIV_BY_ZERO_TRAP, "1"})
|
||||
// Checks x / x => 1
|
||||
public int constant(int x) {
|
||||
return x / x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
// Checks x / 1 => x
|
||||
public int identity(int x) {
|
||||
return x / 1;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
// Checks x / (c / c) => x
|
||||
public int identityAgain(int x) {
|
||||
return x / (13 / 13);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.DIV_BY_ZERO_TRAP, "1"})
|
||||
// Checks x / (y / y) => x
|
||||
public int identityThird(int x, int y) {
|
||||
return x / (y / y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.DIV, "1",
|
||||
IRNode.DIV_BY_ZERO_TRAP, "1"
|
||||
})
|
||||
// Hotspot should keep the division because it may cause a division by zero trap
|
||||
public int retainDenominator(int x, int y) {
|
||||
return (x * y) / y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.SUB_I, "1"})
|
||||
// Checks x / -1 => 0 - x
|
||||
public int divByNegOne(int x) {
|
||||
return x / -1;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.AND, "1",
|
||||
IRNode.RSHIFT, "1",
|
||||
})
|
||||
// Checks (x & -(2^c0)) / 2^c1 => (x >> c1) & (2^c0 >> c1) => (x >> c1) & c3 where 2^c0 > |2^c1| "AND" c3 = 2^c0 >> c1
|
||||
// Having a large enough and in the dividend removes the need to account for rounding when converting to shifts and multiplies as in divByPow2()
|
||||
public int divByPow2And(int x) {
|
||||
return (x & -4) / 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV, IRNode.AND})
|
||||
@IR(counts = {IRNode.RSHIFT, "1"})
|
||||
// Checks (x & -(2^c0)) / 2^c0 => x >> c0
|
||||
// If the negative of the constant within the & equals the divisor then the and can be removed as it only affects bits that will be shifted off
|
||||
public int divByPow2And1(int x) {
|
||||
return (x & -2) / 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.URSHIFT, "1",
|
||||
IRNode.RSHIFT, "2",
|
||||
IRNode.ADD_I, "1",
|
||||
})
|
||||
// Checks x / 2^c0 => x + ((x >> (32-1)) >>> (32 - c0)) >> c0 => x + ((x >> 31) >>> c1) >> c0 where c1 = 32 - c0
|
||||
// An additional (dividend - 1) needs to be added to the shift to account for rounding when dealing with negative numbers.
|
||||
// Since x may be negative in this method, an additional add, logical right shift, and signed shift are needed to account for rounding.
|
||||
public int divByPow2(int x) {
|
||||
return x / 8;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.URSHIFT, "1",
|
||||
IRNode.RSHIFT, "2",
|
||||
IRNode.ADD_I, "1",
|
||||
IRNode.SUB_I, "1",
|
||||
})
|
||||
// Checks x / -(2^c0) =>0 - (x + ((x >> (32-1)) >>> (32 - c0)) >> c0) => 0 - (x + ((x >> 31) >>> c1) >> c0) where c1 = 32 - c0
|
||||
// Similar to divByPow2() except a negative divisor turns positive.
|
||||
// After the transformations, 0 is subtracted by the whole expression
|
||||
// to account for the negative.
|
||||
public int divByNegPow2(int x) {
|
||||
return x / -8;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.SUB, "1",
|
||||
IRNode.MUL, "1",
|
||||
IRNode.CONV_I2L, "1",
|
||||
IRNode.CONV_L2I, "1",
|
||||
})
|
||||
// Checks magic int division occurs in general when dividing by a non power of 2.
|
||||
// More tests can be made to cover the specific cases for differences in the
|
||||
// graph that depend upon different values for the "magic constant" and the
|
||||
// "shift constant"
|
||||
public int magicDiv(int x) {
|
||||
return x / 13;
|
||||
}
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Test that Ideal transformations of DivLNode* are being performed as expected.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.DivLNodeIdealizationTests
|
||||
*/
|
||||
public class DivLNodeIdealizationTests {
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@Run(test = {"constant", "identity", "identityAgain", "identityThird",
|
||||
"retainDenominator", "divByNegOne", "divByPow2And",
|
||||
"divByPow2And1", "divByPow2", "divByNegPow2"})
|
||||
public void runMethod() {
|
||||
long a = RunInfo.getRandom().nextLong();
|
||||
a = (a == 0) ? 1 : a;
|
||||
long b = RunInfo.getRandom().nextLong();
|
||||
b = (b == 0) ? 1 : b;
|
||||
|
||||
long min = Long.MIN_VALUE;
|
||||
long max = Long.MAX_VALUE;
|
||||
|
||||
assertResult(0, 0, true);
|
||||
assertResult(a, b, false);
|
||||
assertResult(min, min, false);
|
||||
assertResult(max, max, false);
|
||||
}
|
||||
|
||||
@DontCompile
|
||||
public void assertResult(long a, long b, boolean shouldThrow) {
|
||||
try {
|
||||
Asserts.assertEQ(a / a, constant(a));
|
||||
Asserts.assertFalse(shouldThrow, "Expected an exception to be thrown.");
|
||||
}
|
||||
catch (ArithmeticException e) {
|
||||
Asserts.assertTrue(shouldThrow, "Did not expected an exception to be thrown.");
|
||||
}
|
||||
|
||||
try {
|
||||
Asserts.assertEQ((a * b) / b, retainDenominator(a, b));
|
||||
Asserts.assertFalse(shouldThrow, "Expected an exception to be thrown.");
|
||||
}
|
||||
catch (ArithmeticException e) {
|
||||
Asserts.assertTrue(shouldThrow, "Did not expected an exception to be thrown.");
|
||||
}
|
||||
|
||||
try {
|
||||
Asserts.assertEQ(a / (b / b), identityThird(a, b));
|
||||
Asserts.assertFalse(shouldThrow, "Expected an exception to be thrown.");
|
||||
}
|
||||
catch (ArithmeticException e) {
|
||||
Asserts.assertTrue(shouldThrow, "Did not expected an exception to be thrown.");
|
||||
}
|
||||
|
||||
Asserts.assertEQ(a / 1 , identity(a));
|
||||
Asserts.assertEQ(a / (13 / 13), identityAgain(a));
|
||||
Asserts.assertEQ(a / -1 , divByNegOne(a));
|
||||
Asserts.assertEQ((a & -4) / 2 , divByPow2And(a));
|
||||
Asserts.assertEQ((a & -2) / 2 , divByPow2And1(a));
|
||||
Asserts.assertEQ(a / 8 , divByPow2(a));
|
||||
Asserts.assertEQ(a / -8 , divByNegPow2(a));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.DIV_BY_ZERO_TRAP, "1"})
|
||||
// Checks x / x => 1
|
||||
public long constant(long x) {
|
||||
return x / x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
// Checks x / 1 => x
|
||||
public long identity(long x) {
|
||||
return x / 1L;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
// Checks x / (c / c) => x
|
||||
public long identityAgain(long x) {
|
||||
return x / (13L / 13L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.DIV_BY_ZERO_TRAP, "1"})
|
||||
// Checks x / (y / y) => x
|
||||
public long identityThird(long x, long y) {
|
||||
return x / (y / y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL_L, "1",
|
||||
IRNode.DIV_L, "1",
|
||||
IRNode.DIV_BY_ZERO_TRAP, "1"
|
||||
})
|
||||
// Hotspot should keep the division because it may cause a division by zero trap
|
||||
public long retainDenominator(long x, long y) {
|
||||
return (x * y) / y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks x / -1 => 0 - x
|
||||
public long divByNegOne(long x) {
|
||||
return x / -1L;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.AND, "1",
|
||||
IRNode.RSHIFT, "1",
|
||||
})
|
||||
// Checks (x & -(2^c0)) / 2^c1 => (x >> c1) & (2^c0 >> c1) => (x >> c1) & c3 where 2^c0 > |2^c1| "and" c3 = 2^c0 >> c1
|
||||
// Having a large enough and in the dividend removes the need to account for
|
||||
// rounding when converting to shifts and multiplies as in divByPow2()
|
||||
public long divByPow2And(long x) {
|
||||
return (x & -4L) / 2L;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV, IRNode.AND})
|
||||
@IR(counts = {IRNode.RSHIFT, "1"})
|
||||
// Checks (x & -(2^c0)) / 2^c0 => x >> c0
|
||||
// If the negative of the constant within the & equals the divisor then
|
||||
// the and can be removed as it only affects bits that will be shifted off
|
||||
public long divByPow2And1(long x) {
|
||||
return (x & -2L) / 2L;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.URSHIFT, "1",
|
||||
IRNode.RSHIFT, "2",
|
||||
IRNode.ADD, "1",
|
||||
})
|
||||
// Checks x / 2^c0 => x + ((x >>)ith negative numbers. Since x may be negative
|
||||
// in this method, an additional add, logical right shift, and signed shift
|
||||
// are needed to account for rounding.
|
||||
public long divByPow2(long x) {
|
||||
return x / 8L;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.DIV})
|
||||
@IR(counts = {IRNode.URSHIFT, "1",
|
||||
IRNode.RSHIFT, "2",
|
||||
IRNode.ADD, "1",
|
||||
IRNode.SUB, "1",
|
||||
})
|
||||
// Checks x / -(2^c0) =>0 - (x + ((x >> (32-1)) >>> (32 - c0)) >> c0) => 0 - (x + ((x >> 31) >>> c1) >> c0) where c1 = 32 - c0
|
||||
// Similar to divByPow2() except a negative divisor turns positive.
|
||||
// After the transformations, 0 is subtracted by the whole expression
|
||||
// to account for the negative.
|
||||
public long divByNegPow2(long x) {
|
||||
return x / -8L;
|
||||
}
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Test that Ideal transformations of MulINode* are being performed as expected.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.MulINodeIdealizationTests
|
||||
*/
|
||||
public class MulINodeIdealizationTests {
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@Run(test = {"combineConstants", "moveConstants", "moveConstantsAgain",
|
||||
"multiplyZero", "multiplyZeroAgain", "distribute",
|
||||
"identity", "identityAgain", "powerTwo",
|
||||
"powerTwoAgain", "powerTwoPlusOne", "powerTwoMinusOne"})
|
||||
public void runMethod() {
|
||||
int a = RunInfo.getRandom().nextInt();
|
||||
int b = RunInfo.getRandom().nextInt();
|
||||
|
||||
int min = Integer.MIN_VALUE;
|
||||
int max = Integer.MAX_VALUE;
|
||||
|
||||
assertResult(0, 0);
|
||||
assertResult(a, b);
|
||||
assertResult(min, min);
|
||||
assertResult(max, max);
|
||||
}
|
||||
|
||||
@DontCompile
|
||||
public void assertResult(int a, int b) {
|
||||
Asserts.assertEQ((a * 13) * 14 , combineConstants(a));
|
||||
Asserts.assertEQ((a * 13) * b , moveConstants(a, b));
|
||||
Asserts.assertEQ(a * (b * 13) , moveConstantsAgain(a, b));
|
||||
Asserts.assertEQ(0 * a , multiplyZero(a));
|
||||
Asserts.assertEQ(a * 0 , multiplyZeroAgain(a));
|
||||
Asserts.assertEQ((13 + a) * 14 , distribute(a));
|
||||
Asserts.assertEQ(1 * a , identity(a));
|
||||
Asserts.assertEQ(a * 1 , identityAgain(a));
|
||||
Asserts.assertEQ(a * 64 , powerTwo(a));
|
||||
Asserts.assertEQ(a * (1025 - 1), powerTwoAgain(a));
|
||||
Asserts.assertEQ(a * (64 + 1) , powerTwoPlusOne(a));
|
||||
Asserts.assertEQ(a * (64 - 1) , powerTwoMinusOne(a));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1"})
|
||||
//Checks (x * c1) * c2 => x * c3 where c3 = c1 * c2
|
||||
public int combineConstants(int x){
|
||||
return (x * 13) * 14;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "2"})
|
||||
// Checks (x * c1) * y => (x * y) * c1
|
||||
public int moveConstants(int x, int y) {
|
||||
return (x * 13) * y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "2"})
|
||||
// Checks x * (y * c1) => (x * y) * c1
|
||||
public int moveConstantsAgain(int x, int y) {
|
||||
return x * (y * 13);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
// Checks 0 * x => 0
|
||||
public int multiplyZero(int x) {
|
||||
return 0 * x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
// Checks x * 0 => 0
|
||||
public int multiplyZeroAgain(int x) {
|
||||
return x * 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1",
|
||||
})
|
||||
// Checks (c1 + x) * c2 => x * c2 + c3 where c3 = c1 * c2
|
||||
public int distribute(int x) {
|
||||
return (13 + x) * 14;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
// Checks 1 * x => x
|
||||
public int identity(int x) {
|
||||
return 1 * x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
// Checks x * 1 => x
|
||||
public int identityAgain(int x) {
|
||||
return x * 1;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
@IR(counts = {IRNode.LSHIFT, "1"})
|
||||
// Checks x * 2^n => x << n
|
||||
public int powerTwo(int x) {
|
||||
return x * 64;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB, IRNode.MUL})
|
||||
@IR(counts = {IRNode.LSHIFT, "1"})
|
||||
// Checks x * 2^n => x << n
|
||||
public int powerTwoAgain(int x) {
|
||||
return x * (1025 - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
@IR(counts = {IRNode.LSHIFT, "1",
|
||||
IRNode.ADD, "1",
|
||||
})
|
||||
// Checks x * (2^n + 1) => (x << n) + x
|
||||
public int powerTwoPlusOne(int x) {
|
||||
return x * (64 + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
@IR(counts = {IRNode.LSHIFT, "1",
|
||||
IRNode.SUB, "1",
|
||||
})
|
||||
// Checks x * (2^n - 1) => (x << n) - x
|
||||
public int powerTwoMinusOne(int x) {
|
||||
return x * (64 - 1);
|
||||
}
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Test that Ideal transformations of MulLNode* are being performed as expected.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.MulLNodeIdealizationTests
|
||||
*/
|
||||
public class MulLNodeIdealizationTests {
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@Run(test = {"combineConstants", "moveConstants", "moveConstantsAgain",
|
||||
"multiplyZero", "multiplyZeroAgain", "distribute",
|
||||
"identity", "identityAgain", "powerTwo",
|
||||
"powerTwoAgain", "powerTwoPlusOne", "powerTwoMinusOne"})
|
||||
public void runMethod() {
|
||||
long a = RunInfo.getRandom().nextLong();
|
||||
long b = RunInfo.getRandom().nextLong();
|
||||
|
||||
long min = Long.MIN_VALUE;
|
||||
long max = Long.MAX_VALUE;
|
||||
|
||||
assertResult(0, 0);
|
||||
assertResult(a, b);
|
||||
assertResult(min, min);
|
||||
assertResult(max, max);
|
||||
}
|
||||
|
||||
@DontCompile
|
||||
public void assertResult(long a, long b) {
|
||||
Asserts.assertEQ((a * 13) * 14 * 15, combineConstants(a));
|
||||
Asserts.assertEQ((a * 13) * b , moveConstants(a, b));
|
||||
Asserts.assertEQ(a * (b * 13) , moveConstantsAgain(a, b));
|
||||
Asserts.assertEQ(0 * a , multiplyZero(a));
|
||||
Asserts.assertEQ(a * 0 , multiplyZeroAgain(a));
|
||||
Asserts.assertEQ((13 + a) * 14 , distribute(a));
|
||||
Asserts.assertEQ(1 * a , identity(a));
|
||||
Asserts.assertEQ(a * 1 , identityAgain(a));
|
||||
Asserts.assertEQ(a * 64 , powerTwo(a));
|
||||
Asserts.assertEQ(a * (1025 - 1) , powerTwoAgain(a));
|
||||
Asserts.assertEQ(a * (64 + 1) , powerTwoPlusOne(a));
|
||||
Asserts.assertEQ(a * (64 - 1) , powerTwoMinusOne(a));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1"})
|
||||
//Checks (x * c1) * c2 => x * c3 where c3 = c1 * c2
|
||||
public long combineConstants(long x){
|
||||
return (x * 13) * 14 * 15;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "2"})
|
||||
// Checks (x * c1) * y => (x * y) * c1
|
||||
public long moveConstants(long x, long y) {
|
||||
return (x * 13) * y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "2"})
|
||||
// Checks x * (y * c1) => (x * y) * c1
|
||||
public long moveConstantsAgain(long x, long y) {
|
||||
return x * (y * 13);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
// Checks 0 * x => 0
|
||||
public long multiplyZero(long x) {
|
||||
return 0 * x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
// Checks x * 0 => 0
|
||||
public long multiplyZeroAgain(long x) {
|
||||
return x * 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.ADD, "1",
|
||||
})
|
||||
// Checks (c1 + x) * c2 => x * c2 + c3 where c3 = c1 * c2
|
||||
public long distribute(long x) {
|
||||
return (13 + x) * 14;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
// Checks 1 * x => x
|
||||
public long identity(long x) {
|
||||
return 1 * x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
// Checks x * 1 => x
|
||||
public long identityAgain(long x) {
|
||||
return x * 1;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
@IR(counts = {IRNode.LSHIFT, "1"})
|
||||
// Checks x * 2^n => x << n
|
||||
public long powerTwo(long x) {
|
||||
return x * 64;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB, IRNode.MUL})
|
||||
@IR(counts = {IRNode.LSHIFT, "1"})
|
||||
// Checks x * 2^n => x << n
|
||||
public long powerTwoAgain(long x) {
|
||||
return x * (1025 - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
@IR(counts = {IRNode.LSHIFT, "1",
|
||||
IRNode.ADD, "1",
|
||||
})
|
||||
// Checks x * (2^n + 1) => (x << n) + x
|
||||
public long powerTwoPlusOne(long x) {
|
||||
return x * (64 + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL})
|
||||
@IR(counts = {IRNode.LSHIFT, "1",
|
||||
IRNode.SUB, "1",
|
||||
})
|
||||
// Checks x * (2^n - 1) => (x << n) - x
|
||||
public long powerTwoMinusOne(long x) {
|
||||
return x * (64 - 1);
|
||||
}
|
||||
}
|
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Test that Ideal transformations of SubINode* are being performed as expected.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.SubINodeIdealizationTests
|
||||
*/
|
||||
public class SubINodeIdealizationTests {
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@Run(test = {"test1", "test2", "test3",
|
||||
"test4", "test5", "test6",
|
||||
"test7", "test8", "test9",
|
||||
"test10", "test11", "test12",
|
||||
"test13", "test14", "test15",
|
||||
"test16", "test17", "test18",
|
||||
"test19", "test20", "test21"})
|
||||
public void runMethod() {
|
||||
int a = RunInfo.getRandom().nextInt();
|
||||
int b = RunInfo.getRandom().nextInt();
|
||||
int c = RunInfo.getRandom().nextInt();
|
||||
|
||||
int min = Integer.MIN_VALUE;
|
||||
int max = Integer.MAX_VALUE;
|
||||
|
||||
assertResult(0, 0, 0);
|
||||
assertResult(a, b, c);
|
||||
assertResult(min, min, min);
|
||||
assertResult(max, max, max);
|
||||
}
|
||||
|
||||
@DontCompile
|
||||
public void assertResult(int a, int b, int c) {
|
||||
Asserts.assertEQ(a - 1 , test1(a));
|
||||
Asserts.assertEQ((a + 1) - b , test2(a, b));
|
||||
Asserts.assertEQ(a - (b + 2021) , test3(a, b));
|
||||
Asserts.assertEQ(a - (a + b) , test4(a, b));
|
||||
Asserts.assertEQ((a - b) - a , test5(a, b));
|
||||
Asserts.assertEQ(a - (b + a) , test6(a, b));
|
||||
Asserts.assertEQ(0 - (a - b) , test7(a, b));
|
||||
Asserts.assertEQ(0 - (a + 2021) , test8(a));
|
||||
Asserts.assertEQ((a + b) - (a + c), test9(a, b, c));
|
||||
Asserts.assertEQ((b + a) - (c + a), test10(a, b, c));
|
||||
Asserts.assertEQ((b + a) - (a + c), test11(a, b, c));
|
||||
Asserts.assertEQ((a + b) - (c + a), test12(a, b, c));
|
||||
Asserts.assertEQ(a - (b - c) , test13(a, b, c));
|
||||
Asserts.assertEQ(0 - (a >> 31) , test14(a));
|
||||
Asserts.assertEQ(0 - (0 - a) , test15(a));
|
||||
Asserts.assertEQ((a + b) - b , test16(a, b));
|
||||
Asserts.assertEQ((a + b) - a , test17(a, b));
|
||||
Asserts.assertEQ(a*b - a*c , test18(a, b, c));
|
||||
Asserts.assertEQ(a*b - b*c , test19(a, b, c));
|
||||
Asserts.assertEQ(a*c - b*c , test20(a, b, c));
|
||||
Asserts.assertEQ(a*b - c*a , test21(a, b, c));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB})
|
||||
@IR(counts = {IRNode.ADD, "1"})
|
||||
// Checks (x - c0) => x + (-c0)
|
||||
public int test1(int x) {
|
||||
return (x - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "1",
|
||||
IRNode.SUB, "1"
|
||||
})
|
||||
// Checks (x + c0) - y => (x - y) + c0
|
||||
public int test2(int x, int y) {
|
||||
return (x + 1) - y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SUB, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks x - (y + c0) => (x - y) + (-c0)
|
||||
public int test3(int x, int y) {
|
||||
return x - (y + 2021);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks x - (x + y) => -y
|
||||
public int test4(int x, int y) {
|
||||
return x - (x + y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (x - y) - x => -y
|
||||
public int test5(int x, int y) {
|
||||
return (x - y) - x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks x - (y + x) => -y
|
||||
public int test6(int x, int y) {
|
||||
return x - (y + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks 0 - (x - y) => y - x
|
||||
public int test7(int x, int y) {
|
||||
return 0 - (x - y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks 0 - (x + 2021) => -2021 - x
|
||||
public int test8(int x) {
|
||||
return 0 - (x + 2021);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (x + a) - (x + b) => a - b;
|
||||
public int test9(int x, int a, int b) {
|
||||
return (x + a) - (x + b);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (a + x) - (b + x) => a - b
|
||||
public int test10(int x, int a, int b) {
|
||||
return (a + x) - (b + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (a + x) - (x + b) => a - b
|
||||
public int test11(int x, int a, int b) {
|
||||
return (a + x) - (x + b);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (x + a) - (b + x) => a - b
|
||||
public int test12(int x, int a, int b) {
|
||||
return (x + a) - (b + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SUB, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks a - (b - c) => (a + c) - b
|
||||
public int test13(int a, int b, int c) {
|
||||
return a - (b - c);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB, IRNode.RSHIFT_I})
|
||||
@IR(counts = {IRNode.URSHIFT_I, "1"})
|
||||
// Checks 0 - (a >> 31) => a >>> 31
|
||||
// signed ^^ ^^^ unsigned
|
||||
public int test14(int a) {
|
||||
return 0 - (a >> 31);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB})
|
||||
// Checks 0 - (0 - x) => x
|
||||
public int test15(int x) {
|
||||
return 0 - (0 - x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB, IRNode.ADD})
|
||||
// Checks (x + y) - y => y
|
||||
public int test16(int x, int y) {
|
||||
return (x + y) - y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB, IRNode.ADD})
|
||||
// Checks (x + y) - x => y
|
||||
public int test17(int x, int y) {
|
||||
return (x + y) - x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.SUB, "1"})
|
||||
// Checks "a*b-a*c => a*(b-c)
|
||||
public int test18(int a, int b, int c) {
|
||||
return a*b - a*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.SUB, "1"})
|
||||
// Checks a*b-b*c => b*(a-c)
|
||||
public int test19(int a, int b, int c) {
|
||||
return a*b - b*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.SUB, "1"})
|
||||
// Checks a*c-b*c => (a-b)*c
|
||||
public int test20(int a, int b, int c) {
|
||||
return a*c - b*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.SUB, "1"})
|
||||
// Checks a*b-c*a => a*(b-c)
|
||||
public int test21(int a, int b, int c) {
|
||||
return a*b - c*a;
|
||||
}
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Test that Ideal transformations of SubLNode* are being performed as expected.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.SubLNodeIdealizationTests
|
||||
*/
|
||||
public class SubLNodeIdealizationTests {
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@Run(test = {"test1", "test2", "test3",
|
||||
"test4", "test5", "test6",
|
||||
"test7", "test8", "test9",
|
||||
"test10", "test11", "test12",
|
||||
"test13", "test14", "test15",
|
||||
"test16", "test17", "test18"})
|
||||
public void runMethod() {
|
||||
long a = RunInfo.getRandom().nextLong();
|
||||
long b = RunInfo.getRandom().nextLong();
|
||||
long c = RunInfo.getRandom().nextLong();
|
||||
|
||||
long min = Long.MIN_VALUE;
|
||||
long max = Long.MAX_VALUE;
|
||||
|
||||
assertResult(0, 0, 0);
|
||||
assertResult(a, b, c);
|
||||
assertResult(min, min, min);
|
||||
assertResult(max, max, max);
|
||||
}
|
||||
|
||||
@DontCompile
|
||||
public void assertResult(long a, long b, long c) {
|
||||
Asserts.assertEQ(a - 1 , test1(a));
|
||||
Asserts.assertEQ((a + 1) - b , test2(a, b));
|
||||
Asserts.assertEQ(a - (b + 2021) , test3(a, b));
|
||||
Asserts.assertEQ(a - (a + b) , test4(a, b));
|
||||
Asserts.assertEQ(a - (b + a) , test5(a, b));
|
||||
Asserts.assertEQ(0 - (a - b) , test6(a, b));
|
||||
Asserts.assertEQ(0 - (a + 2021) , test7(a, b));
|
||||
Asserts.assertEQ((a + b) - (a + c), test8(a, b, c));
|
||||
Asserts.assertEQ((b + a) - (c + a), test9(a, b, c));
|
||||
Asserts.assertEQ((b + a) - (a + c), test10(a, b, c));
|
||||
Asserts.assertEQ((a + b) - (c + a), test11(a, b, c));
|
||||
Asserts.assertEQ(a - (b - c) , test12(a, b, c));
|
||||
Asserts.assertEQ(0 - (a >> 63) , test13(a));
|
||||
Asserts.assertEQ(0 - (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));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB})
|
||||
@IR(counts = {IRNode.ADD, "1"})
|
||||
// Checks (x - c0) => x + (-c0)
|
||||
public long test1(long x) {
|
||||
return (x - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD, "1",
|
||||
IRNode.SUB, "1"
|
||||
})
|
||||
// Checks (x + c0) - y => (x - y) + c0
|
||||
public long test2(long x, long y) {
|
||||
return (x + 1) - y;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SUB, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks x - (y + c0) => (x - y) + (-c0)
|
||||
public long test3(long x, long y) {
|
||||
return x - (y + 2021);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks x - (x + y) => 0 - y
|
||||
public long test4(long x, long y) {
|
||||
return x - (x + y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks x - (y + x) => 0 - y
|
||||
public long test5(long x, long y) {
|
||||
return x - (y + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks 0 - (x - y) => y - x
|
||||
public long test6(long x, long y) {
|
||||
return 0 - (x - y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks 0 - (x + 2021) => -2021 - x
|
||||
public long test7(long x, long y) {
|
||||
return 0 - (x + 2021);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (x + a) - (x + b) => a - b;
|
||||
public long test8(long x, long a, long b) {
|
||||
return (x + a) - (x + b);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (a + x) - (b + x) => a - b
|
||||
public long test9(long x, long a, long b) {
|
||||
return (a + x) - (b + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (a + x) - (x + b) => a - b
|
||||
public long test10(long x, long a, long b) {
|
||||
return (a + x) - (x + b);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD})
|
||||
@IR(counts = {IRNode.SUB, "1"})
|
||||
// Checks (x + a) - (b + x) => a - b
|
||||
public long test11(long x, long a, long b) {
|
||||
return (x + a) - (b + x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SUB, "1",
|
||||
IRNode.ADD, "1"
|
||||
})
|
||||
// Checks a - (b - c) => (a + c) - b
|
||||
public long test12(long a, long b, long c) {
|
||||
return a - (b - c);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB, IRNode.RSHIFT_L})
|
||||
@IR(counts = {IRNode.URSHIFT_L, "1"})
|
||||
// Checks 0 - (a >> 63) => a >>> 63
|
||||
// signed ^^ ^^^ unsigned
|
||||
public long test13(long a) {
|
||||
return 0 - (a >> 63);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.SUB})
|
||||
// Checks 0 - (0 - x) => x
|
||||
public long test14(long x) {
|
||||
return 0 - (0 - x);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.SUB, "1"})
|
||||
// Checks "a*b-a*c => a*(b-c)
|
||||
public long test15(long a, long b, long c) {
|
||||
return a*b - a*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.SUB, "1"})
|
||||
// Checks a*b-b*c => b*(a-c)
|
||||
public long test16(long a, long b, long c) {
|
||||
return a*b - b*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.SUB, "1"})
|
||||
// Checks a*c-b*c => (a-b)*c
|
||||
public long test17(long a, long b, long c) {
|
||||
return a*c - b*c;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.MUL, "1",
|
||||
IRNode.SUB, "1"})
|
||||
// Checks a*b-c*a => a*(b-c)
|
||||
public long test18(long a, long b, long c) {
|
||||
return a*b - c*a;
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests.loopOpts;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Test that Ideal transformations of CountedLoopNode* are being performed as expected.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.loopOpts.LoopIdealizationTests
|
||||
*/
|
||||
public class LoopIdealizationTests {
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@DontInline
|
||||
private void blackhole() { }
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.MUL, IRNode.DIV, IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.CALL})
|
||||
// Checks that a for loop with 0 iterations is removed
|
||||
public void zeroIterForLoop() {
|
||||
for (int i = 0; i < 0; i++) {
|
||||
System.out.println(13 / 17 * 23 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.CALL})
|
||||
// Checks that a for loop with 1 iteration doesn't have CountedLoop nodes
|
||||
public void iterOneBreakForLoop() {
|
||||
for (int i = 0; i < 500; i++) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
|
||||
@IR(counts = {IRNode.CALL, "1"})
|
||||
// Checks that a for loop with 1 iteration is simplified to straight code
|
||||
public void oneIterForLoop() {
|
||||
for (int i = 0; i < 1; i++) {
|
||||
this.blackhole();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
|
||||
@IR(counts = {IRNode.CALL, "1"})
|
||||
// Checks that a for loop with 1 iteration is simplified to straight code
|
||||
public void oneIterForLoop1() {
|
||||
for (int i = 0; i < 500; i++) {
|
||||
this.blackhole();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
|
||||
@IR(counts = {IRNode.CALL, "1"})
|
||||
// Checks that a for loop with 1 iteration is simplified to straight code
|
||||
public void oneIterForLoop2() {
|
||||
for (int i = 0; i < 500; i++) {
|
||||
this.blackhole();
|
||||
if (i == 0) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
this.blackhole();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.LOOP, IRNode.TRAP})
|
||||
@IR(counts = {IRNode.CALL, "1"})
|
||||
// Checks that a while loop with 1 iteration is simplified to straight code
|
||||
public void oneIterWhileLoop() {
|
||||
while (true) {
|
||||
this.blackhole();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
|
||||
@IR(counts = {IRNode.CALL, "1"})
|
||||
// Checks that a while loop with 1 iteration is simplified to straight code
|
||||
public void oneIterWhileLoop1() {
|
||||
int i = 0;
|
||||
while (i < 1) {
|
||||
this.blackhole();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.COUNTEDLOOP, IRNode.COUNTEDLOOP_MAIN, IRNode.TRAP})
|
||||
@IR(counts = {IRNode.CALL, "1"})
|
||||
// Checks that a while loop with 1 iteration is simplified to straight code
|
||||
public void oneIterWhileLoop2() {
|
||||
int i = 0;
|
||||
while (i < 500) {
|
||||
this.blackhole();
|
||||
if (i == 0) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
this.blackhole();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.LOOP, IRNode.TRAP})
|
||||
@IR(counts = {IRNode.CALL, "1"})
|
||||
// Checks that a while loop with 1 iteration is simplified to straight code
|
||||
public void oneIterDoWhileLoop() {
|
||||
do {
|
||||
this.blackhole();
|
||||
break;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.LOOP, IRNode.TRAP})
|
||||
@IR(counts = {IRNode.CALL, "1"})
|
||||
// Checks that a while loop with 1 iteration is simplified to straight code
|
||||
public void oneIterDoWhileLoop1() {
|
||||
do {
|
||||
this.blackhole();
|
||||
} while (false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.ADD, IRNode.LOOP, IRNode.TRAP})
|
||||
@IR(counts = {IRNode.CALL, "1"})
|
||||
// Checks that a while loop with 1 iteration is simplified to straight code
|
||||
public void oneIterDoWhileLoop2() {
|
||||
int i = 0;
|
||||
do {
|
||||
this.blackhole();
|
||||
i++;
|
||||
} while (i == -1);
|
||||
}
|
||||
}
|
100
test/hotspot/jtreg/compiler/c2/irTests/scalarReplacement/ScalarReplacementTests.java
Normal file
100
test/hotspot/jtreg/compiler/c2/irTests/scalarReplacement/ScalarReplacementTests.java
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package compiler.c2.irTests.scalarReplacement;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267265
|
||||
* @summary Tests that Escape Analysis and Scalar Replacement is able to handle some simple cases.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.scalarReplacement.ScalarReplacementTests
|
||||
*/
|
||||
public class ScalarReplacementTests {
|
||||
private class Person {
|
||||
private String name;
|
||||
private int age;
|
||||
|
||||
public Person(Person p) {
|
||||
this.name = p.getName();
|
||||
this.age = p.getAge();
|
||||
}
|
||||
|
||||
public Person(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getName() { return name; }
|
||||
public int getAge() { return age; }
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework.run();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Arguments(Argument.RANDOM_EACH)
|
||||
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
|
||||
public String stringConstant(int age) {
|
||||
Person p = new Person("Java", age);
|
||||
return p.getName();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Arguments(Argument.RANDOM_EACH)
|
||||
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
|
||||
public int intConstant(int age) {
|
||||
Person p = new Person("Java", age);
|
||||
return p.getAge();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Arguments(Argument.RANDOM_EACH)
|
||||
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
|
||||
public String nestedStringConstant(int age) {
|
||||
Person p1 = new Person("Java", age);
|
||||
Person p2 = new Person(p1);
|
||||
return p2.getName();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Arguments(Argument.RANDOM_EACH)
|
||||
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
|
||||
public int nestedIntConstant(int age) {
|
||||
Person p1 = new Person("Java", age);
|
||||
Person p2 = new Person(p1);
|
||||
return p2.getAge();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
|
||||
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
|
||||
public int nestedConstants(int age1, int age2) {
|
||||
Person p = new Person(
|
||||
new Person("Java", age1).getName(),
|
||||
new Person("Java", age2).getAge());
|
||||
return p.getAge();
|
||||
}
|
||||
}
|
@ -130,6 +130,7 @@ public class IRNode {
|
||||
public static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END;
|
||||
public static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END;
|
||||
public static final String INTRINSIC_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*intrinsic" + END;
|
||||
public static final String DIV_BY_ZERO_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*div0_check" + END;
|
||||
// Does not work for VM builds without JVMCI like x86_32 (a rule containing this regex will be skipped without having JVMCI built).
|
||||
public static final String INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*intrinsic_or_type_checked_inlining" + END;
|
||||
|
||||
@ -140,22 +141,36 @@ public class IRNode {
|
||||
public static final String ABS_L = START + "AbsL" + MID + END;
|
||||
public static final String ABS_F = START + "AbsF" + MID + END;
|
||||
public static final String ABS_D = START + "AbsD" + MID + END;
|
||||
public static final String AND = START + "And(I|L)" + MID + END;
|
||||
public static final String AND_I = START + "AndI" + MID + END;
|
||||
public static final String AND_L = START + "AndL" + MID + END;
|
||||
public static final String XOR_I = START + "XorI" + MID + END;
|
||||
public static final String XOR_L = START + "XorL" + MID + END;
|
||||
public static final String LSHIFT = START + "LShift(I|L)" + MID + END;
|
||||
public static final String LSHIFT_I = START + "LShiftI" + MID + END;
|
||||
public static final String LSHIFT_L = START + "LShiftL" + MID + END;
|
||||
public static final String RSHIFT = START + "RShift(I|L)" + MID + END;
|
||||
public static final String RSHIFT_I = START + "RShiftI" + MID + END;
|
||||
public static final String RSHIFT_L = START + "RShiftL" + MID + END;
|
||||
public static final String URSHIFT = START + "URShift(B|S|I|L)" + MID + END;
|
||||
public static final String URSHIFT_I = START + "URShiftI" + MID + END;
|
||||
public static final String URSHIFT_L = START + "URShiftL" + MID + END;
|
||||
public static final String ADD = START + "Add(I|L|F|D|P)" + MID + END;
|
||||
public static final String ADD_I = START + "AddI" + MID + END;
|
||||
public static final String ADD_L = START + "AddL" + MID + END;
|
||||
public static final String ADD_VD = START + "AddVD" + MID + END;
|
||||
public static final String SUB = START + "Sub(I|L|F|D)" + MID + END;
|
||||
public static final String SUB_I = START + "SubI" + MID + END;
|
||||
public static final String SUB_L = START + "SubL" + MID + END;
|
||||
public static final String SUB_F = START + "SubF" + MID + END;
|
||||
public static final String SUB_D = START + "SubD" + MID + END;
|
||||
public static final String MUL = START + "Mul(I|L|F|D)" + MID + END;
|
||||
public static final String MUL_I = START + "MulI" + MID + END;
|
||||
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 CONV_I2L = START + "ConvI2L" + MID + END;
|
||||
public static final String CONV_L2I = START + "ConvL2I" + MID + END;
|
||||
|
||||
public static final String VECTOR_CAST_B2X = START + "VectorCastB2X" + MID + END;
|
||||
public static final String VECTOR_CAST_S2X = START + "VectorCastS2X" + MID + END;
|
||||
|
Loading…
x
Reference in New Issue
Block a user