Skip to content

Commit 72e319c

Browse files
committed
IRVerify: Check IR stmt + metadata vector ranges
These checks are important to make sure that `verify_ir` does not end up triggering out-of-bounds errors as it checks IR. It also fills out some of the verification: - Confirms that cfg.index is correct - Confirms that cfg.blocks[i].stmts cover the complete IR
1 parent d6f66b5 commit 72e319c

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

base/compiler/ssair/verify.jl

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,31 @@ end
8989
function verify_ir(ir::IRCode, print::Bool=true,
9090
allow_frontend_forms::Bool=false,
9191
𝕃ₒ::AbstractLattice = SimpleInferenceLattice.instance)
92+
# Verify CFG graph. Must be well formed to construct domtree
93+
if !(length(ir.cfg.blocks) - 1 <= length(ir.cfg.index) <= length(ir.cfg.blocks))
94+
@verify_error "CFG index length ($(length(ir.cfg.index))) does not correspond to # of blocks $(length(ir.cfg.blocks))"
95+
error("")
96+
end
97+
if length(ir.stmts.stmt) != length(ir.stmts)
98+
@verify_error "IR stmt length is invalid $(length(ir.stmts.stmt)) / $(length(ir.stmts))"
99+
error("")
100+
end
101+
if length(ir.stmts.type) != length(ir.stmts)
102+
@verify_error "IR type length is invalid $(length(ir.stmts.type)) / $(length(ir.stmts))"
103+
error("")
104+
end
105+
if length(ir.stmts.info) != length(ir.stmts)
106+
@verify_error "IR info length is invalid $(length(ir.stmts.info)) / $(length(ir.stmts))"
107+
error("")
108+
end
109+
if length(ir.stmts.line) != length(ir.stmts)
110+
@verify_error "IR line length is invalid $(length(ir.stmts.line)) / $(length(ir.stmts))"
111+
error("")
112+
end
113+
if length(ir.stmts.flag) != length(ir.stmts)
114+
@verify_error "IR flag length is invalid $(length(ir.stmts.flag)) / $(length(ir.stmts))"
115+
error("")
116+
end
92117
# For now require compact IR
93118
# @assert isempty(ir.new_nodes)
94119
# Verify CFG
@@ -125,6 +150,18 @@ function verify_ir(ir::IRCode, print::Bool=true,
125150
error("")
126151
end
127152
end
153+
if !(1 <= first(block.stmts) <= length(ir.stmts))
154+
@verify_error "First statement of BB $idx ($(first(block.stmts))) out of bounds for IR (length=$(length(ir.stmts)))"
155+
error("")
156+
end
157+
if !(1 <= last(block.stmts) <= length(ir.stmts))
158+
@verify_error "Last statement of BB $idx ($(last(block.stmts))) out of bounds for IR (length=$(length(ir.stmts)))"
159+
error("")
160+
end
161+
if idx <= length(ir.cfg.index) && last(block.stmts) + 1 != ir.cfg.index[idx]
162+
@verify_error "End of BB $idx ($(last(block.stmts))) is not one less than CFG index ($(ir.cfg.index[idx]))"
163+
error("")
164+
end
128165
end
129166
# Verify statements
130167
domtree = construct_domtree(ir.cfg.blocks)
@@ -145,7 +182,7 @@ function verify_ir(ir::IRCode, print::Bool=true,
145182
end
146183
elseif isa(terminator, GotoNode)
147184
if length(block.succs) != 1 || block.succs[1] != terminator.label
148-
@verify_error "Block $idx successors ($(block.succs)), does not match GotoNode terminator"
185+
@verify_error "Block $idx successors ($(block.succs)), does not match GotoNode terminator ($(terminator.label))"
149186
error("")
150187
end
151188
elseif isa(terminator, GotoIfNot)
@@ -167,8 +204,8 @@ function verify_ir(ir::IRCode, print::Bool=true,
167204
if length(block.succs) != 1 || block.succs[1] != idx + 1
168205
# As a special case, we allow extra statements in the BB of an :enter
169206
# statement, until we can do proper CFG manipulations during compaction.
170-
for idx in first(block.stmts):last(block.stmts)
171-
stmt = ir[SSAValue(idx)][:stmt]
207+
for stmt_idx in first(block.stmts):last(block.stmts)
208+
stmt = ir[SSAValue(stmt_idx)][:stmt]
172209
if isexpr(stmt, :enter)
173210
terminator = stmt
174211
@goto enter_check
@@ -188,6 +225,10 @@ function verify_ir(ir::IRCode, print::Bool=true,
188225
end
189226
end
190227
end
228+
if length(ir.stmts) != last(ir.cfg.blocks[end].stmts)
229+
@verify_error "End of last BB $(last(ir.cfg.blocks[end].stmts)) does not match last IR statement $(length(ir.stmts))"
230+
error("")
231+
end
191232
lastbb = 0
192233
is_phinode_block = false
193234
firstidx = 1

0 commit comments

Comments
 (0)