diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index 12cd0cd582f8c..016e038afd25a 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -174,7 +174,7 @@ function walk_to_defs(compact::IncrementalCompact, @nospecialize(defssa), @nospe found_def = false ## Track which PhiNodes, SSAValue intermediaries ## we forwarded through. - visited = IdSet{Any}() + visited = IdDict{Any, Any}() worklist_defs = Any[] worklist_constraints = Any[] leaves = Any[] @@ -183,7 +183,7 @@ function walk_to_defs(compact::IncrementalCompact, @nospecialize(defssa), @nospe while !isempty(worklist_defs) defssa = pop!(worklist_defs) typeconstraint = pop!(worklist_constraints) - push!(visited, defssa) + visited[defssa] = typeconstraint def = compact[defssa] if isa(def, PhiNode) push!(visited_phinodes, defssa) @@ -207,9 +207,15 @@ function walk_to_defs(compact::IncrementalCompact, @nospecialize(defssa), @nospe if isa(val, AnySSAValue) new_def, new_constraint = simple_walk_constraint(compact, val, typeconstraint) if isa(new_def, AnySSAValue) - if !(new_def in visited) + if !haskey(visited, new_def) push!(worklist_defs, new_def) push!(worklist_constraints, new_constraint) + elseif !(new_constraint <: visited[new_def]) + # We have reached the same definition via a different + # path, with a different type constraint. We may have + # to redo some work here with the wider typeconstraint + push!(worklist_defs, new_def) + push!(worklist_constraints, tmerge(new_constraint, visited[new_def])) end continue end diff --git a/test/compiler/ssair.jl b/test/compiler/ssair.jl index 523b338d4452d..6a40e2d4a566c 100644 --- a/test/compiler/ssair.jl +++ b/test/compiler/ssair.jl @@ -40,3 +40,23 @@ let Meta.isexpr(ex, :meta) end end + +# Issue #32579 - Optimizer bug involving type constraints +function f32579(x::Int, b::Bool) + if b + x = nothing + end + if isa(x, Int) + y = x + else + y = x + end + if isa(y, Nothing) + z = y + else + z = y + end + return z === nothing +end +@test f32579(0, true) === true +@test f32579(0, false) === false