You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Compute precise generic context after de-virtualization #38477
using System;
using System.Runtime.CompilerServices;
class G<T>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual bool M() => typeof(T) == typeof(string);
}
class Program
{
static int Main() => new G<string>().M() ? 1 : -1;
}
Expected result (disassembly of Main method):
mov eax, 1
ret
Actual result:
G_M24375_IG01:
4883EC28 sub rsp, 40
;; bbWeight=1 PerfScore 0.25
G_M24375_IG02:
48B9F0A37960FD7F0000 mov rcx, 0x7FFD6079A3F0
E8CDF1905F call CORINFO_HELP_NEWSFAST
488BC8 mov rcx, rax
// The call is devirtualized properly, but inlining fails due to imprecise generic context
// Note that the inlining succeeds when M is changed to be non-virtual
FF15F4672700 call [G`1[__Canon][System.__Canon]:M():bool:this]
85C0 test eax, eax
750A jne SHORT G_M24375_IG05
;; bbWeight=1 PerfScore 5.75
G_M24375_IG03:
B8FFFFFFFF mov eax, -1
;; bbWeight=0.50 PerfScore 0.13
G_M24375_IG04:
4883C428 add rsp, 40
C3 ret
;; bbWeight=0.50 PerfScore 0.63
G_M24375_IG05:
B801000000 mov eax, 1
;; bbWeight=0.50 PerfScore 0.13
G_M24375_IG06:
4883C428 add rsp, 40
C3 ret
;; bbWeight=0.50 PerfScore 0.63
This is currently keying off what kind of context gets passed in, so a method context leads to an updated method context, and likewise for class contexts. I wonder if this is sufficiently general.
Activity
jkotas commentedon Jun 26, 2020
Context #38229 (comment)
AndyAyersMS commentedon Nov 2, 2020
Think we should fix this in .NET 6, as part of removing barriers to efficient generic composition.
Rattenkrieg commentedon Nov 3, 2020
I did some research while debugging #43668 I will share my findings (and maybe I will be able to craft some PoC) after I'll done with #43668
AndyAyersMS commentedon Nov 26, 2020
Is this just a matter of updating the context (and the exact context) to either the method context (like we do now) or the object class context...?
Seems to work on this simple example anyways, though the codegen creates a frame it doesn't use:
This is currently keying off what kind of context gets passed in, so a method context leads to an updated method context, and likewise for class contexts. I wonder if this is sufficiently general.
Get exact class during devirtualization
Get exact class during devirtualization (#45526)