<p dir="auto">without threads it is fine:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="julia&gt; function foo(x,y,z)
         for i in eachindex(y)
           y[i] -= z[x]
         end
         x += 1
         return x
       end
foo (generic function with 1 method)

julia&gt; @code_warntype foo(1,[1,2,3],[4,5,6])
Variables
  #self#::Core.Const(foo)
  x@_2::Int64
  y::Vector{Int64}
  z::Vector{Int64}
  @_5::Union{Nothing, Tuple{Int64, Int64}}
  i::Int64
  x@_7::Int64

Body::Int64
1 ─       (x@_7 = x@_2)
│   %2  = Main.eachindex(y)::Base.OneTo{Int64}
│         (@_5 = Base.iterate(%2))
│   %4  = (@_5 === nothing)::Bool
│   %5  = Base.not_int(%4)::Bool
└──       goto #4 if not %5
2 ┄ %7  = @_5::Tuple{Int64, Int64}::Tuple{Int64, Int64}
│         (i = Core.getfield(%7, 1))
│   %9  = Core.getfield(%7, 2)::Int64
│   %10 = Base.getindex(y, i)::Int64
│   %11 = Base.getindex(z, x@_7)::Int64
│   %12 = (%10 - %11)::Int64
│         Base.setindex!(y, %12, i)
│         (@_5 = Base.iterate(%2, %9))
│   %15 = (@_5 === nothing)::Bool
│   %16 = Base.not_int(%15)::Bool
└──       goto #4 if not %16
3 ─       goto #2
4 ┄       (x@_7 = x@_7 + 1)
└──       return x@_7"><pre class="notranslate"><code class="notranslate">julia&gt; function foo(x,y,z)
         for i in eachindex(y)
           y[i] -= z[x]
         end
         x += 1
         return x
       end
foo (generic function with 1 method)

julia&gt; @code_warntype foo(1,[1,2,3],[4,5,6])
Variables
  #self#::Core.Const(foo)
  x@_2::Int64
  y::Vector{Int64}
  z::Vector{Int64}
  @_5::Union{Nothing, Tuple{Int64, Int64}}
  i::Int64
  x@_7::Int64

Body::Int64
1 ─       (x@_7 = x@_2)
│   %2  = Main.eachindex(y)::Base.OneTo{Int64}
│         (@_5 = Base.iterate(%2))
│   %4  = (@_5 === nothing)::Bool
│   %5  = Base.not_int(%4)::Bool
└──       goto #4 if not %5
2 ┄ %7  = @_5::Tuple{Int64, Int64}::Tuple{Int64, Int64}
│         (i = Core.getfield(%7, 1))
│   %9  = Core.getfield(%7, 2)::Int64
│   %10 = Base.getindex(y, i)::Int64
│   %11 = Base.getindex(z, x@_7)::Int64
│   %12 = (%10 - %11)::Int64
│         Base.setindex!(y, %12, i)
│         (@_5 = Base.iterate(%2, %9))
│   %15 = (@_5 === nothing)::Bool
│   %16 = Base.not_int(%15)::Bool
└──       goto #4 if not %16
3 ─       goto #2
4 ┄       (x@_7 = x@_7 + 1)
└──       return x@_7
</code></pre></div>
<p dir="auto">same function but with the loop threaded.  <code class="notranslate">x</code> is now unstable.  i've marked the red bits with ###:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="julia&gt; function foo(x,y,z)
         Threads.@threads for i in eachindex(y)
           y[i] -= z[x]
         end
         x += 1
         return x
       end
foo (generic function with 1 method)

julia&gt; @code_warntype foo(1,[1,2,3],[4,5,6])
Variables
  #self#::Core.Const(foo)
  x@_2::Int64
  y::Vector{Int64}
  z::Vector{Int64}
  threadsfor_fun::var&quot;#4#threadsfor_fun#1&quot;{Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}}
  range::Base.OneTo{Int64}
  x@_7::Union{}
  x@_8::Union{}
  x@_9::Union{Int64, Core.Box}                   ###
  @_10::Bool

Body::Any                                                      ###
1 ──       (x@_9 = x@_2)
│          (x@_9 = Core.Box(x@_9::Int64))
│    %3  = Main.eachindex(y)::Base.OneTo{Int64}
│          (range = %3)
│    %5  = Main.:(var&quot;#4#threadsfor_fun#1&quot;)::Core.Const(var&quot;#4#threadsfor_fun#1&quot;)
│    %6  = Core.typeof(y)::Core.Const(Vector{Int64})
│    %7  = Core.typeof(z)::Core.Const(Vector{Int64})
│    %8  = Core.typeof(range)::Core.Const(Base.OneTo{Int64})
│    %9  = Core.apply_type(%5, %6, %7, %8)::Core.Const(var&quot;#4#threadsfor_fun#1&quot;{Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}})
│    %10 = x@_9::Core.Box::Core.Box                                         ###
│          (threadsfor_fun = %new(%9, %10, y, z, range))
│    %12 = Base.Threads.threadid()::Int64
│    %13 = (%12 != 1)::Bool
└───       goto #3 if not %13
2 ──       (@_10 = %13)
└───       goto #4
3 ── %17 = $(Expr(:foreigncall, :(:jl_in_threaded_region), Int32, svec(), 0, :(:ccall)))::Int32
└───       (@_10 = %17 != 0)
4 ┄─       goto #6 if not @_10
5 ── %20 = Base.invokelatest::Core.Const(Base.invokelatest)
│    %21 = threadsfor_fun::var&quot;#4#threadsfor_fun#1&quot;{Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}}
│          (%20)(%21, true)
└───       goto #7
6 ──       Base.Threads.threading_run(threadsfor_fun)
7 ┄─       Base.Threads.nothing
│    %26 = Core.isdefined(x@_9::Core.Box, :contents)::Bool
└───       goto #9 if not %26
8 ──       goto #10
9 ──       Core.NewvarNode(:(x@_7))
└───       x@_7
10 ┄ %31 = Core.getfield(x@_9::Core.Box, :contents)::Any                    ###
│    %32 = (%31 + 1)::Any                                                 ###
│          Core.setfield!(x@_9::Core.Box, :contents, %32)
│    %34 = Core.isdefined(x@_9::Core.Box, :contents)::Bool
└───       goto #12 if not %34
11 ─       goto #13
12 ─       Core.NewvarNode(:(x@_8))
└───       x@_8
13 ┄ %39 = Core.getfield(x@_9::Core.Box, :contents)::Any                   ###
└───       return %39

julia&gt;"><pre class="notranslate"><code class="notranslate">julia&gt; function foo(x,y,z)
         Threads.@threads for i in eachindex(y)
           y[i] -= z[x]
         end
         x += 1
         return x
       end
foo (generic function with 1 method)

julia&gt; @code_warntype foo(1,[1,2,3],[4,5,6])
Variables
  #self#::Core.Const(foo)
  x@_2::Int64
  y::Vector{Int64}
  z::Vector{Int64}
  threadsfor_fun::var"#4#threadsfor_fun#1"{Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}}
  range::Base.OneTo{Int64}
  x@_7::Union{}
  x@_8::Union{}
  x@_9::Union{Int64, Core.Box}                   ###
  @_10::Bool

Body::Any                                                      ###
1 ──       (x@_9 = x@_2)
│          (x@_9 = Core.Box(x@_9::Int64))
│    %3  = Main.eachindex(y)::Base.OneTo{Int64}
│          (range = %3)
│    %5  = Main.:(var"#4#threadsfor_fun#1")::Core.Const(var"#4#threadsfor_fun#1")
│    %6  = Core.typeof(y)::Core.Const(Vector{Int64})
│    %7  = Core.typeof(z)::Core.Const(Vector{Int64})
│    %8  = Core.typeof(range)::Core.Const(Base.OneTo{Int64})
│    %9  = Core.apply_type(%5, %6, %7, %8)::Core.Const(var"#4#threadsfor_fun#1"{Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}})
│    %10 = x@_9::Core.Box::Core.Box                                         ###
│          (threadsfor_fun = %new(%9, %10, y, z, range))
│    %12 = Base.Threads.threadid()::Int64
│    %13 = (%12 != 1)::Bool
└───       goto #3 if not %13
2 ──       (@_10 = %13)
└───       goto #4
3 ── %17 = $(Expr(:foreigncall, :(:jl_in_threaded_region), Int32, svec(), 0, :(:ccall)))::Int32
└───       (@_10 = %17 != 0)
4 ┄─       goto #6 if not @_10
5 ── %20 = Base.invokelatest::Core.Const(Base.invokelatest)
│    %21 = threadsfor_fun::var"#4#threadsfor_fun#1"{Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}}
│          (%20)(%21, true)
└───       goto #7
6 ──       Base.Threads.threading_run(threadsfor_fun)
7 ┄─       Base.Threads.nothing
│    %26 = Core.isdefined(x@_9::Core.Box, :contents)::Bool
└───       goto #9 if not %26
8 ──       goto #10
9 ──       Core.NewvarNode(:(x@_7))
└───       x@_7
10 ┄ %31 = Core.getfield(x@_9::Core.Box, :contents)::Any                    ###
│    %32 = (%31 + 1)::Any                                                 ###
│          Core.setfield!(x@_9::Core.Box, :contents, %32)
│    %34 = Core.isdefined(x@_9::Core.Box, :contents)::Bool
└───       goto #12 if not %34
11 ─       goto #13
12 ─       Core.NewvarNode(:(x@_8))
└───       x@_8
13 ┄ %39 = Core.getfield(x@_9::Core.Box, :contents)::Any                   ###
└───       return %39

julia&gt;
</code></pre></div>
<p dir="auto">the workaround is to not mutate <code class="notranslate">x</code>:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="julia&gt; function foo(x,y,z)
         Threads.@threads for i in eachindex(y)
           y[i] -= z[x]
         end
       end
foo (generic function with 1 method)

julia&gt; @code_warntype foo(1,[1,2,3],[4,5,6])
Variables
  #self#::Core.Const(foo)
  x::Int64
  y::Vector{Int64}
  z::Vector{Int64}
  threadsfor_fun::var&quot;#25#threadsfor_fun#2&quot;{Int64, Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}}
  range::Base.OneTo{Int64}
  @_7::Bool

Body::Nothing
1 ─ %1  = Main.eachindex(y)::Base.OneTo{Int64}
│         (range = %1)
│   %3  = Main.:(var&quot;#25#threadsfor_fun#2&quot;)::Core.Const(var&quot;#25#threadsfor_fun#2&quot;)
│   %4  = Core.typeof(x)::Core.Const(Int64)
│   %5  = Core.typeof(y)::Core.Const(Vector{Int64})
│   %6  = Core.typeof(z)::Core.Const(Vector{Int64})
│   %7  = Core.typeof(range)::Core.Const(Base.OneTo{Int64})
│   %8  = Core.apply_type(%3, %4, %5, %6, %7)::Core.Const(var&quot;#25#threadsfor_fun#2&quot;{Int64, Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}})
│         (threadsfor_fun = %new(%8, x, y, z, range))
│   %10 = Base.Threads.threadid()::Int64
│   %11 = (%10 != 1)::Bool
└──       goto #3 if not %11
2 ─       (@_7 = %11)
└──       goto #4
3 ─ %15 = $(Expr(:foreigncall, :(:jl_in_threaded_region), Int32, svec(), 0, :(:ccall)))::Int32
└──       (@_7 = %15 != 0)
4 ┄       goto #6 if not @_7
5 ─ %18 = Base.invokelatest::Core.Const(Base.invokelatest)
│   %19 = threadsfor_fun::var&quot;#25#threadsfor_fun#2&quot;{Int64, Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}}
│         (%18)(%19, true)
└──       goto #7
6 ─       Base.Threads.threading_run(threadsfor_fun)
7 ┄ %23 = Base.Threads.nothing::Core.Const(nothing)
└──       return %23"><pre class="notranslate"><code class="notranslate">julia&gt; function foo(x,y,z)
         Threads.@threads for i in eachindex(y)
           y[i] -= z[x]
         end
       end
foo (generic function with 1 method)

julia&gt; @code_warntype foo(1,[1,2,3],[4,5,6])
Variables
  #self#::Core.Const(foo)
  x::Int64
  y::Vector{Int64}
  z::Vector{Int64}
  threadsfor_fun::var"#25#threadsfor_fun#2"{Int64, Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}}
  range::Base.OneTo{Int64}
  @_7::Bool

Body::Nothing
1 ─ %1  = Main.eachindex(y)::Base.OneTo{Int64}
│         (range = %1)
│   %3  = Main.:(var"#25#threadsfor_fun#2")::Core.Const(var"#25#threadsfor_fun#2")
│   %4  = Core.typeof(x)::Core.Const(Int64)
│   %5  = Core.typeof(y)::Core.Const(Vector{Int64})
│   %6  = Core.typeof(z)::Core.Const(Vector{Int64})
│   %7  = Core.typeof(range)::Core.Const(Base.OneTo{Int64})
│   %8  = Core.apply_type(%3, %4, %5, %6, %7)::Core.Const(var"#25#threadsfor_fun#2"{Int64, Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}})
│         (threadsfor_fun = %new(%8, x, y, z, range))
│   %10 = Base.Threads.threadid()::Int64
│   %11 = (%10 != 1)::Bool
└──       goto #3 if not %11
2 ─       (@_7 = %11)
└──       goto #4
3 ─ %15 = $(Expr(:foreigncall, :(:jl_in_threaded_region), Int32, svec(), 0, :(:ccall)))::Int32
└──       (@_7 = %15 != 0)
4 ┄       goto #6 if not @_7
5 ─ %18 = Base.invokelatest::Core.Const(Base.invokelatest)
│   %19 = threadsfor_fun::var"#25#threadsfor_fun#2"{Int64, Vector{Int64}, Vector{Int64}, Base.OneTo{Int64}}
│         (%18)(%19, true)
└──       goto #7
6 ─       Base.Threads.threading_run(threadsfor_fun)
7 ┄ %23 = Base.Threads.nothing::Core.Const(nothing)
└──       return %23
</code></pre></div>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="using Images: realtype

function ifi{T&lt;:Real,K,N}(img::AbstractArray{T,N}, kern::AbstractArray{K,N}, border::AbstractString, value)
    if border == &quot;circular&quot; &amp;&amp; size(img) == size(kern)
        out = real(ifftshift(ifft(fft(img).*fft(kern))))
    elseif border != &quot;inner&quot;
        prepad  = [div(size(kern,i)-1, 2) for i = 1:N]
        postpad = [div(size(kern,i),   2) for i = 1:N]
        fullpad = [nextprod([2,3], size(img,i) + prepad[i] + postpad[i]) - size(img, i) - prepad[i] for i = 1:N]
        A = padarray(img, prepad, fullpad, border, convert(T, value))
        krn = zeros(typeof(one(T)*one(K)), size(A))
        indexesK = ntuple(d-&gt;[size(krn,d)-prepad[d]+1:size(krn,d);1:size(kern,d)-prepad[d]], N)::NTuple{N,Vector{Int}}
        AF = ifft(fft(A).*fft(krn))
        out = Array(realtype(eltype(AF)), size(img))
    end
    out
end"><pre class="notranslate"><span class="pl-k">using</span> Images<span class="pl-k">:</span> realtype

<span class="pl-k">function</span> <span class="pl-en">ifi</span><span class="pl-c1">{T&lt;:Real,K,N}</span>(img<span class="pl-k">::</span><span class="pl-c1">AbstractArray{T,N}</span>, kern<span class="pl-k">::</span><span class="pl-c1">AbstractArray{K,N}</span>, border<span class="pl-k">::</span><span class="pl-c1">AbstractString</span>, value)
    <span class="pl-k">if</span> border <span class="pl-k">==</span> <span class="pl-s"><span class="pl-pds">"</span>circular<span class="pl-pds">"</span></span> <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">size</span>(img) <span class="pl-k">==</span> <span class="pl-c1">size</span>(kern)
        out <span class="pl-k">=</span> <span class="pl-c1">real</span>(<span class="pl-c1">ifftshift</span>(<span class="pl-c1">ifft</span>(<span class="pl-c1">fft</span>(img)<span class="pl-k">.*</span><span class="pl-c1">fft</span>(kern))))
    <span class="pl-k">elseif</span> border <span class="pl-k">!=</span> <span class="pl-s"><span class="pl-pds">"</span>inner<span class="pl-pds">"</span></span>
        prepad  <span class="pl-k">=</span> [<span class="pl-c1">div</span>(<span class="pl-c1">size</span>(kern,i)<span class="pl-k">-</span><span class="pl-c1">1</span>, <span class="pl-c1">2</span>) <span class="pl-k">for</span> i <span class="pl-k">=</span> <span class="pl-c1">1</span><span class="pl-k">:</span>N]
        postpad <span class="pl-k">=</span> [<span class="pl-c1">div</span>(<span class="pl-c1">size</span>(kern,i),   <span class="pl-c1">2</span>) <span class="pl-k">for</span> i <span class="pl-k">=</span> <span class="pl-c1">1</span><span class="pl-k">:</span>N]
        fullpad <span class="pl-k">=</span> [<span class="pl-c1">nextprod</span>([<span class="pl-c1">2</span>,<span class="pl-c1">3</span>], <span class="pl-c1">size</span>(img,i) <span class="pl-k">+</span> prepad[i] <span class="pl-k">+</span> postpad[i]) <span class="pl-k">-</span> <span class="pl-c1">size</span>(img, i) <span class="pl-k">-</span> prepad[i] <span class="pl-k">for</span> i <span class="pl-k">=</span> <span class="pl-c1">1</span><span class="pl-k">:</span>N]
        A <span class="pl-k">=</span> <span class="pl-c1">padarray</span>(img, prepad, fullpad, border, <span class="pl-c1">convert</span>(T, value))
        krn <span class="pl-k">=</span> <span class="pl-c1">zeros</span>(<span class="pl-c1">typeof</span>(<span class="pl-c1">one</span>(T)<span class="pl-k">*</span><span class="pl-c1">one</span>(K)), <span class="pl-c1">size</span>(A))
        indexesK <span class="pl-k">=</span> <span class="pl-c1">ntuple</span>(d<span class="pl-k">-&gt;</span>[<span class="pl-c1">size</span>(krn,d)<span class="pl-k">-</span>prepad[d]<span class="pl-k">+</span><span class="pl-c1">1</span><span class="pl-k">:</span><span class="pl-c1">size</span>(krn,d);<span class="pl-c1">1</span><span class="pl-k">:</span><span class="pl-c1">size</span>(kern,d)<span class="pl-k">-</span>prepad[d]], N)<span class="pl-k">::</span><span class="pl-c1">NTuple{N,Vector{Int}}</span>
        AF <span class="pl-k">=</span> <span class="pl-c1">ifft</span>(<span class="pl-c1">fft</span>(A)<span class="pl-k">.*</span><span class="pl-c1">fft</span>(krn))
        out <span class="pl-k">=</span> <span class="pl-c1">Array</span>(<span class="pl-c1">realtype</span>(<span class="pl-c1">eltype</span>(AF)), <span class="pl-c1">size</span>(img))
    <span class="pl-k">end</span>
    out
<span class="pl-k">end</span></pre></div>
<p dir="auto">Test:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="julia&gt; @code_warntype ifi(rand(3,3), rand(3,3), &quot;replicate&quot;, 0)
Variables:
  #self#::#ifi
  img::Array{Float64,2}
  kern::Array{Float64,2}
  border::ASCIIString
  value::Int64
  prepad::Box
..."><pre class="notranslate">julia<span class="pl-k">&gt;</span> <span class="pl-c1">@code_warntype</span> <span class="pl-c1">ifi</span>(<span class="pl-c1">rand</span>(<span class="pl-c1">3</span>,<span class="pl-c1">3</span>), <span class="pl-c1">rand</span>(<span class="pl-c1">3</span>,<span class="pl-c1">3</span>), <span class="pl-s"><span class="pl-pds">"</span>replicate<span class="pl-pds">"</span></span>, <span class="pl-c1">0</span>)
Variables<span class="pl-k">:</span>
  <span class="pl-c"><span class="pl-c">#</span>self#::#ifi</span>
  img<span class="pl-k">::</span><span class="pl-c1">Array{Float64,2}</span>
  kern<span class="pl-k">::</span><span class="pl-c1">Array{Float64,2}</span>
  border<span class="pl-k">::</span><span class="pl-c1">ASCIIString</span>
  value<span class="pl-k">::</span><span class="pl-c1">Int64</span>
  prepad<span class="pl-k">::</span><span class="pl-c1">Box</span>
<span class="pl-k">...</span></pre></div>
<p dir="auto">Now comment out the <code class="notranslate">indexesK = ...</code> line (the output of which is not used at all). Suddenly <code class="notranslate">prepad</code> is inferred as <code class="notranslate">Array{Int, 1}</code>.</p>