Fix for a rotation transformation bug.
authorEugene Rozenfeld <erozen@microsoft.com>
Mon, 16 Nov 2015 23:47:59 +0000 (15:47 -0800)
committerEugene Rozenfeld <erozen@microsoft.com>
Mon, 16 Nov 2015 23:47:59 +0000 (15:47 -0800)
rotatedValueBitSize should be calculated from genActualType(rotatedValue->gtType) instead of rotatedValue->gtType.
I added a test that was failing with an assert because of this bug: rol32ushort.

src/jit/morph.cpp
tests/src/JIT/CodeGenBringUpTests/Rotate.cs

index 2d6d620..539f79f 100644 (file)
@@ -12072,7 +12072,8 @@ GenTreePtr Compiler::fgRecognizeAndMorphBitwiseRotation(GenTreePtr tree)
     if (GenTree::Compare(leftShiftTree->gtGetOp1(), rightShiftTree->gtGetOp1()))
     {
         GenTreePtr rotatedValue = leftShiftTree->gtGetOp1();
-        ssize_t rotatedValueBitSize = genTypeSize(rotatedValue->gtType) * 8;
+        var_types rotatedValueActualType = genActualType(rotatedValue->gtType);
+        ssize_t rotatedValueBitSize = genTypeSize(rotatedValueActualType) * 8;
         noway_assert((rotatedValueBitSize == 32) || (rotatedValueBitSize == 64));
         GenTreePtr leftShiftIndex = leftShiftTree->gtGetOp2();
         GenTreePtr rightShiftIndex = rightShiftTree->gtGetOp2();
@@ -12205,7 +12206,7 @@ GenTreePtr Compiler::fgRecognizeAndMorphBitwiseRotation(GenTreePtr tree)
             }
             else
             {
-                tree = gtNewOperNode(rotateOp, genActualType(rotatedValue->gtType), rotatedValue, rotateIndex);
+                tree = gtNewOperNode(rotateOp, rotatedValueActualType, rotatedValue, rotateIndex);
                 noway_assert(inputTreeEffects == (tree->gtFlags & GTF_ALL_EFFECT));
             }
 
index 936718c..f5c2c04 100644 (file)
@@ -14,6 +14,8 @@ public class Test
 
     volatile uint volatile_field;
 
+    ushort usfield;
+
     [MethodImpl(MethodImplOptions.NoInlining)]
     static uint rol32(uint value, int amount)
     {
@@ -166,10 +168,17 @@ public class Test
         return (value >> 10) | (value << 5);
     }
 
-    Test(ulong i, uint j)
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    uint rol32ushort(int amount)
+    {
+        return ((uint)usfield << amount) | ((uint)usfield >> (32 - amount));
+    }
+
+    Test(ulong i, uint j, ushort k)
     {
         field = i;
         volatile_field = j;
+        usfield = k;
     }
 
     public static int Main()
@@ -291,6 +300,11 @@ public class Test
             return Fail;
         }
 
+        if (test.rol32ushort(25) != 0x68000024)
+        {
+            return Fail;
+        }
+
         return Pass;
     }
 }