ADDITIONAL SYSTEM INFORMATION :
- Operating system: Linux
- Compiler/toolchain: GCC 9.5
- Source commit: 76b626867f7c436e493566c2cc5d6ac847420894 (tag: 1.8.0_492-internal, branch: master)
- Build type: fastdebug (also happens in release version)
- Coverage: enabled (built with --enable-coverage)
- Build environment: Linux, compiled from source with GCC 9.5
- Also happens in 1.8.0_472, released version
A DESCRIPTION OF THE PROBLEM :
I have encountered a discrepancy in execution results when running a specific Java program involving floating-point arithmetic. The code relies on `Math.min`, `Math.max`, and arithmetic operations involving `Float.NaN` and `-0.0f`.
When running with `-Xint` (interpreted mode) or `-Xmixed` (mixed mode), the program outputs `false`. However, when running with `-Xcomp` (forcing JIT compilation), the program outputs `true`.
Since the interpreted mode usually adheres strictly to the Java semantics, the `-Xcomp` result appears to be incorrect, suggesting a JIT optimization issue (potentially related to NaN checks or constant folding in the C2 compiler).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Save the provided source code to a file named `Test.java`.
2. Compile the source code:
`javac Test.java`
3. Run the application using the interpreter (reference result):
`java -Xint -Xbatch Test`
4. Run the application forcing compilation:
`java -Xcomp -Xbatch Test`
---------- BEGIN SOURCE ----------
public class Test {
public void mainTest(String[] strArr1, int intTestVar) {
boolean boool2 = (intTestVar % 2 == 0);
float fff5 = intTestVar + 0.5f;
float fff4 = intTestVar + 0.5f;
float fff1 = intTestVar + 0.5f;
float fff9 = intTestVar + 0.5f;
float fff8 = intTestVar + 0.5f;
float fff6 = intTestVar + 0.5f;
float ccff4 = -0.0f;
boool2 = (
Float.floatToRawIntBits(
18.366003f / 31.415833f + 0.33937734f / Math.max(fff1, 59.811413f) +
Math.min(Float.NaN, fff5) + fff6 + ccff4 % ccff4
)
==
Float.floatToRawIntBits(
96.412651f * Math.max(fff5, Float.NaN) + Math.min(49.977535f, fff4) +
Math.max(fff5, Float.NaN) + Math.min(39.18654f, fff5) / Math.max(fff8, 1) -
Math.max(fff9, Float.NaN) + Math.min(Float.NaN, fff8) *
Math.max(fff1, 54.43523f) + Math.min(Float.NaN, fff4)
)
);
booleanTestVar = boool2;
}
public static void main(String[] strArr) {
booleanTestVar = false;
Test _instance = new Test();
_instance.mainTest(strArr, 10);
System.out.println("booleanTestVar = " + String.valueOf(booleanTestVar));
}
public static boolean booleanTestVar;
}
---------- END SOURCE ----------
FREQUENCY :
ALWAYS
- Operating system: Linux
- Compiler/toolchain: GCC 9.5
- Source commit: 76b626867f7c436e493566c2cc5d6ac847420894 (tag: 1.8.0_492-internal, branch: master)
- Build type: fastdebug (also happens in release version)
- Coverage: enabled (built with --enable-coverage)
- Build environment: Linux, compiled from source with GCC 9.5
- Also happens in 1.8.0_472, released version
A DESCRIPTION OF THE PROBLEM :
I have encountered a discrepancy in execution results when running a specific Java program involving floating-point arithmetic. The code relies on `Math.min`, `Math.max`, and arithmetic operations involving `Float.NaN` and `-0.0f`.
When running with `-Xint` (interpreted mode) or `-Xmixed` (mixed mode), the program outputs `false`. However, when running with `-Xcomp` (forcing JIT compilation), the program outputs `true`.
Since the interpreted mode usually adheres strictly to the Java semantics, the `-Xcomp` result appears to be incorrect, suggesting a JIT optimization issue (potentially related to NaN checks or constant folding in the C2 compiler).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Save the provided source code to a file named `Test.java`.
2. Compile the source code:
`javac Test.java`
3. Run the application using the interpreter (reference result):
`java -Xint -Xbatch Test`
4. Run the application forcing compilation:
`java -Xcomp -Xbatch Test`
---------- BEGIN SOURCE ----------
public class Test {
public void mainTest(String[] strArr1, int intTestVar) {
boolean boool2 = (intTestVar % 2 == 0);
float fff5 = intTestVar + 0.5f;
float fff4 = intTestVar + 0.5f;
float fff1 = intTestVar + 0.5f;
float fff9 = intTestVar + 0.5f;
float fff8 = intTestVar + 0.5f;
float fff6 = intTestVar + 0.5f;
float ccff4 = -0.0f;
boool2 = (
Float.floatToRawIntBits(
18.366003f / 31.415833f + 0.33937734f / Math.max(fff1, 59.811413f) +
Math.min(Float.NaN, fff5) + fff6 + ccff4 % ccff4
)
==
Float.floatToRawIntBits(
96.412651f * Math.max(fff5, Float.NaN) + Math.min(49.977535f, fff4) +
Math.max(fff5, Float.NaN) + Math.min(39.18654f, fff5) / Math.max(fff8, 1) -
Math.max(fff9, Float.NaN) + Math.min(Float.NaN, fff8) *
Math.max(fff1, 54.43523f) + Math.min(Float.NaN, fff4)
)
);
booleanTestVar = boool2;
}
public static void main(String[] strArr) {
booleanTestVar = false;
Test _instance = new Test();
_instance.mainTest(strArr, 10);
System.out.println("booleanTestVar = " + String.valueOf(booleanTestVar));
}
public static boolean booleanTestVar;
}
---------- END SOURCE ----------
FREQUENCY :
ALWAYS
- duplicates
-
JDK-8375735 C1 compilation produces different NaN values than the interpreter
-
- Closed
-