Skip to content

Commit 15b9851

Browse files
authored
Eagerly do boundscheck when indexing into CartesianIndices (#42119)
1 parent 9d5de6c commit 15b9851

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

base/multidimensional.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,14 @@ module IteratorsMD
357357
@propagate_inbounds function Base.getindex(iter::CartesianIndices{0,R}) where {R}
358358
CartesianIndex()
359359
end
360-
@propagate_inbounds function Base.getindex(iter::CartesianIndices{N,R}, I::Vararg{Int, N}) where {N,R}
361-
CartesianIndex(getindex.(iter.indices, I))
360+
@inline function Base.getindex(iter::CartesianIndices{N,R}, I::Vararg{Int, N}) where {N,R}
361+
# Eagerly do boundscheck before calculating each item of the CartesianIndex so that
362+
# we can pass `@inbounds` hint to inside the map and generates more efficient SIMD codes (#42115)
363+
@boundscheck checkbounds(iter, I...)
364+
index = map(iter.indices, I) do r, i
365+
@inbounds getindex(r, i)
366+
end
367+
CartesianIndex(index)
362368
end
363369

364370
# CartesianIndices act as a multidimensional range, so cartesian indexing of CartesianIndices

test/boundscheck_exec.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,17 @@ if bc_opt == bc_default || bc_opt == bc_off
259259
@test !occursin("arrayref(true", typed_40281)
260260
end
261261

262+
@testset "pass inbounds meta to getindex on CartesianIndices (#42115)" begin
263+
@inline getindex_42115(r, i, j) = @inbounds getindex(r, i, j)
264+
265+
R = CartesianIndices((5, 5))
266+
if bc_opt == bc_on
267+
@test_throws BoundsError getindex_42115(R, -1, -1)
268+
@test_throws BoundsError getindex_42115(R, 1, -1)
269+
else
270+
@test getindex_42115(R, -1, -1) == CartesianIndex(-1, -1)
271+
@test getindex_42115(R, 1, -1) == CartesianIndex(1, -1)
272+
end
273+
end
274+
262275
end

0 commit comments

Comments
 (0)