From 1353404095e1ab886ff3c028d75218081d428e36 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Sat, 17 Nov 2018 10:26:25 -0800 Subject: [PATCH] JIT: retype some return expressions 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 dotnet/coreclr#21051. Commit migrated from https://github.com/dotnet/coreclr/commit/3bc2f7a800498135a1c1575b01d0f5d1113d9acd --- src/coreclr/src/jit/flowgraph.cpp | 14 +++++++++++++- .../src/System/Globalization/CharUnicodeInfo.cs | 2 -- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index b2846ed..acad016 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -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 diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs index 354785b..575683b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs @@ -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."); -- 2.7.4