dotnet / dotnet/runtime

JIT: Writing into local memory prevents hoisting loads out of loop

Open
#121,423 11 comments 2 reactions 1 assignee Claimed by @AndyAyersMS View on GitHub
area-CodeGen-coreclr JIT-LoopOpt
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

https://godbolt.org/z/f7xheT6E6

Inside the loop I expect 1 load per iteration from `buildData.OriginalTriIds`.
The actual number of loads is 4. It seems like loop hoisting gives up because of the write into `indices`. But `indices` shouldn't be able to alias `leafNode` in any way:

```cs
static Span GetUnindexed(in GpuBlasNode leafNode, BuildData buildData)
{
Span indices = new int[leafNode.TriCount];
for (int i = 0; i < leafNode.TriCount; i++)
{
indices[i] = buildData.OriginalTriIds[leafNode.TriStartOrChild + i];
}

return indices;
}
```
`leafNode.TriCount`, `leafNode.TriStartOrChild` and `buildData.OriginalTriIds.Length` (for the bounds check) can be hoisted.
```assembly
Program:GetUnindexed(byref,Program+BuildData):System.Span`1[int] (FullOpts):
push rbp
push r15
push r14
push rbx
push rax
lea rbp, [rsp+0x20]
mov rbx, rdi
mov r15, rsi
mov r14d, dword ptr [rbx+0x24]
movsxd rsi, r14d
mov rdi, 0x7AD3E913A7C0 ; int[]
call CORINFO_HELP_NEWARR_1_VC
add rax, 16
mov edx, r14d
xor ecx, ecx
test r14d, r14d
jle SHORT G_M9601_IG04
align [10 bytes for IG03]
G_M9601_IG03: ;; offset=0x0040
cmp ecx, edx
jae SHORT G_M9601_IG05
mov edi, ecx
add edi, dword ptr [rbx+0x10] ; <-- load leafNode.TriStartOrChild
cmp edi, dword ptr [r15+0x08] ; <-- load buildData.OriginalTriIds.Length
jae SHORT G_M9601_IG05
mov edi, dword ptr [r15+4*rdi+0x10]
mov dword ptr [rax+4*rcx], edi
inc ecx
cmp ecx, dword ptr [rbx+0x24] ; <-- load leafNode.TriCount
jl SHORT G_M9601_IG03
G_M9601_IG04: ;; offset=0x005E
add rsp, 8
pop rbx
pop r14
pop r15
pop rbp
ret
G_M9601_IG05: ;; offset=0x0069
call CORINFO_HELP_RNGCHKFAIL
int3
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.