Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT doesn't elide bounds checking when iterating over a span and an array of known length #110986

Open
itsBuggingMe opened this issue Dec 29, 2024 · 4 comments
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI tenet-performance Performance related issue
Milestone

Comments

@itsBuggingMe
Copy link

Description

If you ensure that the length of an array and a span are the same, the JIT will still emit bounds checking on only the span when indexing.
This does not occur when iterating over a span and a span, or an array and an array.

public static int SumSpanArray(int[] arr, Span<int> span)
{
    int counter = 0;
    
    if(arr.Length != span.Length)
        return 0;
    
    //bounds check here
    for(int i = 0; i < arr.Length; i++)
        counter += arr[i] + span[i];
    
    return counter;
}

Sharplab example here

Regression?

I have only used Sharplab to test this, but it doesn't seem likely to be a regression.

Analysis

I don't know why, but curiously enough when checking the span length when iterating over a span + array, there is no bound check

public static int SumSpanArray2(int[] arr, Span<int> span)
{
    int counter = 0;
    
    if(arr.Length != span.Length)
        return 0;
    
    //no bound check
    for(int i = 0; i < span.Length; i++)
        counter += arr[i] + span[i];
    
    return counter;
}
@itsBuggingMe itsBuggingMe added the tenet-performance Performance related issue label Dec 29, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Dec 29, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-memory
See info in area-owners.md if you want to be subscribed.

@jkotas jkotas added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI and removed area-System.Memory labels Dec 29, 2024
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@EgorBo
Copy link
Member

EgorBo commented Dec 29, 2024

It works if both are arrays. Presumably it should work here as well once #82946 is implemented.

@EgorBo EgorBo removed the untriaged New issue has not been triaged by the area owner label Dec 29, 2024
@EgorBo EgorBo added this to the Future milestone Dec 29, 2024
@tannergooding
Copy link
Member

Notably as well it does work if you insert a span1 = span1.Slice(span2.Length) after a if (span1.Length != span2.Length) { return; } check.

So there is a relatively easy workaround, but ideally we'd still just handle correlating the array/span or span/span lengths directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI tenet-performance Performance related issue
Projects
None yet
Development

No branches or pull requests

4 participants