JIT: Coalescing of `Arr.Length` memory accesses inside loop
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
The [Memory Model](https://github.com/dotnet/runtime/blob/9acc0d90d977fda25b4d2309f6ae17f2d8f4f485/docs/design/specs/Memory-model.md#side-effects-and-optimizations-of-memory-accesses) states:
> Adjacent non-volatile reads from the same location can be coalesced.
In the following loop we end up with two reads from `Arr.Length`. One for the bounds check and one for the loop limit. I wonder if this is a candiate for coalescing.
```cs
// https://godbolt.org/z/d3hY4ev8f
class Program
{
int[] Arr;
int Test()
{
int sum = 0;
for (int i = 0; i < Arr.Length; i++)
{
sum += Arr[i];
}
return sum;
}
}
```
```assembly
G_M38134_IG03: ;; offset=0x0020
mov rdi, rdx
cmp ecx, dword ptr [rdi+0x08] ; Arr.Length
jae SHORT G_M38134_IG05
add eax, dword ptr [rdi+4*rcx+0x10]
inc ecx
cmp dword ptr [rdx+0x08], ecx ; Arr.Length
jg SHORT G_M38134_IG03
```
Furthermore, it also states this:
> Coalescing of adjacent ordinary memory accesses to the same location is ok because most programs do not rely on presence of data races thus, unlike introducing, removing data races is ok. **Programs that do rely on observing data races shall use volatile accesses.**
Since this code doesn't use `volatile` reads can't we hoist `Arr.Length` entirely and eliminate the bounds check?
Contributor guide
Assessment
This issue has not been assessed yet.