United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6910484 incorrect integer optimization (loosing and op-r in a given example)
JDK-6910484 : incorrect integer optimization (loosing and op-r in a given example)

Details
Type:
Bug
Submit Date:
2009-12-15
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
linux,generic
Sub-Component:
compiler
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
hs17,6u14
Fixed Versions:
hs17 (b07)

Related Reports
Backport:
Backport:
Duplicate:
Relates:

Sub Tasks

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
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;
        }
      }
    }
...
}
                                     
2009-12-15
EVALUATION

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

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/174ade00803b
                                     
2010-01-08
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.
                                     
2010-01-08



Hardware and Software, Engineered to Work Together