From b9806d6e63ad1910455cba6a0edb1e000a8b3560 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Mon, 15 May 2023 16:47:14 -0400 Subject: [PATCH] irinterp: Don't try to rekill fall-through terminators (#49815) If a fall-through terminator was already Bottom, we should not attempt to rekill the successor edge, because it was already deleted. Yet another fix in the #49692, #49750, #49797 series, which is turning out to be quite a rabit hole. Also fix a typo in the verifer tweak where we were looking at the BB idx rather than the terminator idx. --- base/compiler/ssair/irinterp.jl | 6 +++++- base/compiler/ssair/verify.jl | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/base/compiler/ssair/irinterp.jl b/base/compiler/ssair/irinterp.jl index ba2587173c089..8d75ad3948ee2 100644 --- a/base/compiler/ssair/irinterp.jl +++ b/base/compiler/ssair/irinterp.jl @@ -247,13 +247,17 @@ function _ir_abstract_constant_propagation(interp::AbstractInterpreter, irsv::IR any_refined = true delete!(ssa_refined, idx) end + is_terminator_or_phi = isa(inst, PhiNode) || isa(inst, GotoNode) || isa(inst, GotoIfNot) || isa(inst, ReturnNode) || isexpr(inst, :enter) + if typ === Bottom && (idx != lstmt || !is_terminator_or_phi) + continue + end if any_refined && reprocess_instruction!(interp, idx, bb, inst, typ, irsv, extra_reprocess) push!(ssa_refined, idx) inst = ir.stmts[idx][:inst] typ = ir.stmts[idx][:type] end - if typ === Bottom && !(isa(inst, PhiNode) || isa(inst, GotoNode) || isa(inst, GotoIfNot) || isa(inst, ReturnNode) || isexpr(inst, :enter)) + if typ === Bottom && !is_terminator_or_phi kill_terminator_edges!(irsv, lstmt, bb) if idx != lstmt for idx2 in (idx+1:lstmt-1) diff --git a/base/compiler/ssair/verify.jl b/base/compiler/ssair/verify.jl index baa0e6e2235a6..bf06d6bb3e523 100644 --- a/base/compiler/ssair/verify.jl +++ b/base/compiler/ssair/verify.jl @@ -174,12 +174,14 @@ function verify_ir(ir::IRCode, print::Bool=true, end isa(stmt, PhiNode) || break end - if isempty(block.succs) && ir.stmts[idx][:type] == Union{} + termidx = last(block.stmts) + stmttyp = ir.stmts[termidx][:type] + if isempty(block.succs) && stmttyp == Union{} # Allow fallthrough terminators that are known to error to # be removed from the CFG. Ideally we'd add an unreachable # here, but that isn't always possible. else - @verify_error "Block $idx successors ($(block.succs)), does not match fall-through terminator ($terminator)" + @verify_error "Block $idx successors ($(block.succs)), does not match fall-through terminator %$termidx ($terminator)::$stmttyp" error("") end end