Skip to content

JIT can't elide span.Slice range checks after a manual check #112953

@MihaZupan

Description

@MihaZupan

https://godbolt.org/z/hjqc5rodx

For a case like this:

public static ReadOnlySpan<char> Test(ReadOnlySpan<char> span, int offset)
{
    if ((uint)offset < (uint)span.Length)
    {
        return span.Slice(offset + 1);
    }
    
    return span;
}

public ReadOnlySpan<T> Slice(int start)
{
if ((uint)start > (uint)_length)
ThrowHelper.ThrowArgumentOutOfRangeException();
return new ReadOnlySpan<T>(ref Unsafe.Add(ref _reference, (nint)(uint)start /* force zero-extension */), _length - start);
}

The JIT isn't removing the if ((uint)start > (uint)_length) check.

You can hit that in IndexOf + slice loops, e.g.

int count = 0;
int pos;
while ((uint)(pos = span.IndexOf(c)) < (uint)span.Length)
{
    count++;
    span = span.Slice(pos + 1);
}

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

Relationships

None yet

Development

No branches or pull requests

Issue actions