JIT: retype some return expressions
authorAndy Ayers <andya@microsoft.com>
Sat, 17 Nov 2018 18:26:25 +0000 (10:26 -0800)
committerAndy Ayers <andya@microsoft.com>
Tue, 27 Nov 2018 18:47:41 +0000 (10:47 -0800)
The jit is fairly tolerant of byref/native int mismatches for inline arguments
and return values. And some of the new unsafe helpers do this kind of
reinterpretation across call boundaries as well. This sometimes leads the jit
to lose track of byrefs.

A general fix for this is likely somewhat involved. For now we simply detect if
we're about to lose track of a byref when substituting a particular kind of
return expression, and retype the expression to a byref.

Fixes #21051.

src/System.Private.CoreLib/shared/System/Globalization/CharUnicodeInfo.cs
src/jit/flowgraph.cpp

index 354785b..575683b 100644 (file)
@@ -146,7 +146,6 @@ namespace System.Globalization
         // Note that for ch in the range D800-DFFF we just treat it as any other non-numeric character
         //
         // Workaround for https://github.com/dotnet/coreclr/issues/21051
-        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]
         internal static double InternalGetNumericValue(int ch)
         {
             Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
@@ -297,7 +296,6 @@ namespace System.Globalization
         ////////////////////////////////////////////////////////////////////////
 
         // Workaround for https://github.com/dotnet/coreclr/issues/21051
-        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]
         internal static byte InternalGetCategoryValue(int ch, int offset)
         {
             Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
index b2846ed..acad016 100644 (file)
@@ -22192,7 +22192,8 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(GenTr
 
         // Skip through chains of GT_RET_EXPRs (say from nested inlines)
         // to the actual tree to use.
-        GenTree* inlineCandidate = tree->gtRetExprVal();
+        GenTree*  inlineCandidate = tree->gtRetExprVal();
+        var_types retType         = tree->TypeGet();
 
 #ifdef DEBUG
         if (comp->verbose)
@@ -22217,6 +22218,17 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(GenTr
             printf("\n");
         }
 #endif // DEBUG
+
+        var_types newType = tree->TypeGet();
+
+        // If we end up swapping in an RVA static we may need to retype it here,
+        // if we've reinterpreted it as a byref.
+        if ((retType != newType) && (retType == TYP_BYREF) && (tree->OperGet() == GT_IND))
+        {
+            assert(newType == TYP_I_IMPL);
+            JITDUMP("Updating type of the return GT_IND expression to TYP_BYREF\n");
+            tree->gtType = TYP_BYREF;
+        }
     }
 
     // If an inline was rejected and the call returns a struct, we may