Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6992759

Bad code generated for integer <= comparison, fails for Integer.MAX_VALUE

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 6
    • hotspot
    • x86
    • linux

      FULL PRODUCT VERSION :
      $ java -version
      java version "1.5.0_06"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
      Java HotSpot(TM) Server VM (build 1.5.0_06-b05, mixed mode)

      On Solaris 10 we used 1.5.0_05-b05.

      It also failed on a 6.0 release we tried.

      FULL OS VERSION :
      $ uname -a
      Linux localhost.localdomain 2.4.21-4.ELsmp #1 SMP Fri Oct 3 17:52:56 EDT 2003 i686 i686 i386 GNU/Linux


      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Also fails on all other platforms we tried:
        - Solaris 10
        - Windows XP

      A DESCRIPTION OF THE PROBLEM :
      The original problem encountered was that the following expression, when Y is Integer.MAX_VALUE and list.size() is four, was evaluating to true when X is zero but to false when X is one:

               ((X <= Y) && (X < list.size()))

      Of course, this should be true for all values of X between zero and three when Y is Integer.MAX_VALUE. (Perhaps a Hotspot optimization based on the fact that (X <= Integer.MAX_VALUE) is always true is misbehaving.)

      Although it was clearly failing in my application I was unable to reproduce the particular case above in a standalone test, but I was able to produce a (hopefully) related problem. After a number of iterations, giving Hotspot time to compile the code, the following expression is always evaluated to true:

             ((X <= Y) && (X < 10))

      Where:
            X varies between 0 and Integer.MAX_VALUE
            Y is Integer.MAX_VALUE

      The expression should be only true when X is less than 10. This is the case when -client is used, but after compilation with -server the expression is always true. The included test demonstrates this problem.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the test included with the java -server option. It will fail. Run it with -client and it won't fail.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Expected result:

      No failure

      Actual result:

      Exception in thread "main" java.lang.RuntimeException: Failed test iteration=9029 max=2147483647 counted=2147483647 expected=10
              at MaxValueBug.doTest(MaxValueBug.java:27)
              at MaxValueBug.main(MaxValueBug.java:14)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      $ javac MaxValueBug.java && java -server -cp . MaxValueBug
      Exception in thread "main" java.lang.RuntimeException: Failed test iteration=9029 max=2147483647 counted=2147483647 expected=10
              at MaxValueBug.doTest(MaxValueBug.java:27)
              at MaxValueBug.main(MaxValueBug.java:14)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class MaxValueBug {

          static final int N_TESTS = 1000000000;

          public static void main(String[] args) throws Exception {

              /*
               * If MAX_VALUE is changed to MAX_VALUE - 1 below, the test passes
               * because (apparently) bad code is only generated when comparing
               * <= MAX_VALUE in the doTest method.
               */
              MaxValueBug test = new MaxValueBug();
              for (int i = 0; i < N_TESTS; i += 1) {
                  test.doTest(10, Integer.MAX_VALUE, i);
                  //test.doTest(10, Integer.MAX_VALUE - 1, i);
              }
              System.out.println("No failure");
          }

          void doTest(int expected, int max, int i) {
              int counted;
              for (counted = 0;
                   (counted <= max) && (counted < expected);
                   counted += 1) {
              }
              if (counted != expected) {
                  throw new RuntimeException("Failed test iteration=" + i +
                                             " max=" + max +
                                             " counted=" + counted +
                                             " expected=" + expected);
              }
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      The workaround, for the specific case we encountered, is to not use Integer.MAX_VALUE as a maximum value but rather (Integer.MAX_VALUE - 1). This happens to be acceptable for this one case. We are, of course, very concerned about this bug in other contexts.

            kvn Vladimir Kozlov
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: