Skip to content

[mlir][SPIRV][Canonicalizer] Assertion \succeeded(result) && "expected ConstantLike op to be foldable" in constant_op_binder::match on spirv.ARM.GraphConstant with !spirv.arm.tensor result type #197970

@YuanchengJiang

Description

@YuanchengJiang

Summary

The canonicalizer crashes with an assertion failure when processing a spirv.ARM.GraphConstant op whose result type is !spirv.arm.tensor<>. The op carries the ConstantLike trait, which causes constant_op_binder::match in the greedy pattern rewriter to call fold() and unconditionally assert success — but fold() returns failure because the constant's value is externally supplied at runtime (via graph_constant_id) and cannot be represented as a compile-time attribute.

Assertion

mlir-opt: mlir/include/mlir/IR/Matchers.h:93:
bool mlir::detail::constant_op_binder<AttrT>::match(mlir::Operation*):
Assertion `succeeded(result) && "expected ConstantLike op to be foldable"' failed.

Minimal Reproducer

File (min.mlir):

spirv.ARM.Graph @g() -> (!spirv.arm.tensor<1xi8>) {
  %0 = spirv.ARM.GraphConstant {graph_constant_id = 0 : i32} : !spirv.arm.tensor<1xi8>
  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1xi8>
}

Command:

mlir-opt --canonicalize min.mlir

Also triggered by --inline alone, or the full pipeline --split-input-file --allow-unregistered-dialect --loop-invariant-code-motion --inline --sccp (the inliner runs canonicalization internally per callable).

Stack Trace (key frames)

#9  mlir::detail::constant_op_binder<mlir::Attribute>::match(mlir::Operation*)
      mlir/include/mlir/IR/Matchers.h:93
#10  mlir::matchPattern<...>(mlir::Operation*, ...)
      mlir/include/mlir/IR/Matchers.h:502
#11  RegionPatternRewriteDriver::simplify(bool*)
      mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp:862
#12  mlir::applyPatternsGreedily(...)
      mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp:956
#13  Canonicalizer::runOnOperation()
      mlir/lib/Transforms/Canonicalizer.cpp:88
#14  Inliner::Impl::optimizeCallable(...)   [when triggered via --inline]
      mlir/lib/Transforms/Utils/Inliner.cpp:577

Analysis

spirv.ARM.GraphConstant is declared with the ConstantLike trait. The constant_op_binder in Matchers.h matches any op with this trait and then asserts that calling fold() succeeds:

// Matchers.h:93
assert(succeeded(result) && "expected ConstantLike op to be foldable");

This assumption does not hold for spirv.ARM.GraphConstant: its constant value is identified by an external graph_constant_id integer rather than a materialized MLIR attribute, so fold() correctly returns failure. The assertion fires because constant_op_binder treats the ConstantLike trait as a guarantee of unconditional foldability.

There are two plausible fixes:

  1. In Matchers.h: Convert the assert to a conditional check — if fold() returns failure on a ConstantLike op, treat it as a non-match rather than crashing.
  2. In spirv.ARM.GraphConstant: Remove the ConstantLike trait if the op's value cannot be represented as a compile-time MLIR attribute, since the trait's contract requires successful folding.

Environment

  • MLIR from llvm-project (build at projects/mlir/llvm-mlir-install)
  • Reproducible with just mlir-opt --canonicalize; no special dialects or flags required

This bug was found by fusion-fuzz

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions