Skip to content
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

Improve codegen for Unsafe<> same size casts. #34156

Closed
sandreenko opened this issue Mar 26, 2020 · 3 comments
Closed

Improve codegen for Unsafe<> same size casts. #34156

sandreenko opened this issue Mar 26, 2020 · 3 comments
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI enhancement Product code improvement that does NOT require public API changes/additions
Milestone

Comments

@sandreenko
Copy link
Contributor

sandreenko commented Mar 26, 2020

For C# code int r = Unsafe.As<float, int>(ref l); we generate:

IN0002: 00000B mov      dword ptr [V00 rsp+24H], ecx
IN0003: 00000F vmovss   xmm0, dword ptr [V00 rsp+24H]

for float r = Unsafe.As<int, float>(ref l); we generate:

IN0002: 00000B mov      dword ptr [V00 rsp+24H], ecx
IN0003: 00000F vmovss   xmm0, dword ptr [V00 rsp+24H]

the optimal codegen should be one mov instead of two, like movq xmm0, rcx in case of Unsafe.As<double, long>(ref l);

The unoptimal code happens because we retype access to LCL_VAR as LCL_FIELD and it forbids LCL_VAR to be enregistered:

fgMorphTree BB01, STMT00002 (before)
               [000009] -ACXG-------              *  ASG       float 
               [000008] D------N----              +--*  LCL_VAR   float  V01 loc1         
               [000007] *-CXG-------              \--*  IND       float 
               [000015] ------------                 \--*  ADDR      byref 
               [000016] ------------                    \--*  LCL_VAR   int    V00 loc0         

Local V00 should not be enregistered because: was accessed as a local field

fgMorphTree BB01, STMT00002 (after)
               [000009] -A--G+------              *  ASG       float 
               [000008] D----+-N----              +--*  LCL_VAR   float  V01 loc1         
               [000016] -----+------              \--*  LCL_FLD   float  V00 loc0         [+0]

and we don't have a better representation of non-widening type changes that do not require LCL_VAR to be address exposed or non-enregistarable.

It will be a bigger problem when #33225 is merged because we will do the same for Unsafe.As<long, 8 byte struct>, because before for a method like System.Runtime.Intrinsics.Vector64:Create(ubyte):System.Runtime.Intrinsics.Vector641[Byte] ` we had:

impFixupStructReturnType: retyping
               [000065] --CXG-------              *  OBJ       struct<System.Runtime.Intrinsics.Vector64`1[Byte], 8>
               [000064] --C---------              \--*  LCL_VAR   long   V01 loc0 

impFixupStructReturnType: result of retyping is
               [000065] *-CXG-------              *  IND       long  
               [000064] --C---------              \--*  LCL_VAR   long   V01 loc0 


STMT00011 (IL   ???...  ???)
               [000066] --CXG-------              *  RETURN    long  
               [000065] *-CXG-------              \--*  IND       long  
               [000064] --C---------                 \--*  LCL_VAR   long   V01 loc0 

and we were lucky because this did not forbid any optimization on the result LCL_VAR.

The number of affected methods is small (mostly Unsafe casts and constructors), but these methods are used where performance is important.

I have discussed with @CarolEidt a possible fix via a new node (call it like OBJ_BITCAST) that appears in morph phase, has object layout field and changes into a normal bitcast during lowering.
Looking for thoughts and other ideas, PTAL @dotnet/jit-contrib .

category:cq
theme:optimization
skill-level:intermediate
cost:medium

@sandreenko sandreenko added enhancement Product code improvement that does NOT require public API changes/additions area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Mar 26, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Mar 26, 2020
@tannergooding
Copy link
Member

tannergooding commented Mar 26, 2020

A similar optimization should be equally applicable to *(int*)&floatValue and similar casts (#11413)

@sandreenko
Copy link
Contributor Author

@tannergooding thanks, I have missed that issue, I will wait and probably close this one as a duplicate.

@BruceForstall BruceForstall removed the untriaged New issue has not been triaged by the area owner label Apr 3, 2020
@BruceForstall BruceForstall added this to the Future milestone Apr 3, 2020
@sandreenko
Copy link
Contributor Author

Duplicate of #11413

@sandreenko sandreenko marked this as a duplicate of #11413 Apr 3, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI enhancement Product code improvement that does NOT require public API changes/additions
Projects
None yet
Development

No branches or pull requests

4 participants