United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6956668 misbehavior of XOR operator (^) with int
6956668 : misbehavior of XOR operator (^) with int

Details
Type:
Bug
Submit Date:
2010-05-28
Status:
Resolved
Updated Date:
2013-04-24
Project Name:
JDK
Resolved Date:
2011-06-04
Component:
hotspot
OS:
windows_7
Sub-Component:
compiler
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u10
Fixed Versions:
hs21

Related Reports
Backport:
Backport:
Backport:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b89)
Java HotSpot(TM) 64-Bit Server VM (build 18.0-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows 7 64bit

EXTRA RELEVANT SYSTEM CONFIGURATION :
occurs on java 6 & 7 64bit version. no issue in 32 bit version

A DESCRIPTION OF THE PROBLEM :
the following rudimentary program fails under 64bit VM (around 2500th iterations in the loop). works fine in 32bit VM. this has been verified w/ multiple machines.

to make it work under 64bit VM, the following line,

            if ((testValue ^= 0x1) != 0)

needs to be changed to:

            if ((testValue ^= 0x1L) != 0)


public class TEST
{
   public static int bitTest()
   {
      int result = 0;

      int testValue = 73;
      int bitCount = Integer.bitCount(testValue);

      if (testValue != 0)
      {
         int gap = Long.numberOfTrailingZeros(testValue);
         testValue >>>= gap;

         while (testValue != 0)
         {
            result++;

            if ((testValue ^= 0x1) != 0)
            {
               gap = Long.numberOfTrailingZeros(testValue);
               testValue >>>= gap;
            }
         }
      }

      if (bitCount != result)
      {
         System.out.println("ERROR!!");
         System.exit(0);
      }

      return (result);
   }

   public static void main(String[] args)
   {
      for (int i = 0; i < 100000; i++)
      {
         int ct = bitTest();
         System.out.println(">>> " + i + " ... " + ct);
      }
   }
}


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the following program in 64VM.  the program terminates w/ ERROR.

public class TEST
{
   public static int bitTest()
   {
      int result = 0;

      int testValue = 73;
      int bitCount = Integer.bitCount(testValue);

      if (testValue != 0)
      {
         int gap = Long.numberOfTrailingZeros(testValue);
         testValue >>>= gap;

         while (testValue != 0)
         {
            result++;

            if ((testValue ^= 0x1) != 0)
            {
               gap = Long.numberOfTrailingZeros(testValue);
               testValue >>>= gap;
            }
         }
      }

      if (bitCount != result)
      {
         System.out.println("ERROR!!");
         System.exit(0);
      }

      return (result);
   }


   public static void main(String[] args)
   {
      for (int i = 0; i < 100000; i++)
      {
         int ct = bitTest();
         System.out.println(">>> " + i + " ... " + ct);
      }
   }
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
it should complete 100000 iterations in the "main" w/o error...
ACTUAL -
sample output:

>>> 2537 ... 3
>>> 2538 ... 3
>>> 2539 ... 3
>>> 2540 ... 3
ERROR!!


ERROR MESSAGES/STACK TRACES THAT OCCUR :
no formal "error message" issued by VM. VM does not recognize it's abnormal behavior.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class TEST
{

   public static int bitTest()
   {
      int result = 0;

      int testValue = 73;
      int bitCount = Integer.bitCount(testValue);

      if (testValue != 0)
      {
         int gap = Long.numberOfTrailingZeros(testValue);
         testValue >>>= gap;

         while (testValue != 0)
         {
            result++;

            if ((testValue ^= 0x1) != 0)
            {
               gap = Long.numberOfTrailingZeros(testValue);
               testValue >>>= gap;
            }
         }
      }

      if (bitCount != result)
      {
         System.out.println("ERROR!!");
         System.exit(0);
      }

      return (result);
   }

   public static void main(String[] args)
   {
      for (int i = 0; i < 100000; i++)
      {
         int ct = bitTest();
         System.out.println(">>> " + i + " ... " + ct);
      }
   }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
replace the following

            if ((testValue ^= 0x1) != 0)

with

            if ((testValue ^= 0x1L) != 0)

note the "L" after "0x1"

                                    

Comments
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/rev/f88fb2fa90cf
                                     
2011-06-09
EVALUATION

http://hg.openjdk.java.net/hsx/hotspot-rt/hotspot/rev/33e2b8f1d466
                                     
2011-06-03
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/f88fb2fa90cf
                                     
2011-06-03
EVALUATION

http://hg.openjdk.java.net/hsx/hotspot-comp/hotspot/rev/33e2b8f1d466
                                     
2011-05-31
SUGGESTED FIX

Such optimization could be done only for boolean X.

src/share/vm/opto/subnode.cpp	Fri May 27 17:41:21 2011 -0700
@@ -1101,6 +1101,7 @@
   if( cmp2_type == TypeInt::ZERO &&
       cmp1_op == Op_XorI &&
       j_xor->in(1) != j_xor &&          // An xor of itself is dead
+      phase->type( j_xor->in(1) ) == TypeInt::BOOL &&
       phase->type( j_xor->in(2) ) == TypeInt::ONE &&
       (_test._test == BoolTest::eq ||
        _test._test == BoolTest::ne) ) {
                                     
2011-05-28
EVALUATION

Incorrect Ideal optimization cmp(xor(X,1),0).
                                     
2011-05-28
EVALUATION

Looks more like a Hotspot problem than a javac problem. Reassigning.
                                     
2011-05-20



Hardware and Software, Engineered to Work Together