KEMBAR78
Pinning ROS with known length causes unnecessary code generation. · Issue #94559 · dotnet/runtime · GitHub
Skip to content

Pinning ROS with known length causes unnecessary code generation. #94559

@Raphtaliyah

Description

@Raphtaliyah

Pinning a ReadOnlySpan<> where the length is constant generates code that checks the length.

This managed code

static void Main()
{
    var data = new byte[128];
    fixed (byte* ptr = (ReadOnlySpan<byte>)data)
    {
        DoSomething(ptr);
    }
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void DoSomething(byte* bob) { }

generates this assembly on x64 for pinning (from godbolt, using the latest runtime):

mov      edi, 128
xor      rcx, rcx
test     edi, edi
cmovne   rcx, rax
mov      bword ptr [rsp], rcx

The JIT is able to figure out that the length is constant (mov edi, 128) which makes the rest of the code unnecessary. test edi, edi will always clear ZF because edi is constant not zero which will cause cmovne rcx, rax to always execute which will overwrite rcx that just got zerod. This whole sequence could be converted to a mov bword ptr [rsp], rax when the length can be proven to be constant.

The codegen on .NET 7 uses a jump instead of cmovne but the testing of constant is still present, .NET 6 does things differently (and worse) so this issue probably only applies to .NET 7 and newer.

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMItenet-performancePerformance related issue

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions