Skip to content

JIT: Field access of struct is not hoisted when bounds check is not eliminated #113107

Open
@BoyBaykiller

Description

@BoyBaykiller

https://godbolt.org/z/nr6zPYveW

First the case where bounds check was elided and codegen in the loop is perfect (loads are hoisted):

struct BuildData
{
    public float[] RightCostsAccum;
    public float Value;
}

void HoistedMov(BuildData buildData)
{
    for (int i = 0; i < buildData.RightCostsAccum.Length; i++)
    {
        buildData.RightCostsAccum[i] = buildData.Value;
    }
}
G_M27756_IG04:
       vmovss   dword ptr [rax], xmm0
       add      rax, 4
       dec      ecx
       jne      SHORT G_M27756_IG04

Now when bounds check is not elided like here:

void NotHoistedMov(BuildData buildData)
{
    for (int i = 0; i < 100; i++)
    {
        buildData.RightCostsAccum[i] = buildData.Value;
    }
}

we repeatedly load buildData.RightCostsAccum and buildData.Value inside the loop:

G_M15865_IG03:
       mov      rcx, gword ptr [rdx]               ; load buildData.RightCostsAccum
       cmp      eax, dword ptr [rcx+0x08]          ; load buildData.RightCostsAccum.Length
       jae      SHORT G_M15865_IG05
       vmovss   xmm0, dword ptr [rdx+0x08]         ; load buildData.Value
       vmovss   dword ptr [rcx+4*rax+0x10], xmm0
       inc      eax
       cmp      eax, 100
       jl       SHORT G_M15865_IG03

As a workarround you can manually load the fields outside the loop.
When the fields of the struct are passed in individual registers this is not an issue.

Metadata

Metadata

Assignees

Labels

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

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions