JDK-6863155 : Server compiler generates incorrect code (x86, long, bitshift, bitmask)
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2009-07-22
  • 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
6u18Fixed 7Fixed hs16Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
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
10-08-2009

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

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);
27-07-2009

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