Skip to content

Jit: Bounds checks are not removed in some inlined functions #32414

Closed
@Thealexbarney

Description

@Thealexbarney

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

Metadata

Metadata

Assignees

No one assigned

    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