Skip to content

Chained pattern matching not eliminating str/arr bounds check #119508

@ovska

Description

@ovska

The pattern str is { Length: 1 } && str[0] is 'x' or 'y' does not eliminate bounds checks when accessing the first char of the string (or array).

Adding extra indirection with && (sdr[0] is char c) && c is 'x' or 'y' does.

If there is only a single match in the indexer call, e.g. str[0] is 'z' the range check is properly eliminated.

Reproduces on older versions of .NET as well.

class Program
{
    // range check
    public static bool IsFlagsFormat(string? format) => format is { Length: 1 } && format[0] is 'f' or 'F';
    public static bool IsFlagsFormat(char[]? format) => format is { Length: 1 } && format[0] is 'f' or 'F';

    // no range check
    public static bool IsFlagsFormat2(string? format) => format is { Length: 1 } && (format[0] is char c) && (c is 'f' or 'F');
    public static bool IsFlagsFormat2(char[]? format) => format is { Length: 1 } && (format[0] is char c) && (c is 'f' or 'F');
}

https://godbolt.org/z/rKfbffMqE

Program:IsFlagsFormat(System.String):bool (FullOpts):
       push     rbp
       mov      rbp, rsp
       test     rdi, rdi
       je       SHORT G_M36473_IG04
       xor      eax, eax
       cmp      dword ptr [rdi+0x08], 1
       sete     al
       jmp      SHORT G_M36473_IG05
G_M36473_IG04:  ;; offset=0x0014
       xor      eax, eax
G_M36473_IG05:  ;; offset=0x0016
       movzx    rax, al
       test     eax, eax
       je       SHORT G_M36473_IG09
       cmp      dword ptr [rdi+0x08], 0
       jbe      SHORT G_M36473_IG10
       movzx    rax, word  ptr [rdi+0x0C]
       cmp      eax, 70
       je       SHORT G_M36473_IG07
       cmp      eax, 102
       jne      SHORT G_M36473_IG08
G_M36473_IG07:  ;; offset=0x0031
       mov      eax, 1
       jmp      SHORT G_M36473_IG09
G_M36473_IG08:  ;; offset=0x0038
       xor      eax, eax
G_M36473_IG09:  ;; offset=0x003A
       pop      rbp
       ret      
G_M36473_IG10:  ;; offset=0x003C
       call     CORINFO_HELP_RNGCHKFAIL
       int3   

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMItenet-performancePerformance related issue

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions