JDK-6559156 : Server compiler generates bad code for "<= Integer.MAX_VALUE" expression
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-05-18
  • Updated: 2010-04-04
  • Resolved: 2009-08-01
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)

Also occurs in all 1.4 and 1.5 releases I have tried.

FULL OS VERSION :
Microsoft Windows XP [Version 5.1.2600]

Also occurs on all Linux platforms I've tried including:

Linux localhost.localdomain 2.4.21-4.ELsmp #1 SMP Fri Oct 3 17:52:56 EDT 2003 i6
86 i686 i386 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
When running the attached test with -Xint or -client, it works fine.  When running with -server the loop condition is not compiled correctly and after compilation occurs the test fails.  The expression in the test is specially constructed to bring out the bug, but based on trying different expressions the problem is bad code generated for (x <= Integer.MAX_VALUE).  If (x <= Integer.MAX_VALUE - 1) is used instead, the problem does not occur.

THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
  To see the bug:

$ java -server -cp . MaxValueBug
Exception in thread "main" java.lang.RuntimeException: Failed test iteration=325
3 max=2147483647 counted=2147483647 expected=10
        at MaxValueBug.doTest(MaxValueBug.java:27)
        at MaxValueBug.main(MaxValueBug.java:14)

  To see it work, use -Xint or -client:

$ java -Xint -cp . MaxValueBug
No failure

$ java -client -cp . MaxValueBug
No failure


EXPECTED VERSUS ACTUAL BEHAVIOR :
See above.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
See above.

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 :
Change the expression from (Integer.MAX_VALUE) to (Integer.MAX_VALUE - 1) as described in the test comments.  While this works, it is difficult to ensure this workaround is applied in all source code that might be impacted, and impossible to ensure it is applied in 3rd party libraries.