[mono] fix bound checks for Spans in LLVM-jit mode (add extra SROA pass) (#20054)
commitf026b9a31cd3d3f980a14bc612a698312570e3fd
authormonojenkins <jo.shields+jenkins@xamarin.com>
Thu, 16 Jul 2020 17:08:51 +0000 (16 13:08 -0400)
committerGitHub <noreply@github.com>
Thu, 16 Jul 2020 17:08:51 +0000 (16 20:08 +0300)
tree3a9bf26467958222d6cce2ba293aa0fcd6b998da
parent3856ef71f87a76657c02dad158d9ba76fb9a0dbe
[mono] fix bound checks for Spans in LLVM-jit mode (add extra SROA pass) (#20054)

I noticed that the following code leaves bound checks when compiled using LLVM-JIT:
```csharp
static void Test(Span<int> span)
{
    for (int i = 0; i < span.Length; i++)
        x[i] = 0;
}
```
#### Current codegen:
```asm
Test:
0000000000000000 pushq %rax
0000000000000001 testl %esi, %esi
0000000000000003 jle 0x3f
0000000000000005 xorl %eax, %eax
0000000000000007 movl %esi, %ecx
0000000000000009 cmpq %rcx, %rax
000000000000000c jae 0x2c
000000000000000e nop
0000000000000010 movl $0x0, (%rdi)
0000000000000016 incq %rax
0000000000000019 movslq %esi, %rcx
000000000000001c cmpq %rcx, %rax
000000000000001f jge 0x3f
0000000000000021 addq $0x4, %rdi
0000000000000025 movl %esi, %ecx
0000000000000027 cmpq %rcx, %rax
000000000000002a jb 0x10
000000000000002c movabsq $0x7fc330531710, %rax
0000000000000036 movl $0x106, %edi
000000000000003b callq *(%rax) ;; <---- bound check
000000000000003d ud2
000000000000003f popq %rax
0000000000000040 retq
```
looks like an additional -sroa pass after lower-expect and instcombine fixes it:
#### New codegen:
```asm
Test:
0000000000000000 testl %esi, %esi
0000000000000002 jle 0x1f
0000000000000004 movl %esi, %eax
0000000000000006 nopw %cs:(%rax,%rax)
0000000000000010 movl $0x0, (%rdi)
0000000000000016 addq $0x4, %rdi
000000000000001a decq %rax
000000000000001d jne 0x10
000000000000001f retq
```
Here is the original LLVM IR before optimizations: https://godbolt.org/z/PLfR6x

Co-authored-by: EgorBo <EgorBo@users.noreply.github.com>
mono/mini/llvm-jit.cpp