Improve the IR test to add the new covered cases

I also checked the test is now failing in the master branch (at
f95af744b07a9ec87e2507b3d584cbcddc827bbd).
This commit is contained in:
Francisco Ferrari Bihurriet 2025-08-14 07:49:26 +02:00
parent 10e1e3f4f7
commit e6b1cb897d

View File

@ -41,16 +41,58 @@ public class TestBoolNodeGVN {
}
/**
* Test changing ((x & m) u<= m) or ((m & x) u<= m) to always true, same with ((x & m) u< m+1) and ((m & x) u< m+1)
* The test is only applicable to x64, aarch64 and riscv64 for having <code>Integer.compareUnsigned</code>
* intrinsified.
* Test CmpUNode::Value_cmpu_and_mask optimizations for cases 1a and 1b.
* The test is only applicable to x64, aarch64 and riscv64 for having
* <code>Integer.compareUnsigned</code> intrinsified.
*/
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(counts = {IRNode.CMP_U, "1"},
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aDoNotOptimizeForEQxm(int x, int m) {
// [BoolTest::eq] 1a) x & m =u m is unknown
return Integer.compareUnsigned((x & m), m) == 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(counts = {IRNode.CMP_U, "1"},
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aDoNotOptimizeForEQmx(int x, int m) {
// [BoolTest::eq] 1a) m & x =u m is unknown
return Integer.compareUnsigned((m & x), m) == 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(counts = {IRNode.CMP_U, "1"},
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aDoNotOptimizeForNExm(int x, int m) {
// [BoolTest::ne] 1a) x & m u m is unknown
return Integer.compareUnsigned((x & m), m) != 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(counts = {IRNode.CMP_U, "1"},
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aDoNotOptimizeForNEmx(int x, int m) {
// [BoolTest::ne] 1a) m & x u m is unknown
return Integer.compareUnsigned((m & x), m) != 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testShouldReplaceCpmUCase1(int x, int m) {
public static boolean testCase1aOptimizeAsTrueForLExm(int x, int m) {
// [BoolTest::le] 1a) x & m u m is always true
return Integer.compareUnsigned((x & m), m) <= 0;
}
@ -59,16 +101,166 @@ public class TestBoolNodeGVN {
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testShouldReplaceCpmUCase2(int x, int m) {
public static boolean testCase1aOptimizeAsTrueForLEmx(int x, int m) {
// [BoolTest::le] 1a) m & x u m is always true
return Integer.compareUnsigned((m & x), m) <= 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(counts = {IRNode.CMP_U, "1"},
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aDoNotOptimizeForGExm(int x, int m) {
// [BoolTest::ge] 1a) x & m u m is unknown
return Integer.compareUnsigned((x & m), m) >= 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(counts = {IRNode.CMP_U, "1"},
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aDoNotOptimizeForGEmx(int x, int m) {
// [BoolTest::ge] 1a) m & x u m is unknown
return Integer.compareUnsigned((m & x), m) >= 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(counts = {IRNode.CMP_U, "1"},
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aDoNotOptimizeForLTxm(int x, int m) {
// [BoolTest::lt] 1a) x & m <u m is unknown
return Integer.compareUnsigned((x & m), m) < 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(counts = {IRNode.CMP_U, "1"},
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aDoNotOptimizeForLTmx(int x, int m) {
// [BoolTest::lt] 1a) m & x <u m is unknown
return Integer.compareUnsigned((m & x), m) < 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aOptimizeAsFalseForGTxm(int x, int m) {
// [BoolTest::gt] 1a) x & m >u m is always false
return Integer.compareUnsigned((x & m), m) > 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1aOptimizeAsFalseForGTmx(int x, int m) {
// [BoolTest::gt] 1a) m & x >u m is always false
return Integer.compareUnsigned((m & x), m) > 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testShouldReplaceCpmUCase3(int x, int m) {
public static boolean testCase1bOptimizeAsFalseForEQxm(int x, int m) {
// [BoolTest::eq] 1b) x & m =u m + 1 is always false (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((x & m), m + 1) == 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsFalseForEQmx(int x, int m) {
// [BoolTest::eq] 1b) m & x =u m + 1 is always false (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((m & x), m + 1) == 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsTrueForNExm(int x, int m) {
// [BoolTest::ne] 1b) x & m u m + 1 is always true (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((x & m), m + 1) != 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsTrueForNEmx(int x, int m) {
// [BoolTest::ne] 1b) m & x u m + 1 is always true (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((m & x), m + 1) != 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsTrueForLExm(int x, int m) {
// [BoolTest::le] 1b) x & m u m + 1 is always true (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((x & m), m + 1) <= 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsTrueForLEmx(int x, int m) {
// [BoolTest::le] 1b) m & x u m + 1 is always true (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((m & x), m + 1) <= 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsFalseForGExm(int x, int m) {
// [BoolTest::ge] 1b) x & m u m + 1 is always false (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((x & m), m + 1) >= 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsFalseForGEmx(int x, int m) {
// [BoolTest::ge] 1b) m & x u m + 1 is always false (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((m & x), m + 1) >= 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsTrueForLTxm(int x, int m) {
// [BoolTest::lt] 1b) x & m <u m + 1 is always true (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((x & m), m + 1) < 0;
}
@ -78,11 +270,34 @@ public class TestBoolNodeGVN {
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testShouldReplaceCpmUCase4(int x, int m) {
public static boolean testCase1bOptimizeAsTrueForLTmx(int x, int m) {
// [BoolTest::lt] 1b) m & x <u m + 1 is always true (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((m & x), m + 1) < 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsFalseForGTxm(int x, int m) {
// [BoolTest::gt] 1b) x & m >u m + 1 is always false (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((x & m), m + 1) > 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.RANDOM_EACH})
@IR(failOn = IRNode.CMP_U,
phase = CompilePhase.AFTER_PARSING,
applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
public static boolean testCase1bOptimizeAsFalseForGTmx(int x, int m) {
// [BoolTest::gt] 1b) m & x >u m + 1 is always false (if m -1)
m = Math.max(0, m);
return Integer.compareUnsigned((m & x), m + 1) > 0;
}
@Test
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
@IR(counts = {IRNode.CMP_U, "1"}, // m could be -1 and thus optimization cannot be applied
@ -145,11 +360,23 @@ public class TestBoolNodeGVN {
for (int x : values) {
for (int m : values) {
if (!testShouldReplaceCpmUCase1(x, m) ||
!testShouldReplaceCpmUCase2(x, m) ||
!testShouldReplaceCpmUCase3(x, m) ||
!testShouldReplaceCpmUCase4(x, m)) {
throw new RuntimeException("Bad result for x = " + x + " and m = " + m + ", expected always true");
if (!testCase1aOptimizeAsTrueForLExm(x, m) ||
!testCase1aOptimizeAsTrueForLEmx(x, m) ||
testCase1aOptimizeAsFalseForGTxm(x, m) ||
testCase1aOptimizeAsFalseForGTmx(x, m) ||
testCase1bOptimizeAsFalseForEQxm(x, m) ||
testCase1bOptimizeAsFalseForEQmx(x, m) ||
!testCase1bOptimizeAsTrueForNExm(x, m) ||
!testCase1bOptimizeAsTrueForNEmx(x, m) ||
!testCase1bOptimizeAsTrueForLExm(x, m) ||
!testCase1bOptimizeAsTrueForLEmx(x, m) ||
testCase1bOptimizeAsFalseForGExm(x, m) ||
testCase1bOptimizeAsFalseForGEmx(x, m) ||
!testCase1bOptimizeAsTrueForLTxm(x, m) ||
!testCase1bOptimizeAsTrueForLTmx(x, m) ||
testCase1bOptimizeAsFalseForGTxm(x, m) ||
testCase1bOptimizeAsFalseForGTmx(x, m)) {
throw new RuntimeException("Bad result for x = " + x + " and m = " + m);
}
}
}