[RyuJit/ARM32] Fix wrong behavior of UINT->CHAR casting
authorsjsujinkim <sjsujin.kim@samsung.com>
Wed, 31 May 2017 09:39:08 +0000 (18:39 +0900)
committersjsujinkim <sjsujin.kim@samsung.com>
Wed, 31 May 2017 10:17:21 +0000 (19:17 +0900)
'JIT\Regression\CLR-x86-JIT\V1-M11-Beta1\b44879\b44879\b44879.cmd'

When UINT cast to CHAR, MOV instruction had been emitted with R0 to R0 for extending the type.
It is wrong behavior to cast.

In case of INT to BOOL casting, that use uxtb instruction to extend BOOL type.

So this PR would use a uxth instruction too insted of wrong mov instruction.

@dotnet/arm64-contrib @dotnet/arm32-contrib Please make sure this code is okay.

Commit migrated from https://github.com/dotnet/coreclr/commit/1c3f1c64df2fcdac4ce609e55c6809e590790a08

src/coreclr/src/jit/codegenarmarch.cpp

index e8391d1..15fc9aa 100644 (file)
@@ -2220,46 +2220,48 @@ void CodeGen::genIntToIntCast(GenTreePtr treeNode)
         {
             var_types extendType = TYP_UNKNOWN;
 
-            // If we need to treat a signed type as unsigned
-            if ((treeNode->gtFlags & GTF_UNSIGNED) != 0)
+            if (genTypeSize(srcType) < genTypeSize(dstType))
             {
-                extendType  = genUnsignedType(srcType);
-                movSize     = emitTypeSize(extendType);
-                movRequired = true;
-            }
-            else
-            {
-                if (genTypeSize(srcType) < genTypeSize(dstType))
+                // If we need to treat a signed type as unsigned
+                if ((treeNode->gtFlags & GTF_UNSIGNED) != 0)
                 {
+                    extendType = genUnsignedType(srcType);
+                }
+                else
                     extendType = srcType;
 #ifdef _TARGET_ARM_
-                    movSize = emitTypeSize(srcType);
+                movSize = emitTypeSize(extendType);
 #endif // _TARGET_ARM_
-                    if (srcType == TYP_UINT)
-                    {
+                if (extendType == TYP_UINT)
+                {
 #ifdef _TARGET_ARM64_
-                        // If we are casting from a smaller type to
-                        // a larger type, then we need to make sure the
-                        // higher 4 bytes are zero to gaurentee the correct value.
-                        // Therefore using a mov with EA_4BYTE in place of EA_8BYTE
-                        // will zero the upper bits
-                        movSize = EA_4BYTE;
+                    // If we are casting from a smaller type to
+                    // a larger type, then we need to make sure the
+                    // higher 4 bytes are zero to gaurentee the correct value.
+                    // Therefore using a mov with EA_4BYTE in place of EA_8BYTE
+                    // will zero the upper bits
+                    movSize = EA_4BYTE;
 #endif // _TARGET_ARM64_
-                        movRequired = true;
-                    }
+                    movRequired = true;
                 }
-                else // (genTypeSize(srcType) > genTypeSize(dstType))
+            }
+            else // (genTypeSize(srcType) > genTypeSize(dstType))
+            {
+                // If we need to treat a signed type as unsigned
+                if ((treeNode->gtFlags & GTF_UNSIGNED) != 0)
                 {
+                    extendType = genUnsignedType(dstType);
+                }
+                else
                     extendType = dstType;
 #if defined(_TARGET_ARM_)
-                    movSize = emitTypeSize(dstType);
+                movSize = emitTypeSize(extendType);
 #elif defined(_TARGET_ARM64_)
-                    if (dstType == TYP_INT)
-                    {
-                        movSize = EA_8BYTE; // a sxtw instruction requires EA_8BYTE
-                    }
-#endif // _TARGET_*
+                if (extendType == TYP_INT)
+                {
+                    movSize = EA_8BYTE; // a sxtw instruction requires EA_8BYTE
                 }
+#endif // _TARGET_*
             }
 
             ins = ins_Move_Extend(extendType, castOp->InReg());