JIT: clear up some no-op casts in the importer (#17996)
authorAndy Ayers <andya@microsoft.com>
Fri, 18 May 2018 19:58:59 +0000 (12:58 -0700)
committerGitHub <noreply@github.com>
Fri, 18 May 2018 19:58:59 +0000 (12:58 -0700)
If we see a no-op cast (say converting long to ulong) where the operand
to be cast already has the right stack type, don't generate a GT_CAST,
just use the operand.

This comes up in some cases with unsafe operations where the pointer type
is cast. Interposing a cast between an GT_IND and GT_ADDR results in poor
codegen as the jit thinks the addressed local is address taken.

src/jit/importer.cpp

index 5a952a4..262bc6e 100644 (file)
@@ -12485,21 +12485,31 @@ void Compiler::impImportBlockCode(BasicBlock* block)
 
                 type = genActualType(lclTyp);
 
-#if SMALL_TREE_NODES
-                if (callNode)
+                // If this is a no-op cast, just use op1.
+                if (!ovfl && (type == op1->TypeGet()) && (genTypeSize(type) == genTypeSize(lclTyp)))
                 {
-                    op1 = gtNewCastNodeL(type, op1, uns, lclTyp);
+                    // Nothing needs to change
                 }
+                // Work is evidently required, add cast node
                 else
-#endif // SMALL_TREE_NODES
                 {
-                    op1 = gtNewCastNode(type, op1, uns, lclTyp);
-                }
+#if SMALL_TREE_NODES
+                    if (callNode)
+                    {
+                        op1 = gtNewCastNodeL(type, op1, uns, lclTyp);
+                    }
+                    else
+#endif // SMALL_TREE_NODES
+                    {
+                        op1 = gtNewCastNode(type, op1, uns, lclTyp);
+                    }
 
-                if (ovfl)
-                {
-                    op1->gtFlags |= (GTF_OVERFLOW | GTF_EXCEPT);
+                    if (ovfl)
+                    {
+                        op1->gtFlags |= (GTF_OVERFLOW | GTF_EXCEPT);
+                    }
                 }
+
                 impPushOnStack(op1, tiRetVal);
                 break;