该错误表示llvm ir违反ssa支配规则:某指令定义的值被非支配基本块使用,常见于phinode配置错误、循环内指令插入不当或replacealluseswith后未安全删除旧指令。

Instruction does not dominate all uses 是什么错误
这是 LLVM Verifier 报出的典型 IR 结构错误,不是语法错,也不是运行时崩溃,而是 IR 违反了 SSA 的支配(dominance)规则。简单说:某条指令 Inst 定义了一个值 %x,但后续有地方用了 %x,而那个使用点所在的 basic block 并不被 Inst 所在的 block 支配——也就是控制流上存在“绕过定义”的路径。
最常见触发场景和修复方式
这类错误几乎都出现在手动构造或修改 IR 时,尤其是涉及 PHINode、循环、条件分支或跨 block 插入指令的情况。
- 在非支配位置插入
PHINode:比如把phi放在 merge block 里,但漏写了某个 predecessor 的入边值,或写错了 predecessor 的顺序 - 把定义指令插在了 loop header 之外,却在 loop body 里直接用——body 中的 block 不支配 header 外的定义
- 用
IRBuilder在某个BasicBlock::end()插入指令,但没确认该 block 实际是当前插入点的支配者;更糟的是,在 terminator 后面强行插入(LLVM 允许但语义非法) - 调用
replaceAllUsesWith后没删旧指令,而旧指令仍留在非支配位置,导致 verifier 看到“一个值被两个不相干的定义同时供给”
怎么快速定位具体哪条指令出问题
Verifier 错误信息通常只报 “Instruction does not dominate all uses”,不指明行号。你需要结合上下文缩小范围:
- 用
opt -verify -debug-only=domtree input.ll查看支配树构建过程,观察 verifier 失败前最后输出的 block 和 dominator 关系 - 对疑似函数加
-print-before=verify,再用llvm-dis反汇编,人工检查 phi 节点的入边是否覆盖所有 predecessors,以及每个 operand 是否来自对应 predecessor 的合法位置 - 如果是在自定义 Pass 中触发,临时在
runOnFunction末尾加verifyFunction(&F)并打印返回 false 的函数名,再单步调试该 Pass 中插入/替换指令的位置 - 特别注意:
alloca指令必须放在 entry block 或被所有使用它的 block 支配;若在循环内重复alloca,不仅栈溢出,还会因多次定义同名%x导致支配关系断裂
为什么有时候 opt -verify 不报错,但 llc 崩溃
Verifier 只校验支配关系是否存在,不校验是否“足够强”。例如:
- 一个
phi节点有两条入边,但其中一条来自 unreachable block —— verifier 接受(因为不可达 block 不参与支配计算),但某些后端 pass 会尝试遍历所有入边并解引用空指针 - 使用
getelementptr inbounds计算地址后,又拿它去load,但 GEP 本身不保证内存可访问;verifier 不管运行时行为,只管 GEP 的索引是否符合 inbounds 规则 - Debug info 元数据(如
!dbg)指向已被删除的指令 —— verifier 不查这个,要靠opt -debug-info-verifier
真正难缠的往往不是支配缺失,而是支配“看似成立实则脆弱”:比如依赖未显式建模的 control dependence,或 phi 入边值来自未初始化的寄存器变量。这种问题在优化流水线中越往后越难回溯。











