Skip to content

Commit 5739ff4

Browse files
vtjnashKristofferC
authored andcommitted
inference: fix lattice for unusual InterConditional return and Const Bool representations (#57080)
Fixes #54886 Rule introduced by 55cee67 (cherry picked from commit 4e13e0e)
1 parent cc7e93a commit 5739ff4

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3097,14 +3097,23 @@ function update_bestguess!(interp::AbstractInterpreter, frame::InferenceState,
30973097
slottypes = frame.slottypes
30983098
rt = widenreturn(rt, BestguessInfo(interp, bestguess, nargs, slottypes, currstate))
30993099
# narrow representation of bestguess slightly to prepare for tmerge with rt
3100-
if rt isa InterConditional && bestguess isa Const
3100+
if rt isa InterConditional && bestguess isa Const && bestguess.val isa Bool
31013101
slot_id = rt.slot
31023102
old_id_type = slottypes[slot_id]
31033103
if bestguess.val === true && rt.elsetype !== Bottom
31043104
bestguess = InterConditional(slot_id, old_id_type, Bottom)
31053105
elseif bestguess.val === false && rt.thentype !== Bottom
31063106
bestguess = InterConditional(slot_id, Bottom, old_id_type)
31073107
end
3108+
# or narrow representation of rt slightly to prepare for tmerge with bestguess
3109+
elseif bestguess isa InterConditional && rt isa Const && rt.val isa Bool
3110+
slot_id = bestguess.slot
3111+
old_id_type = widenconditional(slottypes[slot_id])
3112+
if rt.val === true && bestguess.elsetype !== Bottom
3113+
rt = InterConditional(slot_id, old_id_type, Bottom)
3114+
elseif rt.val === false && bestguess.thentype !== Bottom
3115+
rt = InterConditional(slot_id, Bottom, old_id_type)
3116+
end
31083117
end
31093118
# copy limitations to return value
31103119
if !isempty(frame.pclimitations)

base/compiler/typelattice.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,13 @@ end
427427
end
428428
a = Bool
429429
elseif isa(b, ConditionalT)
430+
if isa(a, Const) && isa(a.val, Bool)
431+
if (a.val === true && b.thentype === Any && b.elsetype === Bottom) ||
432+
(a.val === false && b.elsetype === Any && b.thentype === Bottom)
433+
# this Conditional contains distinctly no lattice information, and is simply an alternative representation of the Const Bool used for internal tracking purposes
434+
return true
435+
end
436+
end
430437
return false
431438
end
432439
return (widenlattice(lattice), a, b)

test/compiler/inference.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2744,6 +2744,26 @@ vacond(cnd, va...) = cnd ? va : 0
27442744
vacond(isa(x, Tuple{Int,Int}), x, x)
27452745
end |> only == Union{Int,Tuple{Any,Any}}
27462746

2747+
let A = Core.Const(true)
2748+
B = Core.InterConditional(2, Tuple, Union{})
2749+
C = Core.InterConditional(2, Any, Union{})
2750+
L = ipo_lattice(Compiler.NativeInterpreter())
2751+
@test !(L, A, B)
2752+
@test (L, B, A)
2753+
@test tmerge(L, A, B) == C
2754+
@test (L, A, C)
2755+
end
2756+
function tail_is_ntuple((@nospecialize t::Tuple))
2757+
if unknown
2758+
t isa Tuple
2759+
else
2760+
tail_is_ntuple(t)
2761+
end
2762+
end
2763+
tail_is_ntuple_val((@nospecialize t::Tuple)) = Val(tail_is_ntuple(t))
2764+
@test Base.return_types(tail_is_ntuple, (Tuple,)) |> only === Bool
2765+
@test Base.return_types(tail_is_ntuple_val, (Tuple,)) |> only === Val{true}
2766+
27472767
# https://github.com/JuliaLang/julia/issues/47435
27482768
is_closed_ex(e::InvalidStateException) = true
27492769
is_closed_ex(e) = false

0 commit comments

Comments
 (0)