From df09f67cfd08e89ceeb5559b8f71e177cacdba9c Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 14 Jun 2023 05:06:07 -0400 Subject: [PATCH] irverify: Enforce invariant that PhiNodes are at the beginning of a BB (#50158) We have an invariant that all PhiNodes are at the beginning of a BasicBlock (only possible interrupted by a `nothing`) and we rely on this in various places for correctness. However, we did not actually verify this invariant. --- base/compiler/ssair/verify.jl | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/base/compiler/ssair/verify.jl b/base/compiler/ssair/verify.jl index bf06d6bb3e523..8df42bd499631 100644 --- a/base/compiler/ssair/verify.jl +++ b/base/compiler/ssair/verify.jl @@ -187,20 +187,30 @@ function verify_ir(ir::IRCode, print::Bool=true, end end end + lastbb = 0 + is_phinode_block = false for (bb, idx) in bbidxiter(ir) + if bb != lastbb + is_phinode_block = true + lastbb = bb + end # We allow invalid IR in dead code to avoid passes having to detect when # they're generating dead code. bb_unreachable(domtree, bb) && continue stmt = ir.stmts[idx][:inst] stmt === nothing && continue if isa(stmt, PhiNode) + if !is_phinode_block + @verify_error "φ node $idx is not at the beginning of the basic block $bb" + error("") + end @assert length(stmt.edges) == length(stmt.values) for i = 1:length(stmt.edges) edge = stmt.edges[i] for j = (i+1):length(stmt.edges) edge′ = stmt.edges[j] if edge == edge′ - # TODO: Move `unique` to Core.Compiler. For now we assume the predecessor list is + # TODO: Move `unique` to Core.Compiler. For now we assume the predecessor list is always unique. @verify_error "Edge list φ node $idx in bb $bb not unique (double edge?)" error("") end @@ -233,7 +243,14 @@ function verify_ir(ir::IRCode, print::Bool=true, end check_op(ir, domtree, val, Int(edge), last(ir.cfg.blocks[stmt.edges[i]].stmts)+1, idx, print, false, i, allow_frontend_forms) end - elseif isa(stmt, PhiCNode) + continue + elseif stmt === nothing + # Nothing to do + continue + end + + is_phinode_block = false + if isa(stmt, PhiCNode) for i = 1:length(stmt.values) val = stmt.values[i] if !isa(val, SSAValue)