<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@inline function f(A, I)
    @boundscheck checkbounds(A, I)
    @inbounds A[I]
end
g(A, I) = @inbounds f(A, I)"><pre class="notranslate"><code class="notranslate">@inline function f(A, I)
    @boundscheck checkbounds(A, I)
    @inbounds A[I]
end
g(A, I) = @inbounds f(A, I)
</code></pre></div>
<p dir="auto">On <code class="notranslate">0.7-beta2</code> <code class="notranslate">@code_typed g(ones(1), 1)</code> will contain  a <code class="notranslate">checkbounds</code> call.</p>
<p dir="auto">cc: <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/mbauman/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/mbauman">@mbauman</a></p>
<p dir="auto">It would be nice to be able to remove more dead code in the julia-level optimizer. Example case:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="julia&gt; function f(A)
           @inbounds for I in 1:length(A)
               view(A, I)
           end
       end
f (generic function with 1 method)

julia&gt; @code_typed f([1])
CodeInfo(
2 1 ── %1  = Base.arraylen(%%A)::Int64                          │╻          length
  │    %2  = Base.sle_int(1, %1)::Bool                          ││╻╷╷╷       Type
  │          Base.sub_int(%1, 1)                                │││╻          unitrange_last
  │    %4  = Base.ifelse(%2, %1, 0)::Int64                      ││││       
  │    %5  = Base.slt_int(%4, 1)::Bool                          ││╻╷╷        isempty
  └───       goto 3 if not %5                                   ││         
  2 ──       goto 4                                             ││         
  3 ──       goto 4                                             ││         
  4 ┄─ %9  = φ (2 =&gt; true, 3 =&gt; false)::Bool                    │          
  │    %10 = φ (3 =&gt; 1)::Int64                                  │          
  │    %11 = φ (3 =&gt; 1)::Int64                                  │          
  │    %12 = Base.not_int(%9)::Bool                             │          
  └───       goto 16 if not %12                                 │          
  5 ┄─ %14 = φ (4 =&gt; %10, 15 =&gt; %35)::Int64                     │          
  │    %15 = φ (4 =&gt; %11, 15 =&gt; %36)::Int64                     │          
3 └───       goto 10 if not false                               │╻          view
  6 ── %17 = Core.tuple(%14)::Tuple{Int64}                      ││         
  │    %18 = Base.arraysize(%%A, 1)::Int64                      ││╻╷╷╷╷      checkbounds
  │    %19 = Base.slt_int(%18, 0)::Bool                         │││╻╷╷╷       checkbounds
  │    %20 = Base.ifelse(%19, 0, %18)::Int64                    ││││┃││││││    eachindex
  │    %21 = Base.sle_int(1, %14)::Bool                         │││││╻          &lt;=
  │    %22 = Base.sle_int(%14, %20)::Bool                       ││││││     
  │    %23 = Base.and_int(%21, %22)::Bool                       │││││╻          &amp;
  └───       goto 8 if not %23                                  │││        
  7 ──       goto 9                                             │││        
  8 ──       invoke Base.throw_boundserror(%%A::Array{Int64,1}, %17::Tuple{Int64})
  └───       unreachable                                        │││        
  9 ──       nothing                                            │          
  10 ┄       goto 11                                            │╻          view
  11 ─ %30 = Base.:===(%15, %4)::Bool                           ││╻          ==
  └───       goto 13 if not %30                                 ││         
  12 ─       goto 14                                            ││         
  13 ─ %33 = Base.add_int(%15, 1)::Int64                        ││╻          +
  └───       goto 14                                            │╻          iterate
  14 ┄ %35 = φ (13 =&gt; %33)::Int64                               │          
  │    %36 = φ (13 =&gt; %33)::Int64                               │          
  │    %37 = φ (12 =&gt; true, 13 =&gt; false)::Bool                  │          
  │    %38 = Base.not_int(%37)::Bool                            │          
  └───       goto 16 if not %38                                 │          
  15 ─       goto 5                                             │          
  16 ┄       return nothing                                     │          
) =&gt; Nothing"><pre class="notranslate"><code class="notranslate">julia&gt; function f(A)
           @inbounds for I in 1:length(A)
               view(A, I)
           end
       end
