Skip to content

JIT: Redundant bounds check depending on branch order #113054

@MihaZupan

Description

@MihaZupan

https://godbolt.org/z/7Ye6je7M7

public static bool Test1(ReadOnlySpan<char> span, int pos) =>
    pos <= span.Length - 42 &&
    pos > 0 &&
    span[pos - 1] != '\n';

public static bool Test2(ReadOnlySpan<char> span, int pos) =>
    pos > 0 &&
    pos <= span.Length - 42 &&
    span[pos - 1] != '\n';
TestClass.Test1(System.ReadOnlySpan`1<Char>, Int32)
    L0000: sub rsp, 0x28
    L0004: mov rax, [rcx]
    L0007: mov ecx, [rcx+8]
    L000a: lea r8d, [rcx-0x2a]
    L000e: cmp edx, r8d
    L0011: jg short L002f
    L0013: test edx, edx
    L0015: jle short L002f
    L0017: dec edx
    L0019: cmp edx, ecx
    L001b: jae short L0036
    L001d: mov ecx, edx
    L001f: cmp word ptr [rax+rcx*2], 0xa
    L0024: setne al
    L0027: movzx eax, al
    L002a: add rsp, 0x28
    L002e: ret
    L002f: xor eax, eax
    L0031: add rsp, 0x28
    L0035: ret
    L0036: call 0x00007ffb09551728
    L003b: int3

TestClass.Test2(System.ReadOnlySpan`1<Char>, Int32)
    L0000: mov rax, [rcx]
    L0003: mov ecx, [rcx+8]
    L0006: test edx, edx
    L0008: jle short L0021
    L000a: add ecx, 0xffffffd6
    L000d: cmp edx, ecx
    L000f: jg short L0021
    L0011: dec edx
    L0013: mov ecx, edx
    L0015: cmp word ptr [rax+rcx*2], 0xa
    L001a: setne al
    L001d: movzx eax, al
    L0020: ret
    L0021: xor eax, eax
    L0023: ret

These are the kinds of checks emitted by Regex, e.g.

private bool TryFindNextPossibleStartingPosition(ReadOnlySpan<char> inputSpan)
{
    int pos = base.runtextpos;
    
    // Any possible match is at least 23 characters.
    if (pos <= inputSpan.Length - 23)
    {
        // The pattern has a leading beginning-of-line anchor.
        if (pos > 0 && inputSpan[pos - 1] != '\n')

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions