diff --git a/base/compiler/ssair/ir.jl b/base/compiler/ssair/ir.jl index f4d7d468feba1..769e373bac286 100644 --- a/base/compiler/ssair/ir.jl +++ b/base/compiler/ssair/ir.jl @@ -950,6 +950,8 @@ end __set_check_ssa_counts(onoff::Bool) = __check_ssa_counts__[] = onoff const __check_ssa_counts__ = fill(false) +should_check_ssa_counts() = __check_ssa_counts__[] + function _oracle_check(compact::IncrementalCompact) observed_used_ssas = Core.Compiler.find_ssavalue_uses1(compact) for i = 1:length(observed_used_ssas) @@ -1683,7 +1685,7 @@ end function complete(compact::IncrementalCompact) result_bbs = resize!(compact.result_bbs, compact.active_result_bb-1) cfg = CFG(result_bbs, Int[first(result_bbs[i].stmts) for i in 2:length(result_bbs)]) - if __check_ssa_counts__[] + if should_check_ssa_counts() oracle_check(compact) end diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index 1d9417fb7ca7d..cf2d87f3bfdb2 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -1511,6 +1511,30 @@ function is_union_phi(compact::IncrementalCompact, idx::Int) return is_some_union(inst[:type]) end +function kill_phi!(compact::IncrementalCompact, phi_uses::Vector{Int}, + to_drop::Union{Vector{Int}, UnitRange{Int}}, + ssa::SSAValue, phi::PhiNode, delete_inst::Bool = false) + for d in to_drop + if isassigned(phi.values, d) + val = phi.values[d] + if !delete_inst + # Deleting the inst will update compact's use count, so + # don't do it here. + kill_current_use(compact, val) + end + if isa(val, SSAValue) + phi_uses[val.id] -= 1 + end + end + end + if delete_inst + compact[ssa] = nothing + elseif !isempty(to_drop) + deleteat!(phi.values, to_drop) + deleteat!(phi.edges, to_drop) + end +end + """ adce_pass!(ir::IRCode) -> newir::IRCode @@ -1596,7 +1620,8 @@ function adce_pass!(ir::IRCode) phi = unionphi[1] t = unionphi[2] if t === Union{} - compact[SSAValue(phi)] = nothing + stmt = compact[SSAValue(phi)][:inst]::PhiNode + kill_phi!(compact, phi_uses, 1:length(stmt.values), SSAValue(phi), stmt, true) continue elseif t === Any continue @@ -1617,12 +1642,7 @@ function adce_pass!(ir::IRCode) end end compact.result[phi][:type] = t - isempty(to_drop) && continue - for d in to_drop - isassigned(stmt.values, d) && kill_current_use(compact, stmt.values[d]) - end - deleteat!(stmt.values, to_drop) - deleteat!(stmt.edges, to_drop) + kill_phi!(compact, phi_uses, to_drop, SSAValue(phi), stmt, false) end # Perform simple DCE for unused values extra_worklist = Int[] diff --git a/test/compiler/irpasses.jl b/test/compiler/irpasses.jl index a85a8a80f288f..ec26cab55da14 100644 --- a/test/compiler/irpasses.jl +++ b/test/compiler/irpasses.jl @@ -1092,3 +1092,13 @@ let src = code_typed1(foo_defined_last_iter, Tuple{Int}) end end end + +# Issue #47180, incorrect phi counts in CmdRedirect +function a47180(b; stdout ) + c = setenv(b, b.env) + if true + c = pipeline(c, stdout) + end + c +end +@test isa(a47180(``; stdout), Base.AbstractCmd)