diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 396769e2eb53e5..f458c119c133c7 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1179,6 +1179,11 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info) return false; } + TypeDesc owningType = impl.OwningType; + + // RyuJIT expects to get the canonical form back + impl = impl.GetCanonMethodTarget(CanonicalFormKind.Specific); + if (impl.OwningType.IsValueType) { impl = getUnboxingThunk(impl); @@ -1186,7 +1191,7 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info) info->devirtualizedMethod = ObjectToHandle(impl); info->requiresInstMethodTableArg = false; - info->exactContext = contextFromType(impl.OwningType); + info->exactContext = contextFromType(owningType); return true; } diff --git a/src/tests/JIT/opt/Devirtualization/generic_noinline.cs b/src/tests/JIT/opt/Devirtualization/generic_noinline.cs new file mode 100644 index 00000000000000..541478c8312385 --- /dev/null +++ b/src/tests/JIT/opt/Devirtualization/generic_noinline.cs @@ -0,0 +1,30 @@ +// 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; + +class Program +{ + static int Main() + { + MyStruct s = default; + + // RyuJIT can devirtualize this, but NoInlining prevents the inline + // This checks that we properly pass the instantiation context to the shared generic method. + return ((IFoo)s).GetTheType() == typeof(Atom) ? 100 : -1; + } +} + +interface IFoo +{ + Type GetTheType(); +} + +struct MyStruct : IFoo +{ + [MethodImpl(MethodImplOptions.NoInlining)] + Type IFoo.GetTheType() => typeof(T); +} + +class Atom { } diff --git a/src/tests/JIT/opt/Devirtualization/generic_noinline.csproj b/src/tests/JIT/opt/Devirtualization/generic_noinline.csproj new file mode 100644 index 00000000000000..80b62656678a80 --- /dev/null +++ b/src/tests/JIT/opt/Devirtualization/generic_noinline.csproj @@ -0,0 +1,13 @@ + + + Exe + 0 + + + PdbOnly + True + + + + +