f (generic function with 1 method)

julia&gt; @code_typed f([1])
CodeInfo(
2 1 ── %1  = Base.arraylen(%%A)::Int64                          │╻          length
  │    %2  = Base.sle_int(1, %1)::Bool                          ││╻╷╷╷       Type
  │          Base.sub_int(%1, 1)                                │││╻          unitrange_last
  │    %4  = Base.ifelse(%2, %1, 0)::Int64                      ││││       
  │    %5  = Base.slt_int(%4, 1)::Bool                          ││╻╷╷        isempty
  └───       goto 3 if not %5                                   ││         
  2 ──       goto 4                                             ││         
  3 ──       goto 4                                             ││         
  4 ┄─ %9  = φ (2 =&gt; true, 3 =&gt; false)::Bool                    │          
  │    %10 = φ (3 =&gt; 1)::Int64                                  │          
  │    %11 = φ (3 =&gt; 1)::Int64                                  │          
  │    %12 = Base.not_int(%9)::Bool                             │          
  └───       goto 16 if not %12                                 │          
  5 ┄─ %14 = φ (4 =&gt; %10, 15 =&gt; %35)::Int64                     │          
  │    %15 = φ (4 =&gt; %11, 15 =&gt; %36)::Int64                     │          
3 └───       goto 10 if not false                               │╻          view
  6 ── %17 = Core.tuple(%14)::Tuple{Int64}                      ││         
  │    %18 = Base.arraysize(%%A, 1)::Int64                      ││╻╷╷╷╷      checkbounds
  │    %19 = Base.slt_int(%18, 0)::Bool                         │││╻╷╷╷       checkbounds
  │    %20 = Base.ifelse(%19, 0, %18)::Int64                    ││││┃││││││    eachindex
  │    %21 = Base.sle_int(1, %14)::Bool                         │││││╻          &lt;=
  │    %22 = Base.sle_int(%14, %20)::Bool                       ││││││     
  │    %23 = Base.and_int(%21, %22)::Bool                       │││││╻          &amp;
  └───       goto 8 if not %23                                  │││        
  7 ──       goto 9                                             │││        
  8 ──       invoke Base.throw_boundserror(%%A::Array{Int64,1}, %17::Tuple{Int64})
  └───       unreachable                                        │││        
  9 ──       nothing                                            │          
  10 ┄       goto 11                                            │╻          view
  11 ─ %30 = Base.:===(%15, %4)::Bool                           ││╻          ==
  └───       goto 13 if not %30                                 ││         
  12 ─       goto 14                                            ││         
  13 ─ %33 = Base.add_int(%15, 1)::Int64                        ││╻          +
  └───       goto 14                                            │╻          iterate
  14 ┄ %35 = φ (13 =&gt; %33)::Int64                               │          
  │    %36 = φ (13 =&gt; %33)::Int64                               │          
  │    %37 = φ (12 =&gt; true, 13 =&gt; false)::Bool                  │          
  │    %38 = Base.not_int(%37)::Bool                            │          
  └───       goto 16 if not %38                                 │          
  15 ─       goto 5                                             │          
  16 ┄       return nothing                                     │          
) =&gt; Nothing
</code></pre></div>
<p dir="auto">In this IR there are a couple redundant basic blocks (consisting only of a goto to the next block). There is also unreachable bounds error code (<code class="notranslate">goto 10 if not false</code>). LLVM can remove this code very easily, but it would still be useful for us to remove it (1) to cut down stored IR size, (2) for inlining heuristics, and (3) to spend less time lowering to LLVM.</p>