Skip to content

Commit 7c31c41

Browse files
authored
Merge pull request #22779 from JuliaLang/jn/isa_tfunc_bugfix
fix isa tfunc for type kinds
2 parents d1d1caa + cd959a2 commit 7c31c41

File tree

2 files changed

+53
-16
lines changed

2 files changed

+53
-16
lines changed

base/inference.jl

+19-15
Original file line numberDiff line numberDiff line change
@@ -378,19 +378,21 @@ isType(t::ANY) = isa(t, DataType) && (t::DataType).name === _Type_name
378378
# true if Type is inlineable as constant (is a singleton)
379379
isconstType(t::ANY) = isType(t) && (isleaftype(t.parameters[1]) || t.parameters[1] === Union{})
380380

381+
iskindtype(t::ANY) = (t === DataType || t === UnionAll || t === Union || t === typeof(Bottom))
382+
381383
const IInf = typemax(Int) # integer infinity
382-
const n_ifunc = reinterpret(Int32,arraylen)+1
383-
const t_ifunc = Array{Tuple{Int,Int,Any},1}(n_ifunc)
384-
const t_ifunc_cost = Array{Int,1}(n_ifunc)
385-
const t_ffunc_key = Array{Function,1}(0)
386-
const t_ffunc_val = Array{Tuple{Int,Int,Any},1}(0)
387-
const t_ffunc_cost = Array{Int,1}(0)
384+
const n_ifunc = reinterpret(Int32, arraylen) + 1
385+
const t_ifunc = Array{Tuple{Int, Int, Any}, 1}(n_ifunc)
386+
const t_ifunc_cost = Array{Int, 1}(n_ifunc)
387+
const t_ffunc_key = Array{Any, 1}(0)
388+
const t_ffunc_val = Array{Tuple{Int, Int, Any}, 1}(0)
389+
const t_ffunc_cost = Array{Int, 1}(0)
388390
function add_tfunc(f::IntrinsicFunction, minarg::Int, maxarg::Int, tfunc::ANY, cost::Int)
389-
idx = reinterpret(Int32,f)+1
391+
idx = reinterpret(Int32, f) + 1
390392
t_ifunc[idx] = (minarg, maxarg, tfunc)
391393
t_ifunc_cost[idx] = cost
392394
end
393-
function add_tfunc(f::Function, minarg::Int, maxarg::Int, tfunc::ANY, cost::Int)
395+
function add_tfunc(#=@nospecialize::Builtin=# f::Function, minarg::Int, maxarg::Int, tfunc::ANY, cost::Int)
394396
push!(t_ffunc_key, f)
395397
push!(t_ffunc_val, (minarg, maxarg, tfunc))
396398
push!(t_ffunc_cost, cost)
@@ -711,7 +713,7 @@ add_tfunc(isa, 2, 2,
711713
if t !== Any && !has_free_typevars(t)
712714
if v t
713715
return Const(true)
714-
elseif isa(v, Const) || isa(v, Conditional) || isleaftype(v)
716+
elseif isa(v, Const) || isa(v, Conditional) || (isleaftype(v) && !iskindtype(v))
715717
return Const(false)
716718
end
717719
end
@@ -1501,20 +1503,20 @@ function builtin_tfunction(f::ANY, argtypes::Array{Any,1},
15011503
end
15021504
if isa(f, IntrinsicFunction)
15031505
iidx = Int(reinterpret(Int32, f::IntrinsicFunction)) + 1
1504-
if !isassigned(t_ifunc, iidx)
1505-
# unknown/unhandled intrinsic (most fall in this category since most return an unboxed value)
1506+
if iidx < 0 || iidx > length(t_ifunc)
1507+
# invalid intrinsic
15061508
return Any
15071509
end
15081510
tf = t_ifunc[iidx]
15091511
else
1510-
fidx = findfirst(t_ffunc_key, f::Function)
1512+
fidx = findfirst(t_ffunc_key, f)
15111513
if fidx == 0
1512-
# unknown/unhandled builtin or anonymous function
1514+
# unknown/unhandled builtin function
15131515
return Any
15141516
end
15151517
tf = t_ffunc_val[fidx]
15161518
end
1517-
tf = tf::Tuple{Real, Real, Any}
1519+
tf = tf::Tuple{Int, Int, Any}
15181520
if !(tf[1] <= length(argtypes) <= tf[2])
15191521
# wrong # of args
15201522
return Bottom
@@ -4640,7 +4642,7 @@ function statement_cost(ex::Expr, src::CodeInfo, mod::Module, params::InferenceP
46404642
elseif f == Main.Core.arrayref
46414643
return plus_saturate(argcost, isknowntype(ex.typ) ? 4 : params.inline_nonleaf_penalty)
46424644
end
4643-
fidx = findfirst(t_ffunc_key, f::Function)
4645+
fidx = findfirst(t_ffunc_key, f)
46444646
if fidx == 0
46454647
# unknown/unhandled builtin or anonymous function
46464648
# Use the generic cost of a direct function call
@@ -5906,6 +5908,8 @@ let fs = Any[typeinf_ext, typeinf, typeinf_edge, occurs_outside_getfield, pure_e
59065908
if isassigned(t_ifunc, i)
59075909
x = t_ifunc[i]
59085910
push!(fs, x[3])
5911+
else
5912+
println(STDERR, "WARNING: tfunc missing for ", reinterpret(IntrinsicFunction, Int32(i)))
59095913
end
59105914
end
59115915
for f in fs

test/inference.jl

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

33
# tests for Core.Inference correctness and precision
4+
import Core.Inference: Const, Conditional,
45

56
# issue 9770
67
@noinline x9770() = false
@@ -877,7 +878,7 @@ let f(x) = isdefined(x, :NonExistentField) ? 1 : ""
877878
@test Base.return_types(f, (Complex64,)) == Any[String]
878879
@test Union{Int,String} <: Base.return_types(f, (AbstractArray,))[1]
879880
end
880-
import Core.Inference: Const, isdefined_tfunc,
881+
import Core.Inference: isdefined_tfunc
881882
@test isdefined_tfunc(Complex64, Const(())) === Union{}
882883
@test isdefined_tfunc(Complex64, Const(1)) === Const(true)
883884
@test isdefined_tfunc(Complex64, Const(2)) === Const(true)
@@ -1049,3 +1050,35 @@ end
10491050
@test find_core_sizeof_call(first(@code_typed sizeof_constvec()).code)
10501051
push!(constvec, 10)
10511052
@test @inferred(sizeof_constvec()) == sizeof(Int) * 4
1053+
1054+
let isa_tfunc = Core.Inference.t_ffunc_val[
1055+
findfirst(Core.Inference.t_ffunc_key, isa)][3]
1056+
@test isa_tfunc(Array, Const(AbstractArray)) === Const(true)
1057+
@test isa_tfunc(Array, Type{AbstractArray}) === Const(true)
1058+
@test isa_tfunc(Array, Type{AbstractArray{Int}}) == Bool
1059+
@test isa_tfunc(Array{Real}, Type{AbstractArray{Int}}) === Bool # could be improved
1060+
@test isa_tfunc(Array{Real, 2}, Const(AbstractArray{Real, 2})) === Const(true)
1061+
@test isa_tfunc(Array{Real, 2}, Const(AbstractArray{Int, 2})) === Const(false)
1062+
@test isa_tfunc(DataType, Int) === Bool # could be improved
1063+
@test isa_tfunc(DataType, Const(Type{Int})) === Bool
1064+
@test isa_tfunc(DataType, Const(Type{Array})) === Bool
1065+
@test isa_tfunc(UnionAll, Const(Type{Int})) === Bool # could be improved
1066+
@test isa_tfunc(UnionAll, Const(Type{Array})) === Bool
1067+
@test isa_tfunc(Union, Const(Union{Float32, Float64})) === Bool
1068+
@test isa_tfunc(Union, Type{Union}) === Const(true)
1069+
@test isa_tfunc(typeof(Union{}), Const(Int)) === Bool # any result is ok
1070+
@test isa_tfunc(typeof(Union{}), Const(Union{})) === Bool # could be improved
1071+
@test isa_tfunc(typeof(Union{}), typeof(Union{})) === Bool # could be improved
1072+
@test isa_tfunc(typeof(Union{}), Union{}) === Bool # could be improved
1073+
@test isa_tfunc(typeof(Union{}), Type{typeof(Union{})}) === Const(true)
1074+
@test isa_tfunc(typeof(Union{}), Const(typeof(Union{}))) === Const(true)
1075+
let c = Conditional(Core.SlotNumber(0), Const(Union{}), Const(Union{}))
1076+
@test isa_tfunc(c, Const(Bool)) === Const(true)
1077+
@test isa_tfunc(c, Type{Bool}) === Const(true)
1078+
@test isa_tfunc(c, Const(Real)) === Const(true)
1079+
@test isa_tfunc(c, Type{Real}) === Const(true)
1080+
@test isa_tfunc(c, Const(Signed)) === Const(false)
1081+
@test isa_tfunc(c, Type{Complex}) === Const(false)
1082+
@test isa_tfunc(c, Type{Complex{T}} where T) === Const(false)
1083+
end
1084+
end

0 commit comments

Comments
 (0)