Skip to content

Commit

Permalink
inference: enhance memoryop tfunc robustness (JuliaLang#52185)
Browse files Browse the repository at this point in the history
Make them able to handle potential `Vararg` argument. Also adds plenty
of tests.
  • Loading branch information
aviatesk committed Nov 16, 2023
1 parent 4689850 commit 7f18f76
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
11 changes: 6 additions & 5 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1992,7 +1992,7 @@ end
add_tfunc(memoryref_isassigned, 3, 3, memoryref_isassigned_tfunc, 20)

@nospecs function memoryref_tfunc(𝕃::AbstractLattice, mem)
a = widenconst(mem)
a = widenconst(unwrapva(mem))
if !has_free_typevars(a)
unw = unwrap_unionall(a)
if isa(unw, DataType) && unw.name === GenericMemory.body.body.body.name
Expand All @@ -2006,7 +2006,10 @@ add_tfunc(memoryref_isassigned, 3, 3, memoryref_isassigned_tfunc, 20)
return GenericMemoryRef
end
@nospecs function memoryref_tfunc(𝕃::AbstractLattice, ref, idx)
memoryref_tfunc(𝕃, ref, idx, Const(true))
if isvarargtype(idx)
idx = unwrapva(idx)
end
return memoryref_tfunc(𝕃, ref, idx, Const(true))
end
@nospecs function memoryref_tfunc(𝕃::AbstractLattice, ref, idx, boundscheck)
memoryref_builtin_common_errorcheck(ref, Const(:not_atomic), boundscheck) || return Bottom
Expand All @@ -2021,12 +2024,10 @@ add_tfunc(memoryref, 1, 3, memoryref_tfunc, 1)
end
add_tfunc(memoryrefoffset, 1, 1, memoryrefoffset_tfunc, 5)



@nospecs function memoryref_builtin_common_errorcheck(mem, order, boundscheck)
hasintersect(widenconst(mem), GenericMemoryRef) || return false
hasintersect(widenconst(order), Symbol) || return false
hasintersect(widenconst(boundscheck), Bool) || return false
hasintersect(widenconst(unwrapva(boundscheck)), Bool) || return false
return true
end

Expand Down
31 changes: 30 additions & 1 deletion test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1580,15 +1580,21 @@ end
f_typeof_tfunc(x) = typeof(x)
@test Base.return_types(f_typeof_tfunc, (Union{<:T, Int} where T<:Complex,)) == Any[Union{Type{Int}, Type{Complex{T}} where T<:Real}]

# memoryref_tfunc, memoryrefget_tfunc, memoryrefset!_tfunc
# memoryref_tfunc, memoryrefget_tfunc, memoryrefset!_tfunc, memoryref_isassigned, memoryrefoffset_tfunc
let memoryref_tfunc(@nospecialize xs...) = Core.Compiler.memoryref_tfunc(Core.Compiler.fallback_lattice, xs...)
memoryrefget_tfunc(@nospecialize xs...) = Core.Compiler.memoryrefget_tfunc(Core.Compiler.fallback_lattice, xs...)
memoryref_isassigned_tfunc(@nospecialize xs...) = Core.Compiler.memoryref_isassigned_tfunc(Core.Compiler.fallback_lattice, xs...)
memoryrefset!_tfunc(@nospecialize xs...) = Core.Compiler.memoryrefset!_tfunc(Core.Compiler.fallback_lattice, xs...)
memoryrefoffset_tfunc(@nospecialize xs...) = Core.Compiler.memoryrefoffset_tfunc(Core.Compiler.fallback_lattice, xs...)
interp = Core.Compiler.NativeInterpreter()
builtin_tfunction(@nospecialize xs...) = Core.Compiler.builtin_tfunction(interp, xs..., nothing)
@test memoryref_tfunc(Memory{Int}) == MemoryRef{Int}
@test memoryref_tfunc(Memory{Integer}) == MemoryRef{Integer}
@test memoryref_tfunc(MemoryRef{Int}, Int) == MemoryRef{Int}
@test memoryref_tfunc(MemoryRef{Int}, Vararg{Int}) == MemoryRef{Int}
@test memoryref_tfunc(MemoryRef{Int}, Int, Symbol) == Union{}
@test memoryref_tfunc(MemoryRef{Int}, Int, Bool) == MemoryRef{Int}
@test memoryref_tfunc(MemoryRef{Int}, Int, Vararg{Bool}) == MemoryRef{Int}
@test memoryref_tfunc(Memory{Int}, Int) == Union{}
@test memoryref_tfunc(Any, Any, Any) == Any # also probably could be GenericMemoryRef
@test memoryref_tfunc(Any, Any) == Any # also probably could be GenericMemoryRef
Expand All @@ -1603,6 +1609,20 @@ let memoryref_tfunc(@nospecialize xs...) = Core.Compiler.memoryref_tfunc(Core.Co
@test memoryrefget_tfunc(MemoryRef{Int}, String, Bool) === Union{}
@test memoryrefget_tfunc(MemoryRef{Int}, Symbol, String) === Union{}
@test memoryrefget_tfunc(Any, Any, Any) === Any
@test builtin_tfunction(Core.memoryrefget, Any[MemoryRef{Int}, Vararg{Any}]) == Int
@test builtin_tfunction(Core.memoryrefget, Any[MemoryRef{Int}, Symbol, Bool, Vararg{Bool}]) == Int
@test memoryref_isassigned_tfunc(MemoryRef{Any}, Symbol, Bool) === Bool
@test memoryref_isassigned_tfunc(MemoryRef{Any}, Any, Any) === Bool
@test memoryref_isassigned_tfunc(MemoryRef{<:Integer}, Symbol, Bool) === Bool
@test memoryref_isassigned_tfunc(GenericMemoryRef, Symbol, Bool) === Bool
@test memoryref_isassigned_tfunc(GenericMemoryRef{:not_atomic}, Symbol, Bool) === Bool
@test memoryref_isassigned_tfunc(Vector{Int}, Symbol, Bool) === Union{}
@test memoryref_isassigned_tfunc(String, Symbol, Bool) === Union{}
@test memoryref_isassigned_tfunc(MemoryRef{Int}, String, Bool) === Union{}
@test memoryref_isassigned_tfunc(MemoryRef{Int}, Symbol, String) === Union{}
@test memoryref_isassigned_tfunc(Any, Any, Any) === Bool
@test builtin_tfunction(Core.memoryref_isassigned, Any[MemoryRef{Int}, Vararg{Any}]) == Bool
@test builtin_tfunction(Core.memoryref_isassigned, Any[MemoryRef{Int}, Symbol, Bool, Vararg{Bool}]) == Bool
@test memoryrefset!_tfunc(MemoryRef{Int}, Int, Symbol, Bool) === MemoryRef{Int}
let ua = MemoryRef{<:Integer}
@test memoryrefset!_tfunc(ua, Int, Symbol, Bool) === ua
Expand All @@ -1617,6 +1637,15 @@ let memoryref_tfunc(@nospecialize xs...) = Core.Compiler.memoryref_tfunc(Core.Co
@test memoryrefset!_tfunc(GenericMemoryRef{:not_atomic}, Any, Any, Any) === GenericMemoryRef{:not_atomic}
@test memoryrefset!_tfunc(GenericMemoryRef, Any, Any, Any) === GenericMemoryRef
@test memoryrefset!_tfunc(Any, Any, Any, Any) === Any # also probably could be GenericMemoryRef
@test builtin_tfunction(Core.memoryrefset!, Any[MemoryRef{Int}, Vararg{Any}]) == MemoryRef{Int}
@test builtin_tfunction(Core.memoryrefset!, Any[MemoryRef{Int}, Vararg{Symbol}]) == Union{}
@test builtin_tfunction(Core.memoryrefset!, Any[MemoryRef{Int}, Any, Symbol, Vararg{Bool}]) == MemoryRef{Int}
@test builtin_tfunction(Core.memoryrefset!, Any[MemoryRef{Int}, Any, Symbol, Bool, Vararg{Any}]) == MemoryRef{Int}
@test memoryrefoffset_tfunc(MemoryRef) == memoryrefoffset_tfunc(GenericMemoryRef) == Int
@test memoryrefoffset_tfunc(Memory) == memoryrefoffset_tfunc(GenericMemory) == Union{}
@test builtin_tfunction(Core.memoryrefoffset, Any[Vararg{MemoryRef}]) == Int
@test builtin_tfunction(Core.memoryrefoffset, Any[Vararg{Any}]) == Int
@test builtin_tfunction(Core.memoryrefoffset, Any[Vararg{Memory}]) == Union{}
end

let tuple_tfunc(@nospecialize xs...) =
Expand Down

0 comments on commit 7f18f76

Please sign in to comment.