Skip to content

Commit

Permalink
Eagerly do boundscheck when indexing into CartesianIndices (#42119)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnychen94 authored Sep 8, 2021
1 parent 9d5de6c commit 15b9851
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
10 changes: 8 additions & 2 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,14 @@ module IteratorsMD
@propagate_inbounds function Base.getindex(iter::CartesianIndices{0,R}) where {R}
CartesianIndex()
end
@propagate_inbounds function Base.getindex(iter::CartesianIndices{N,R}, I::Vararg{Int, N}) where {N,R}
CartesianIndex(getindex.(iter.indices, I))
@inline function Base.getindex(iter::CartesianIndices{N,R}, I::Vararg{Int, N}) where {N,R}
# Eagerly do boundscheck before calculating each item of the CartesianIndex so that
# we can pass `@inbounds` hint to inside the map and generates more efficient SIMD codes (#42115)
@boundscheck checkbounds(iter, I...)
index = map(iter.indices, I) do r, i
@inbounds getindex(r, i)
end
CartesianIndex(index)
end

# CartesianIndices act as a multidimensional range, so cartesian indexing of CartesianIndices
Expand Down
13 changes: 13 additions & 0 deletions test/boundscheck_exec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -259,4 +259,17 @@ if bc_opt == bc_default || bc_opt == bc_off
@test !occursin("arrayref(true", typed_40281)
end

@testset "pass inbounds meta to getindex on CartesianIndices (#42115)" begin
@inline getindex_42115(r, i, j) = @inbounds getindex(r, i, j)

R = CartesianIndices((5, 5))
if bc_opt == bc_on
@test_throws BoundsError getindex_42115(R, -1, -1)
@test_throws BoundsError getindex_42115(R, 1, -1)
else
@test getindex_42115(R, -1, -1) == CartesianIndex(-1, -1)
@test getindex_42115(R, 1, -1) == CartesianIndex(1, -1)
end
end

end

0 comments on commit 15b9851

Please sign in to comment.