-
Bug
-
Resolution: Fixed
-
P3
-
1.4.2_16
-
b10
-
itanium
-
linux_redhat_3.0, linux_redhat_4.0
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2168777 | 1.4.2_19 | Abhijit Saha | P3 | Resolved | Fixed | b01 |
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 %}
......
-------------
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 %}
......
- backported by
-
JDK-2168777 [1.4.2] : 2 possible problems in shift operation in compiler2 (RHEL, IA64)
-
- Resolved
-
- duplicates
-
JDK-6660833 [1.4.2] : 2 incorrect right shift operation in compiler2 in 1.4.2(Itanium2)
-
- Closed
-