verify 函数是 MLIR 中 Op 语义校验的唯一自动调用入口,需在 Op 类中定义签名 LogicalResult verify() 并在 ODS 中设 hasVerifier=1;校验时可安全访问 operand、result、attr,须用 emitOpError() 报错,禁止修改 IR 或抛异常。

怎么在 MLIR 中为自定义 Op 添加校验逻辑
MLIR 不会在解析或构建时自动检查 Op 的语义合法性,verify 函数是唯一由框架主动调用的校验入口——它在 Operation 构建完成、插入到 IR 前被触发,失败则直接报错并中止插入。
校验逻辑必须写在 Op 类定义里,且需显式注册;不写 verify 或漏掉注册,等于完全跳过校验。
-
verify是成员函数,签名固定为LogicalResult verify(),返回success()或failure() - 校验中可安全访问
getOperand(n)、getResult(n)、getAttr("xxx")等,但不能修改 IR 结构 - 错误信息必须用
emitOpError()(不是emitError()),否则位置信息丢失、报错不指向具体 Op - 若依赖类型约束(如要求某 operand 是 tensor 类型且 rank ≥ 2),应先用
isa<RankedTensorType>()检查,再取.getRank(),避免未检查就调用崩溃
为什么 verify 有时不触发
常见误解是“只要写了 verify 就一定运行”,实际取决于 Op 的构建方式和上下文:
- 通过
builder.create<MyOp>(...)创建时,verify默认启用且必调 - 用
parseAssembly从文本解析时,verify也必调;但如果 parser 内部提前return failure()(比如属性格式错),verify根本不会执行 - 在 Pass 中用
rewriter.replaceOpWithNewOp<MyOp>(...)时,新 Op 的verify会触发,但旧 Op 已移除,不校验 - 若 Op 定义里没在 ODS(.td 文件)中声明
let hasVerifier = 1;,C++ 代码生成器根本不会把verify注册进 dispatch 表——此时函数存在但永不调用
verify 里能做哪些事,哪些绝对不能做
校验阶段不是优化阶段,它的唯一职责是回答“这个 Op 在当前形态下是否合法”。越界操作会导致未定义行为或断言失败:
- ✅ 可检查:operand 数量是否匹配、属性是否存在且类型正确、tensor shape 是否兼容、整数属性是否在合理范围(如
axis不越界) - ✅ 可调用:其他 Op 提供的
hasTrait<...>()、getType().isa<...>()、getLoc()获取源位置用于报错 - ❌ 禁止:创建新 Operation、修改 Block、调用
rewriter、触发 dialect conversion、访问外部状态(如全局 map) - ❌ 禁止:在
verify里抛 C++ 异常(MLIR 要求纯 LogicalResult 流程)、或用llvm_unreachable替代return failure()
一个典型的 OrOp 校验示例
假设你为 Toy Dialect 添加了 toy.or,要求两个 operand 类型相同、都是 ranked tensor,且元素类型为 integer:
LogicalResult OrOp::verify() {
auto lhs = getLhs();
auto rhs = getRhs();
if (lhs.getType() != rhs.getType())
return emitOpError() << "lhs and rhs must have the same type";
auto ty = lhs.getType().dyn_cast_or_null<RankedTensorType>();
if (!ty)
return emitOpError() << "operands must be ranked tensors";
if (!ty.getElementType().isInteger(1) && !ty.getElementType().isInteger(32))
return emitOpError() << "element type must be i1 or i32";
return success();
}
注意:这里没检查 shape 是否 broadcastable——那是后续 canonicalization 或 lowering 阶段的事;verify 只管“结构上能否成立”,不管“语义上是否最优”。这点容易混淆,也是最常被忽略的边界。

















