Skip to content

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

Closed

Description

@itsBuggingMe

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;
}

Activity

  1. dotnet-policy-service commented on Dec 29, 2024

    @dotnet-policy-service
    Contributor

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

  2. added
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    and removed on Dec 29, 2024
  3. dotnet-policy-service commented on Dec 29, 2024

    @dotnet-policy-service
    Contributor

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

  4. EgorBo commented on Dec 29, 2024

    @EgorBo
    Member

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

  5. removed
    untriagedNew issue has not been triaged by the area owner
    on Dec 29, 2024
  6. added this to the Future milestone on Dec 29, 2024
  7. tannergooding commented on Dec 31, 2024

    @tannergooding
    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.

  8. added
    in-prThere is an active PR which will close this issue when it is merged
    on Mar 16, 2025
  9. self-assigned this
    on Mar 18, 2025
  10. modified the milestones: Future, 10.0.0 on Mar 18, 2025
  11. locked and limited conversation to collaborators on Apr 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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 mergedtenet-performancePerformance related issue

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions