-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strange codegen with struct forwarding implementation to another struct #11000
Comments
As far as I can tell a simple repro looks something like this: struct moo
{
public void foo() => Console.WriteLine();
}
struct boo
{
public void foo() => default(moo).foo();
}
static int Test()
{
default(moo).foo(); // replace moo with boo => worse codegen
} "Normal" codegen: G_M55887_IG01:
4883EC28 sub rsp, 40
33C0 xor rax, rax
4889442420 mov qword ptr [rsp+20H], rax
G_M55887_IG02:
488D442420 lea rax, bword ptr [rsp+20H]
C60000 mov byte ptr [rax], 0
E810FEFFFF call System.Console:WriteLine()
B82A000000 mov eax, 42
G_M55887_IG03:
4883C428 add rsp, 40
C3 ret Worse codegen: G_M55888_IG01:
4883EC38 sub rsp, 56
33C0 xor rax, rax
4889442430 mov qword ptr [rsp+30H], rax
4889442428 mov qword ptr [rsp+28H], rax
G_M55888_IG02:
488D442430 lea rax, bword ptr [rsp+30H]
C60000 mov byte ptr [rax], 0
C644242800 mov byte ptr [rsp+28H], 0
488D442428 lea rax, bword ptr [rsp+28H]
C60000 mov byte ptr [rax], 0
E8FEFDFFFF call System.Console:WriteLine()
B82A000000 mov eax, 42
G_M55888_IG03:
4883C438 add rsp, 56
C3 ret Unfortunately this type of issues are rather common, the JIT's handling of structs was and still is rather limited. |
cc @CarolEidt Maybe another good case for the first class structs work. |
Hmm, I'm not sure if first class structs work will help here. The IL generated for something like
The address of the local gets spilled because of the dup and you end up with an address exposed variable and that's a bit of a dead end. |
Info
Setup: Runtime=.NET Core 2.1.3 (CoreCLR 4.6.26725.06, CoreFX 4.6.26725.05), 64bit RyuJIT
Code for repro is at this commit (I haven't reduced it to a minimal repro yet): Porges/Fastre@3a2f805 (the
Accepts
method is what I am looking at, and the structs areVector128Impl
andVector256Impl
.)Description
I have two structs
T1
andT2
that implement an interface. These are used via thedefault(T1).Func(...)
method to get nice inlined code in a generic function.The
T2
struct implements all of its methods by forwarding to theT1
struct, so at the moment the behaviour is the same. I would expect the codegen to be the same in both cases, if everything inT2
inlines successfully (which it appears to). However, I'm seeing oddities.The codegen for
T1
looks fine:However with
T2
it looks like it's doing something very strange:You can see more of the disassembly here: https://gist.github.com/Porges/334ca424055be72470a67bc6eefe43a8
category:cq
theme:structs
skill-level:expert
cost:large
The text was updated successfully, but these errors were encountered: