Issue 1:
without threads it is fine:

julia> 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> @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

same function but with the loop threaded. x is now unstable. i've marked the red bits with ###:

julia> 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> @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>

the workaround is to not mutate x:

julia> 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> @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

Issue 2:
using Images: realtype

function ifi{T<:Real,K,N}(img::AbstractArray{T,N}, kern::AbstractArray{K,N}, border::AbstractString, value)
if border == "circular" && size(img) == size(kern)
out = real(ifftshift(ifft(fft(img).*fft(kern))))
elseif border != "inner"
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->[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

Test:

julia> @code_warntype ifi(rand(3,3), rand(3,3), "replicate", 0)
Variables:
#self#::#ifi
img::Array{Float64,2}
kern::Array{Float64,2}
border::ASCIIString
value::Int64
prepad::Box
...

Now comment out the indexesK = ... line (the output of which is not used at all). Suddenly prepad is inferred as Array{Int, 1}.