United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6863155 Server compiler generates incorrect code (x86, long, bitshift, bitmask)
6863155 : Server compiler generates incorrect code (x86, long, bitshift, bitmask)

Details
Type:
Bug
Submit Date:
2009-07-22
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
generic,windows_xp
Sub-Component:
compiler
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
hs16

Related Reports
Backport:
Backport:
Duplicate:
Duplicate:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b65)
Java HotSpot(TM) Server VM (build 16.0-b06, mixed mode)

FULL OS VERSION :
Microsoft Windows XP [Version 5.1.2600]

EXTRA RELEVANT SYSTEM CONFIGURATION :
Intel x86 32-bit

A DESCRIPTION OF THE PROBLEM :
Code compiled with server compiler generates an incorrect result.

Ran the source code with:
-server
-XX:CompileThreshold=10
-XX:CompileOnly=jvmtest/Tester
-XX:+PrintCompilation

and got:
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
  13254907146       jvmtest.Tester::
te3254907146s
t3254907146 (51 bytes)

3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
3254907146
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150
-1040060150

The negative (incorrect) results seem to occur after the compiled code starts kicking in.  The negative results never occur with client compiler or interpreted mode.

THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run code without -server.  Observe correct result.
Then observe code with -server and a low compile threshold and observe incorrect result after code is compiled.

EXPECTED VERSUS ACTUAL BEHAVIOR :
The correct result from the code is '3254907146'.  The result after the code is compiled is calculated as '-1040060150'.
REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package jvmtest;

public class Tester
{
	private static long test(byte bytes[])
    {
		long value;
		value = bytes[3] << 24 & 0xff000000L;
        value += bytes[2] << 16 & 0xff0000;
        value += bytes[1] << 8 & 0xff00;
        value += bytes[0] & 0xff;
        return(value);
    }
	
	public static void main(String... args)
	throws Exception
	{
		for (int i = 0; i < 1000; i++)
		{
			//byte[] bytes = new byte[] {10, -15, 1, -62};
			byte[] bytes = new byte[] {0x0a, (byte)0xf1, 0x01, (byte)0xc2};
			System.out.println(test(bytes));
		}
	}
}
---------- END SOURCE ----------

                                    

Comments
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/52898b0c43e9
                                     
2009-08-10
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/52898b0c43e9
                                     
2009-07-29
EVALUATION

The bug happens with masks which would cause a sign extension to the integer value.  This is not handled properly in AndLNode::Ideal().
                                     
2009-07-27
SUGGESTED FIX

diff --git a/src/share/vm/opto/mulnode.cpp b/src/share/vm/opto/mulnode.cpp
--- a/src/share/vm/opto/mulnode.cpp
+++ b/src/share/vm/opto/mulnode.cpp
@@ -610,10 +610,11 @@
   // Are we masking a long that was converted from an int with a mask
   // that fits in 32-bits?  Commute them and use an AndINode.
   if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF00000000)) == 0) {
-    // If we are doing an UI2L conversion (i.e. the mask is
-    // 0x00000000FFFFFFFF) we cannot convert the AndL to an AndI
-    // because the AndI would be optimized away later in Identity.
-    if (mask != CONST64(0x00000000FFFFFFFF)) {
+    // Don't convert masks which would cause a sign extension of the
+    // integer value.
+    // This check includes UI2L masks (0x00000000FFFFFFFF) which would
+    // be optimized away later in Identity.
+    if ((mask & CONST64(0x0000000080000000)) == 0) {
       Node* andi = new (phase->C, 3) AndINode(in1->in(1), phase->intcon(mask));
       andi = phase->transform(andi);
       return new (phase->C, 2) ConvI2LNode(andi);
                                     
2009-07-27



Hardware and Software, Engineered to Work Together