# IRCE appreciation and gripes (inductive range check elimination)

**URL:** <https://discourse.julialang.org/t/irce-appreciation-and-gripes-inductive-range-check-elimination/111822>\
**Category:** Internals & Design\
**Created:** [March 19, 2024, 2:45pm UTC](https://discourse.julialang.org/t/irce-appreciation-and-gripes-inductive-range-check-elimination/111822 "2024-03-19T14:45:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [March 19, 2024, 2:45pm UTC](https://discourse.julialang.org/t/irce-appreciation-and-gripes-inductive-range-check-elimination/111822/1 "2024-03-19T14:45:23Z")

</div>

IRCE is an LLVM pass that aims to loop unswitch range checks. As such, its goal is to reduce the performance impact of bounds checks – especially missing @inbounds should no longer prevent vectorization.

To give a simple example:

```julia
function sumRange(arr, start, stop)
  s = zero(eltype(arr))
  for idx = start:stop
    s += arr[idx]
  end
  s
end

```

It used to be that this checked bounds on every loop iteration, which prevented vectorization and therefore had a huge performance impact (4x+).

Therefore, the old way of writing julia code was:

```julia
Base.@propagate_inbounds function sumRange(arr, start, stop)
  @boundscheck checkbounds(arr, start:stop)
  s = zero(eltype(arr))
  @inbounds for idx = start:stop
    s += arr[idx]
  end
  s
end

```

This is annoying. Enter IRCE, which uses the fact that the loop index and the boundschecks implied by the access are monotone, in order to hoist the bounds-checks out of the loop.

First of all, huge kudos to pchintalapudi who made this work in 2021 (+20/-5 lines over 2 PRs [here](https://github.com/JuliaLang/julia/pull/42573) and [here](https://github.com/JuliaLang/julia/pull/42692)). I had tried the same some years ago, and I failed miserably.

If reliable, then this simple change in the optimization pipeline can change the face of the language. ❤

It seems that this change has flown under the radar for most people. Really, try out how necessary all the `@inbounds` are – you might be pleasantly surprised.

* * *

That being said, it doesn’t work reliably anymore on master ☹

For example,

```julia
function fooSum(arr)
  s=zero(eltype(arr))
  for i=1:length(arr)
    s += arr[i]
  end
  s
end

```

used to vectorize in 1.10.1 (it even managed to remove _all_ boundschecks) and doesn’t vectorize any longer in

```julia
julia> versioninfo()
Julia Version 1.12.0-DEV.214
Commit 2775c9a0dc4 (2024-03-19 08:20 UTC)

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 19, 2024, 2:49pm UTC](https://discourse.julialang.org/t/irce-appreciation-and-gripes-inductive-range-check-elimination/111822/2 "2024-03-19T14:49:00Z")

</div>

That sounds like a regression for a non-released version; please open an issue.

---

<div class="post-metadata">

**Author:** ![Zentrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zentrik/32/35409_2.png) [@Zentrik](https://discourse.julialang.org/u/Zentrik)\
**Post date:** [March 19, 2024, 4:42pm UTC](https://discourse.julialang.org/t/irce-appreciation-and-gripes-inductive-range-check-elimination/111822/3 "2024-03-19T16:42:26Z")

</div>

Note there is a benchmark, [BaseBenchmarks.jl/src/array/sumindex.jl at 9e78db8463f01dcbebffc1bccb949a28be52d130 · JuliaCI/BaseBenchmarks.jl · GitHub](https://github.com/JuliaCI/BaseBenchmarks.jl/blob/9e78db8463f01dcbebffc1bccb949a28be52d130/src/array/sumindex.jl#L13-L21C4), that is tracked by CI that is precisely your example.  
Oddly there doesn’t seem to be a benchmark run on something like a `Vector{Float64}`, nevertheless a regression was identified recently and reported [3.5x regression on bounds checking in BaseBenchmarks due to LLVM bump to 15.0.7+10 in #52405 · Issue #53698 · JuliaLang/julia (github.com)](https://github.com/JuliaLang/julia/issues/53698).

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [March 19, 2024, 4:54pm UTC](https://discourse.julialang.org/t/irce-appreciation-and-gripes-inductive-range-check-elimination/111822/4 "2024-03-19T16:54:47Z")

</div>

I wonder if it’s having trouble understanding the relation between memory and array
