Closed
Description
Minimal reproduction:
SharpLab link
public readonly ref struct Wrapper
{
private readonly ReadOnlySpan<byte> _buffer;
public int Length => _buffer.Length;
public byte this[int i] => _buffer[i];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool BeginsWith0(Wrapper p)
{
return (uint)p.Length > 1 && p[0] == 0;
}
public static bool BeginsWith0Caller(Wrapper a) => BeginsWith0(a);
BeginsWith0 produces the following code. The wrapper's Length and indexer are inlined and the JIT removes the bounds checks.
G_M8674_IG01:
G_M8674_IG02:
mov eax, dword ptr [rcx+8]
cmp eax, 1
jbe SHORT G_M8674_IG05
G_M8674_IG03:
mov rax, bword ptr [rcx]
cmp byte ptr [rax], 0
sete al
movzx rax, al
G_M8674_IG04:
ret
G_M8674_IG05:
xor eax, eax
G_M8674_IG06:
ret
; Total bytes of code: 24
BeginsWith0Caller has unnecessary stack usage and the bounds checks are not removed.
G_M26510_IG01:
sub rsp, 56
vzeroupper
xor rax, rax
mov qword ptr [rsp+28H], rax
G_M26510_IG02:
vmovdqu xmm0, xmmword ptr [rcx]
vmovdqu xmmword ptr [rsp+28H], xmm0
G_M26510_IG03:
cmp dword ptr [rsp+30H], 1
jbe SHORT G_M26510_IG05
G_M26510_IG04:
lea rax, bword ptr [rsp+28H]
cmp dword ptr [rax+8], 0
jbe SHORT G_M26510_IG07
mov rax, bword ptr [rax]
cmp byte ptr [rax], 0
sete al
movzx rax, al
jmp SHORT G_M26510_IG06
G_M26510_IG05:
xor eax, eax
G_M26510_IG06:
add rsp, 56
ret
G_M26510_IG07:
call CORINFO_HELP_RNGCHKFAIL
int3
; Total bytes of code: 69
category:cq
theme:value-numbering
skill-level:intermediate
cost:medium
impact:medium