diff --git a/base/compiler/ssair/ir.jl b/base/compiler/ssair/ir.jl index 045477e615b57..3325b9784996f 100644 --- a/base/compiler/ssair/ir.jl +++ b/base/compiler/ssair/ir.jl @@ -1359,7 +1359,7 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr (; result, ssa_rename, late_fixup, used_ssas, new_new_used_ssas) = compact (; cfg_transforms_enabled, fold_constant_branches, bb_rename_succ, bb_rename_pred, result_bbs) = compact.cfg_transform mark_refined! = Refiner(result.flag, result_idx) - already_inserted = (::Int, ssa::OldSSAValue)->ssa.id <= processed_idx + already_inserted_phi_arg = already_inserted_ssa(compact, processed_idx) if stmt === nothing ssa_rename[idx] = stmt elseif isa(stmt, OldSSAValue) @@ -1535,7 +1535,7 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr values = stmt.values end - values = process_phinode_values(values, late_fixup, already_inserted, result_idx, ssa_rename, used_ssas, new_new_used_ssas, do_rename_ssa, mark_refined!) + values = process_phinode_values(values, late_fixup, already_inserted_phi_arg, result_idx, ssa_rename, used_ssas, new_new_used_ssas, do_rename_ssa, mark_refined!) # Don't remove the phi node if it is before the definition of its value # because doing so can create forward references. This should only # happen with dead loops, but can cause problems when optimization @@ -1574,7 +1574,7 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr push!(values, value) end end - result[result_idx][:stmt] = PhiCNode(process_phinode_values(values, late_fixup, already_inserted, result_idx, ssa_rename, used_ssas, new_new_used_ssas, do_rename_ssa, mark_refined!)) + result[result_idx][:stmt] = PhiCNode(process_phinode_values(values, late_fixup, already_inserted_phi_arg, result_idx, ssa_rename, used_ssas, new_new_used_ssas, do_rename_ssa, mark_refined!)) result_idx += 1 else if isa(stmt, SSAValue) @@ -1883,6 +1883,8 @@ function fixup_node(compact::IncrementalCompact, @nospecialize(stmt), reify_new_ compact.used_ssas[node.id] += 1 elseif isa(node, NewSSAValue) compact.new_new_used_ssas[-node.id] += 1 + elseif isa(node, OldSSAValue) + return fixup_node(compact, node, reify_new_nodes) end return FixedNode(node, needs_fixup) else diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index 005545f473f07..39109786009aa 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -348,17 +348,23 @@ function record_immutable_preserve!(new_preserves::Vector{Any}, def::Expr, compa end function already_inserted(compact::IncrementalCompact, old::OldSSAValue) - id = old.id - if id < length(compact.ir.stmts) - return id < compact.idx - end - id -= length(compact.ir.stmts) - if id < length(compact.ir.new_nodes) - return already_inserted(compact, OldSSAValue(compact.ir.new_nodes.info[id].pos)) + already_inserted_ssa(compact, compact.idx-1)(0, old) +end + +function already_inserted_ssa(compact::IncrementalCompact, processed_idx::Int) + return function did_already_insert(phi_arg::Int, old::OldSSAValue) + id = old.id + if id <= length(compact.ir.stmts) + return id <= processed_idx + end + id -= length(compact.ir.stmts) + if id <= length(compact.ir.new_nodes) + return did_already_insert(phi_arg, OldSSAValue(compact.ir.new_nodes.info[id].pos)) + end + id -= length(compact.ir.new_nodes) + @assert id <= length(compact.pending_nodes) + return !(id in compact.pending_perm) end - id -= length(compact.ir.new_nodes) - @assert id <= length(compact.pending_nodes) - return !(id in compact.pending_perm) end function is_pending(compact::IncrementalCompact, old::OldSSAValue) @@ -2079,6 +2085,7 @@ function adce_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing) end end end + return Pair{IRCode, Bool}(complete(compact), made_changes) end diff --git a/base/compiler/ssair/verify.jl b/base/compiler/ssair/verify.jl index ca3b7c4b64894..6b079c753c003 100644 --- a/base/compiler/ssair/verify.jl +++ b/base/compiler/ssair/verify.jl @@ -72,7 +72,7 @@ function check_op(ir::IRCode, domtree::DomTree, @nospecialize(op), use_bb::Int, end end elseif isa(op, Union{OldSSAValue, NewSSAValue}) - @verify_error "Left over SSA marker" + @verify_error "At statement %$use_idx: Left over SSA marker ($op)" error("") elseif isa(op, SlotNumber) @verify_error "Left over slot detected in converted IR" diff --git a/test/compiler/irpasses.jl b/test/compiler/irpasses.jl index da717803d93e4..48a23fd0d5c39 100644 --- a/test/compiler/irpasses.jl +++ b/test/compiler/irpasses.jl @@ -1709,3 +1709,19 @@ end @test scope_folding_opt() == 1 @test_broken fully_eliminated(scope_folding) @test_broken fully_eliminated(scope_folding_opt) + +# Function that happened to have lots of sroa that +# happened to trigger a bad case in the renamer. We +# just want to check this doesn't crash in inference. +function f52610() + slots_dict = IdDict() + for () in Base.inferencebarrier(1) + for x in 1 + if Base.inferencebarrier(true) + slots_dict[x] = 0 + end + end + end + return nothing +end +@test code_typed(f52610)[1][2] === Nothing