Skip to content

[RyuJIT] Unnecessary register moves from Unsafe.AsRef<T> #8730

@fiigii

Description

@fiigii

According to VTune characterization, ParseHeaders is one of the hot functions in TechEmpower-Plaintext scenario.

ParseHeaders invokes inlined DangerousGetPinnableReference twice, which generates roundtrip mov sequences from inlined Unsafe.AsRef<T>:

IN0056: 000203 call     System.IntPtr:ToPointer():long:this
IN0057: 000208 mov      rdi, rax
IN0058: 00020B mov      rax, rdi
IN0059: 00020E mov      rdi, rax
IN005a: 000211 jmp      SHORT G_M11292_IG13
......
IN0080: 0002BE call     System.IntPtr:ToPointer():long:this
IN0081: 0002C3 mov      rdi, rax
IN0082: 0002C6 mov      rax, rdi
IN0083: 0002C9 mov      rdi, rax
IN0084: 0002CC mov      eax, dword ptr [V48 rbp-198H]
IN0085: 0002D2 movsxd   rax, eax

These redundant moves are from Unsafe.AsRef<T> source code:

  .method public hidebysig static !!T& AsRef<T>(void* source) cil managed aggressiveinlining
  {
        .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
        .locals (int32&)
        .maxstack 1
        ldarg.0
        // Roundtrip via a local to avoid type mismatch on return that the JIT inliner chokes on.
        stloc.0
        ldloc.0
        ret
  } // end of method Unsafe::AsRef

@jkotas 's example shows that this roundtrip has been correctly eliminated by the compiler, but it appears in the generated code of Span.DangerousGetPinnableReference.

I will look into providing a solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions