diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index cd4edae7cc0f98..5566e42698733a 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -5244,7 +5244,23 @@ void Compiler::generatePatchpointInfo() // but would need to adjust all consumers, too. for (unsigned lclNum = 0; lclNum < info.compLocalsCount; lclNum++) { - LclVarDsc* const varDsc = lvaGetDesc(lclNum); + // If there are shadowed params, the patchpoint info should refer to the shadow copy. + // + unsigned varNum = lclNum; + + if (gsShadowVarInfo != nullptr) + { + unsigned const shadowNum = gsShadowVarInfo[lclNum].shadowCopy; + if (shadowNum != BAD_VAR_NUM) + { + assert(shadowNum < lvaCount); + assert(shadowNum >= info.compLocalsCount); + + varNum = shadowNum; + } + } + + LclVarDsc* const varDsc = lvaGetDesc(varNum); // We expect all these to have stack homes, and be FP relative assert(varDsc->lvOnFrame); @@ -5260,8 +5276,8 @@ void Compiler::generatePatchpointInfo() patchpointInfo->SetIsExposed(lclNum); } - JITDUMP("--OSR-- V%02u is at virtual offset %d%s\n", lclNum, patchpointInfo->Offset(lclNum), - patchpointInfo->IsExposed(lclNum) ? " (exposed)" : ""); + JITDUMP("--OSR-- V%02u is at virtual offset %d%s%s\n", lclNum, patchpointInfo->Offset(lclNum), + patchpointInfo->IsExposed(lclNum) ? " (exposed)" : "", (varNum != lclNum) ? " (shadowed)" : ""); } // Special offsets diff --git a/src/tests/JIT/opt/OSR/shadowparam.cs b/src/tests/JIT/opt/OSR/shadowparam.cs new file mode 100644 index 00000000000000..d43b2b809a5fe2 --- /dev/null +++ b/src/tests/JIT/opt/OSR/shadowparam.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +// F is an OSR method with parameter shadowing + +public unsafe struct ShadowParam +{ + public int a; + public fixed int data[2]; + public int b; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int F(int x, string sa, ShadowParam u, string sb, int a, int b, int y) + { + for (int i = 0; i < a + b; i++) + { + x += u.data[0]; + } + + for (int i = 0; i < a + b; i++) + { + y += u.data[1]; + } + + return x + y + u.a + u.b + sb.Length - sa.Length; + } + + public static int Main() + { + var u = new ShadowParam(); + u.data[0] = 1; + u.data[1] = -1; + u.a = 3; + u.b = -3; + + int r = F(0, "a", u, "b", 100_001, -1, 100); + Console.WriteLine($"Result is {r}"); + return r; + } +} + diff --git a/src/tests/JIT/opt/OSR/shadowparam.csproj b/src/tests/JIT/opt/OSR/shadowparam.csproj new file mode 100644 index 00000000000000..2ab2ec62439f7f --- /dev/null +++ b/src/tests/JIT/opt/OSR/shadowparam.csproj @@ -0,0 +1,11 @@ + + + Exe + + True + True + + + + +