openj9
openj9 copied to clipboard
Inconsistent Output from OpenJ9 Java 8 When Running Test.java Compared to HotSpot Results
Java -version output
openjdk version "1.8.0_402-internal"
OpenJDK Runtime Environment (build 1.8.0_402-internal_2024_01_05_11_05-b00)
Eclipse OpenJ9 VM (build master-1b60ab828, JRE 1.8.0 Linux amd64-64-Bit Compressed References 20240105_000000 (JIT enabled, AOT enabled)
OpenJ9 - 1b60ab828
OMR - 3a4787401
JCL - b058bf977e based on jdk8u402-b05)
javac 1.8.0_402-internal
Summary of problem
The following Test.java makes OpenJ9 (with above version) to produce different result from HotSpot (jdk11, jdk17 and jdk 21). This should be a JIT compiler's bug since -Xint gives the same result as HotSpot.
class Test {
static int N = 400;
static long instanceCount;
static float a = 23.504F;
public static volatile short sFld;
static float[][] fArrFld = new float[N][N];
static long vMeth_check_sum = 0;
void vMeth1() {
int i5;
double d = i5 = 1;
while (++i5 < 132) {
a += d;
fArrFld[i5][i5] = sFld = 8;
d -= instanceCount;
for (int i6 = 1; i6 < 12; ++i6) {
instanceCount = (long) a;
}
}
}
void mainTest(String[] strArr1) {
for (int i = 0; i < 10; ++i) {
int i2 = -12171;
for (int i1 = 9; 217 > i1; ++i1) {
for (int i3 = 0; i3 < 20000; ++i3) ;
vMeth1();
i2 = (int) instanceCount;
}
vMeth_check_sum += i2;
}
System.out.println(vMeth_check_sum);
}
public static void main(String[] strArr) {
Test _instance = new Test();
_instance.mainTest(strArr);
}
}
An error occurs roughly once in every three attempts. Results of OpenJ9 (Java 8) is 0; sometimes the output result can also be 1.
$ java Test
0
The correct result (also the output of HotSpot) should be:
$ java Test
-10
Additionally, I have discovered that this bug is more likely to be triggered when setting optLevel to hot, veryhot, or scorching, and it does not occur when setting -Xjit:exclude={Test.mainTest(*)*}.
$ java -Xjit:optLevel=hot Test
0
$ java -Xjit:optLevel=veryhot Test
0
$ java -Xjit:optLevel=scorching Test
-1
$ java -Xjit:exclude={Test.mainTest(*)*} Test
-10
@hzongaro fyi
@jmesyou, may I ask you to take a look at this one? It might be a problem in Partial Redundancy Elimination.
$ java -Xjit:limit={Test.mainTest*},optLevel=hot,disablePRE Test
-10
$ java -Xjit:limit={Test.mainTest*},optLevel=hot,disablePRE Test
-10
$ java -Xjit:limit={Test.mainTest*},optLevel=hot,disablePRE Test
-10
$ java -Xjit:limit={Test.mainTest*},optLevel=hot Test
0
FYI - I was able to reproduce this failure with a 0.28 release, so it's not a regression.
Disabling GlobalVP gives the correct result, too.
$ java -Xjit:limit=mainTest,optLevel=hot,disableAsyncCompilation Test
0
$ java -Xjit:limit=mainTest,optLevel=hot,disableAsyncCompilation,disableGlobalVP Test
-10
Same with LoopCanonicalization
⬢ [Docker] ❯ java -Xjit:limit=mainTest,optLevel=hot,disableAsyncCompilation,disableLoopCanonicalization Test
-10
⬢ [Docker] ❯ java -Xjit:limit=mainTest,optLevel=hot,disableAsyncCompilation Test
0
Disabling GlobalVP gives the correct result, too Same with LoopCanonicalization
Thanks! I had arrived at Partial Redundancy Elimination using a binary search with lastOptIndex, so it might be a good place to begin, even if the actual bug turns out to be something introduced by an earlier optimization.
Hello, I recently received a new test case. It is similar to the original test case in this issue, in that it can produce the correct results when the -Xjit:optLevel=hot,disablePRE option is enabled. I hope this test case can be helpful to you.
Additionally, how should I determine whether the reasons for the erroneous results in these two test cases are the same?
class Test {
int a = 400;
int b;
float m;
volatile short e;
float[] f = new float[a];
void g(int h) {
for (int l = 1; l < 132; ++l) {
m += 109.56382;
f[l] = h;
e = 8;
h -= b;
for (int n = 1; n < 2; ++n)
b = (int) m;
}
}
void z() {
for (int p = 9; 217 > p; ++p) {
b = 0;
for (int q = 0; q < 20000; ++q);
g(p);
}
}
void u(String[] v) {
for (int i = 0; i < a; i++)
z();
System.out.println(f[131]);
}
public static void main(String[] x) {
Test y = new Test();
y.u(x);
}
}
$ /tools/jdk1.8.0_371/bin/java Test
1.0506584E7
$ /tools/jdk-11.0.15/bin/java Test
1.0506584E7
$ /tools/jdk-17.0.10/bin/java Test
1.0506584E7
$ /tools/jdk-21.0.1/bin/java Test
1.0506584E7
$ /openj9-openjdk-jdk8/.../bin/java Test
1.1579864E7
$ /openj9-openjdk-jdk8/.../bin/java -Xjit:limit=z,optLevel=veryhot Test
1.1579864E7
$ /openj9-openjdk-jdk8/.../bin/java -Xjit:limit=z,optLevel=veryhot,disablePRE Test
1.0506584E7
how should I determine whether the reasons for the erroneous results in these two test cases are the same?
@Qeryu, the Isolating a Failure section of the Problem Determination guide describes at a high-level the process JIT developers will often go through in first determining which method might be affected and which optimization might be responsible. It's possible for a user to perform the same process, without having in depth knowledge of the JIT compiler's optimizations and code generation.
But actually determining whether the reasons for the failure are the same can be more difficult, and usually requires one to examine the details of the internal representation of methods, the implementation of optimizations, perhaps taking into account interactions with the JVM. Given that, I think it's safest either to open a new issue, or report the variant in a comment as you've done here. When a developer comes up with a fix for the original problem, they can verify whether the variant is the same problem.
I understand now. Thank you for your explanation. @hzongaro
We haven't investigated this problem enough to get a fix in for the 0.44.0 release. Moving to 0.45.
@hzongaro I haven't been able to reproduce this bug on HEAD, ~so far it looks like the test produces the correct result for me~
⬢ [Docker] > java -Xjit:optLevel=hot TestIssue18765
-10
I was able to reproduce it after roughly 10 attempts
In this environment, bugs can still be triggered fairly reliably.
$ openj9-openjdk-jdk8/.../java -version
openjdk version "1.8.0_412-internal"
OpenJDK Runtime Environment (build 1.8.0_412-internal-user_2024_03_06_10_45-b00)
Eclipse OpenJ9 VM (build master-8c1d42dad, JRE 1.8.0 Linux amd64-64-Bit Compressed References 20240306_000000 (JIT enabled, AOT enabled)
OpenJ9 - 8c1d42dad
OMR - 8bea58e95
JCL - 16aa7c2499 based on jdk8u412-b05)
$ openj9-openjdk-jdk8/.../java Test
0
@Qeryu, you had previously reported some similar problems - #18777 and #19218 - that appeared as problems related to or exposed by PRE that @a7ehuo has fixed. May I ask you to see whether you're still able to reproduce this failure?
I tried reproducing the problem using the test provided in the initial comment of this issue and the second test provided in a subsequent comment. I was able to reproduce incorrect results for both with a JDK 17 build of the 0.44.0 release, but not with a recent build of the 0.46.0 release of OpenJ9. I'm going to close this as a duplicate of those problems I mentioned earlier.
@Qeryu, if you are still able to reproduce this problem, please reopen the issue.