mlir-opt可解析并验证.mlir文件语法与结构,报错即终止,是mlir开发第一道防线;支持--canonicalize等pass应用、--print-ir-before/after调试、--verify-diagnostics断言测试及--mlir-print-op-on-failure精准定位错误。

mlir-opt 是 MLIR 工具链里最常用的 IR 检查与变换工具,它不生成机器码,只做 IR 层面的解析、验证、打印和 pass 应用。你写完一段 .mlir 文件后,想确认语法是否合法、结构是否符合预期、或某个 pass 是否生效,就靠它。
怎么用 mlir-opt 读取并验证一个 .mlir 文件
最基础的用法就是让 mlir-opt 解析并原样输出(即“parse + print”):
mlir-opt input.mlir
如果文件有语法错误(比如漏了冒号、类型不匹配、操作名拼错),mlir-opt 会直接报错并退出,例如:
error: expected ':' in type
或者:
error: unknown operation 'arith.addf_bad'
这种报错比在 C++ 编译期或运行时报错早得多,是写 MLIR 的第一道防线。
常见检查建议:
- 确保
input.mlir开头有module { ... }或至少一个顶层操作(如func.func); - 所有
%命名值必须先定义再使用(SSA 要求); - 方言名(如
arith、linalg)必须已注册,否则会报unknown dialect; - 若用到
transform方言,需显式启用:mlir-opt --load-pass-plugin=libTransformDialect.so input.mlir(插件路径依构建而定)。
怎么用 mlir-opt 查看某 pass 的效果
比如你想确认 canonicalizer 是否能把 arith.constant 0 : i32 和 arith.addi %x, %c0 简化成 %x:
mlir-opt --canonicalize input.mlir
输出就是应用一次 canonicalizer 后的 IR。注意:
-
--canonicalize默认只跑一轮,不迭代;要多轮需加--canonicalize=enable-region-simplification或手动链式调用; - 有些 pass 依赖其他 dialect 注册,比如
linalg相关 pass 需提前加载--load-pass-plugin=libLinalgTransforms.so; - 若 IR 中含未注册方言(如
iree.stream),mlir-opt会拒绝加载,除非你编译时启用了对应子项目或手动注册插件。
怎么用 mlir-opt 查看 IR 结构细节(dump)
有时你看不出为什么某个 pass 没生效,需要 inspect IR 的实际结构:
-
mlir-opt --print-ir-before-all input.mlir 2>&1 | grep "arith.addi":看所有 pass 前的 IR 中是否有目标操作; -
mlir-opt --print-ir-after=canonicalize input.mlir:只在canonicalize后打印一次; -
mlir-opt --verify-diagnostics input.mlir:配合expect!注释(如// expect! error: ...)做测试断言,适合写 test case; -
mlir-opt --mlir-print-op-on-failure input.mlir:出错时自动 dump 出问题的操作上下文,比默认报错信息更准。
这些 flag 不是“锦上添花”,而是调试时真正省时间的手段。特别是 --mlir-print-op-on-failure,很多新手卡在“pass 没反应”上,其实只是 IR 根本没满足触发条件(比如 operand 类型不对),但默认错误信息不告诉你哪一行、哪个 op 出的问题。
常见环境坑点:找不到 pass 或方言
你执行 mlir-opt --linalg-bufferize input.mlir 却提示:
unknown option '--linalg-bufferize'
这不是你命令写错了,而是:
- 你用的是系统自带或精简版 MLIR(如 Ubuntu apt 安装的
mlir-tools),它不含linalg插件; - 你从源码编译时没开
LLVM_ENABLE_PROJECTS="mlir",或漏了-DLLVM_BUILD_EXAMPLES=ON(部分插件依赖 examples); - 你没把 build 目录下的
lib加进LD_LIBRARY_PATH,导致mlir-opt找不到动态插件; -
linalg-bufferize实际属于mlir-linalg-ods-gen相关组件,需确保build/mlir/lib/Transforms/下有对应 so 文件。
最稳的做法:用自己从 llvm-project 编译出来的 mlir-opt,路径类似 build/bin/mlir-opt,并确认 build/lib 在 LD_LIBRARY_PATH 中。











