-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
JIT generates suboptimal code for value copy to pointer #11992
Comments
It is worth calling out that sharplab only shows disassembly for the full framework version of RyuJIT (and uses the legacy JIT for x86). This means it is decently outdated and is missing many of the optimizations/fixes that have been made in CoreCLR. It would be worth validating which of these still produce unoptimal assembly with either the latest NetCore 3.0 preview or the current head of the master branch. |
Current coreclr build generates: ; Assembly listing for method Test:WriteShort(short):this
G_M60373_IG01:
0F1F440000 nop
G_M60373_IG02:
488B4108 mov rax, qword ptr [rcx+8]
668910 mov word ptr [rax], dx
G_M60373_IG03:
C3 ret
; Total bytes of code 13, prolog size 5 for method Test:WriteShort(short):this
; ============================================================
; Assembly listing for method Test:WriteUShort(ushort):this
G_M11744_IG01:
0F1F440000 nop
G_M11744_IG02:
488B4108 mov rax, qword ptr [rcx+8]
668910 mov word ptr [rax], dx
G_M11744_IG03:
C3 ret
; Total bytes of code 13, prolog size 5 for method Test:WriteUShort(ushort):this
; ============================================================
; Assembly listing for method Test:WriteChar(ushort):this
G_M3391_IG01:
0F1F440000 nop
G_M3391_IG02:
488B4108 mov rax, qword ptr [rcx+8]
668910 mov word ptr [rax], dx
G_M3391_IG03:
C3 ret
; Total bytes of code 13, prolog size 5 for method Test:WriteChar(ushort):this
; ============================================================
; Assembly listing for method Test:WriteShort_TakeRefAndDeref(short):this
G_M9115_IG01:
0F1F440000 nop
89542410 mov dword ptr [rsp+10H], edx
G_M9115_IG02:
488B4108 mov rax, qword ptr [rcx+8]
480FBF542410 movsx rdx, word ptr [rsp+10H]
668910 mov word ptr [rax], dx
G_M9115_IG03:
C3 ret
; Total bytes of code 23, prolog size 5 for method Test:WriteShort_TakeRefAndDeref(short):this
; ============================================================
; Assembly listing for method Test:WriteStruct_Direct(struct):this
G_M5762_IG01:
0F1F440000 nop
4889542410 mov qword ptr [rsp+10H], rdx
G_M5762_IG02:
488B4108 mov rax, qword ptr [rcx+8]
480FBF542410 movsx rdx, word ptr [rsp+10H]
668910 mov word ptr [rax], dx
G_M5762_IG03:
C3 ret
; Total bytes of code 24, prolog size 5 for method Test:WriteStruct_Direct(struct):this
; ============================================================
; Assembly listing for method Test:WriteStruct_ByShort(struct):this
G_M41542_IG01:
0F1F440000 nop
4889542410 mov qword ptr [rsp+10H], rdx
G_M41542_IG02:
488B4108 mov rax, qword ptr [rcx+8]
480FBF542410 movsx rdx, word ptr [rsp+10H]
668910 mov word ptr [rax], dx
G_M41542_IG03:
C3 ret
; Total bytes of code 24, prolog size 5 for method Test:WriteStruct_ByShort(struct):this
; ============================================================
; Assembly listing for method Test:WriteStruct_ByUShort(struct):this
G_M57683_IG01:
0F1F440000 nop
4889542410 mov qword ptr [rsp+10H], rdx
G_M57683_IG02:
488B4108 mov rax, qword ptr [rcx+8]
0FB7542410 movzx rdx, word ptr [rsp+10H]
668910 mov word ptr [rax], dx
G_M57683_IG03:
C3 ret
; Total bytes of code 23, prolog size 5 for method Test:WriteStruct_ByUShort(struct):this |
@dotnet/jit-contrib |
So We start with reasonable IR:
and morph transforms it into problematic IR
So this is basically another struct handling issue, different but related to #11940, #4323, #11848 and probably others that I don't remember. It's not clear what a good solution would be. Probably either reinterpreting |
|
The remaining two -
|
@sandreenko - I think this might have been fixed by your changes? |
; Method Test:WriteStruct_ByShort(Test+MyStruct):this
G_M56169_IG01:
mov qword ptr [rsp+10H], rdx
;; size=5 bbWeight=1 PerfScore 1.00
G_M56169_IG02:
mov rax, qword ptr [rcx+08H]
movsx rdx, word ptr [rsp+10H]
mov word ptr [rax], dx
;; size=13 bbWeight=1 PerfScore 6.00
G_M56169_IG03:
ret
;; size=1 bbWeight=1 PerfScore 1.00
; Total bytes of code: 19 Fundamentally the JIT does not handle promoted structs "packed" in registers today when their fields do not map cleanly which likely would need to be resolved in some way to avoid |
I believe all methods bellow should have same code generated by JIT. Only 'WriteShort' method looks fine.
Short/UShort/Char/MyStruct are all 2 bytes long and therefore all methods are equivalent.
There are unnecessary moves back and forth.
Can be seen at sharplab.io.
category:cq
theme:structs
skill-level:expert
cost:large
impact:small
The text was updated successfully, but these errors were encountered: