JDK-6910484 : incorrect integer optimization (loosing and op-r in a given example)
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: hs17,6u14
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,linux
  • CPU: generic,x86
  • Submitted: 2009-12-15
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u21Fixed 7Fixed hs17Fixed
Related Reports
Duplicate :  
Relates :  
Description
The server compiler replaces the expression "(x & -32) / 2" by "x >> 1" which is not correct. Actually it's ok to replace the division by a right shift, but the removal of the "and operation" is not correct.


1) Test program

DivIdealizeAndMinus32FollowedByDivConst2Bug.java:

public class DivIdealizeAndMinus32FollowedByDivConst2Bug {

    public static void main(String[] args) {
        long iteration = 0;
        while (true) {
            iteration++;
            int result = andMinus32FollowedByDivConst2(255);
            if (result != 112) {
                System.out.println("expected 112, but got " + result + " after iteration " + iteration);
                System.exit(-1);
            }
        }
    }

    private static int andMinus32FollowedByDivConst2(int x) {
        return (x & -32) / 2;
    }

}


2) Output of the test program on linux-x86_64

$ bin/java -showversion -classpath tests -server -XX:-UseOnStackReplacement -XX:+PrintCompilation DivIdealizeAndMinus32FollowedByDivConst2Bug

java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)

  1       DivIdealizeAndMinus32FollowedByDivConst2Bug::andMinus32FollowedByDivConst2 (7 bytes)
expected 112, but got 127 after iteration 171644

Comments
PUBLIC COMMENTS Problem: After 6667595 changes Div node ideal optimization incorrectly removes AND operation if mask is larger then shift: (x & -32)/2 incorrectly transformed to x/2 Solution: Remove AND operation only if mask is equal to shift. Add regression test.
08-01-2010

EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/174ade00803b
08-01-2010

EVALUATION Regression after 6667595. AndI node should be removed only if (-andconi) == d.
08-01-2010

SUGGESTED FIX Provided by the CU with permission to use it. hotspot/src/share/vm/opto/divnode.cpp: static Node *transform_int_divide( PhaseGVN *phase, Node *dividend, jint divisor ) { ... if (dti && dti->_lo >= 0) { // we don't need to round a positive dividend needs_rounding = false; } else if( dividend->Opcode() == Op_AndI ) { // An AND mask of sufficient size clears the low bits and // I can avoid rounding. const TypeInt *andconi_t = phase->type( dividend->in(2) )->isa_int(); if( andconi_t && andconi_t->is_con() ) { jint andconi = andconi_t->get_con(); if( andconi < 0 && is_power_of_2(-andconi) && (-andconi) >= d ) { - dividend = dividend->in(1); needs_rounding = false; } } } ... }
15-12-2009