United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6654460 : [1.4.2] : 2 possible problems in shift operation in compiler2 (RHEL, IA64)

Details
Type:
Bug
Submit Date:
2008-01-24
Status:
Resolved
Updated Date:
2010-12-03
Project Name:
JDK
Resolved Date:
2008-08-11
Component:
hotspot
OS:
linux_redhat_4.0,linux_redhat_3.0
Sub-Component:
compiler
CPU:
itanium
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.2_16
Fixed Versions:
1.4.2_18-rev (b10)

Related Reports
Backport:
Duplicate:

Sub Tasks

Description
The customer reported  2 possible problems in shift operation in compiler2.

-------------
1. Shift distance is more than 32 in int type variable.

PROBLEM DESCRIPTION:

Left-shift operation for int type variable causes incorrect result.
This problem occurs when the operator executes more than 32 bits shift.
Also, interpreter executes correctly. After VM context moves
to compiled code execution, incorrect result appears.

CONFIGURATION :
OS : Red Hat Enterprise Linux Server release 5 (Itanium)
     Red Hat Enterprise Linux AS release 4 (Itanium)
JDK : 1.4.2_14 / 1.4.2_16 Server VM


ABOUT REPRODUCING PROGRAM:
The attached program executes 11 << 38. The result is 0(zero).
However, the following is extracted from  "15.19 Shift Operators" of  JLS.
 "If the promoted type of the left-hand operand is int, 
   only the five lowest-order bits of the right-hand operand 
   are used as the shift distance."
 ( 11 << 38 ) = ( 11 << 6 ) = 704 seems correct.

INVESTIGATION :

The customer investigated the compiled code. The compiled code which always causes 0(zero)
is generated.

0x200000000392e076 e0 02 00 18 40 00 :             and r46=r0,r0
0x200000000392e07c 00 00 04 00 11 00 :             nop.i 0x0;;
0x200000000392e080 11 00 b8 6e 90 11 : [MIB]       st4 [r55]=r46

They think the following (source) code at 3344 in ia64.ad causes the above-mentioned 
compiled code.

---- ./hotspot/src/cpu/ia64/vm/ia64.ad in 1.4.2_16 -------

  3338    enc_class emit_shlI_reg_imm6( gRegI dst, gRegI src, immI_1to64 cnt, pReg qp ) %{
  3339      MacroAssembler _masm(&cbuf);
  3340      if ( (int)$cnt$$constant < 32 )
  3341        __ depz( as_PredicateRegister($qp$$reg), as_Register($dst$$reg), as_Register($src$$reg),
  3342                 (int)$cnt$$constant, 32 - (int)$cnt$$constant );
  3343      else
  3344        __ and3( as_PredicateRegister($qp$$reg), as_Register($dst$$reg), GR0, GR0 );
  3345    %}

At the above line, when shift distance is more than 32, compiled code always causes 0.


REPRODUCING PROGRAM : 
------- ShlI.java ------
public class ShlI {
    public static       int value = 11;
    public static final int shift = 38;
    public static final int LOOPS = 10000;

    static void foo() {
        for (int i=0; i<LOOPS; i++) {
          if (i==LOOPS-1) {
              value = 11;
              System.out.print( value + " << " + shift + " = " );
          }
          value<<=shift;
          if (i==LOOPS-1) {
              System.out.println(value);
          }
        }
    }
    public static void main(String args[]) {
       for (int i=0; i<20; i++) {
         foo();
       }
    }
}
-------

COMMAND LINE :
% java ShlI
11 << 38 = 704
11 << 38 = 704
11 << 38 = 704
11 << 38 = 704
11 << 38 = 704
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0
11 << 38 = 0


2. Shift distance is more than 64 in long type variable.

PROBLEM DESCRIPTION :

The following shift function for long type variable is provided.
However, when the shift distance is more than 64 in long type variable,
"64 - (int)$cnt$$constant"  will be negative number.
This might generate incorrect compiled code.

---- ./hotspot/src/cpu/ia64/vm/ia64.ad in 1.4.2_16 -----
.....
  3347    enc_class emit_shlL_reg_imm6( gRegL dst, gRegL src, gRegI cnt, pReg qp ) %{
  3348      MacroAssembler _masm(&cbuf);
  3349      __ depz( as_PredicateRegister($qp$$reg), as_Register($dst$$reg), as_Register($src$$reg),
  3350               (int)$cnt$$constant, 64 - (int)$cnt$$constant );
  3351    %}
......

                                    

Comments
SUGGESTED FIX

JLE pasted:

As to the problem 1. Shift distance is more than 32 in int type variable,
the customer, Fujitsu provided possible fix.
On the other hand, they sent a concern whether their fix might cause side-effect or not.

-------->
As just trial, when we modify the source code as follows, we can get the correct result.

---- ./hotspot/src/cpu/ia64/vm/ia64.ad in 1.4.2_16 -------
......
3338   enc_class emit_shlI_reg_imm6( gRegI dst, gRegI src, immI_1to64 cnt, pReg qp ) %{
3339    MacroAssembler _masm(&cbuf);
3340    int cnt = (int)$cnt$$constant & 0x1f;
3341    __ depz( as_PredicateRegister($qp$$reg), as_Register($dst$$reg), as_Register($src$$reg),
3342            cnt, 32 - cnt );
3343  %}
......

However,if there is any other cource code portion which uses the result of emit_shlI_reg_imm6() 
and causes correct result for more than 32 bits shift, the above modification can not be
applied. That will affect serious side-effect to the portion.

<-------
                                     
2008-01-24
EVALUATION

Changes required in assembly macros in ia64.ad
Customer has made suggestions.
                                     
2008-03-12
EVALUATION

In addition, ###@###.### has pointed out why the customer's second point does not cause a failure for long values with >64 bit shift distances:
"
In this snippet:

 3347    enc_class emit_shlL_reg_imm6( gRegL dst, gRegL src, gRegI cnt, pReg qp ) %{
 3348      MacroAssembler _masm(&cbuf);
 3349      __ depz( as_PredicateRegister($qp$$reg), as_Register($dst$$reg), as_Register($src$$reg),
 3350               (int)$cnt$$constant, 64 - (int)$cnt$$constant );
 3351    %}

cnt is actually of type immI_1to64 which guarantees it's in range.  The emit functions don't actually pay any attention to the type declared in the emit definition.  That are actually more like macros which are substituted back into their uses and pick up the types at the uses.
"

So the fix this will address 32-bit int shifts only.
                                     
2008-06-20



Hardware and Software, Engineered to Work Together