Inconsistent floating-point results between -Xcomp and -Xint involving Math.min/max and Float.NaN

XMLWordPrintable

    • Type: Bug
    • Resolution: Duplicate
    • Priority: P3
    • None
    • Affects Version/s: 27
    • Component/s: hotspot

      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

            Assignee:
            Unassigned
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: