[MLIR][Linalg][Canonicalize] Crash in FoldTensorCastPackOp::matchAndRewrite via getNewMixedTileSizes when tile size is dynamic (assert/bad_optional_access on non-constant tile)
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
**Description**
`mlir-opt --canonicalize` crashes with an assertion failure in `getNewMixedTileSizes` when canonicalizing a `linalg.pack` op that has a `tensor.cast` as its destination and a dynamic (non-constant) inner tile size. The `FoldTensorCastPackOp` pattern fires and calls `getNewMixedTileSizes`, which calls `assert(getConstantIntValue(tile).value() == shape)` unconditionally. When the tile size is a dynamic `index` SSA value rather than a compile-time constant, `getConstantIntValue` returns `std::nullopt` and `.value()` aborts.
This is the `linalg.pack` counterpart of issues #187975 and #188405 (which affected `linalg.unpack` via `FoldTensorCastUnPackOp`). Both operations share the same `getNewMixedTileSizes` helper function in `LinalgOps.cpp` with the same crash at line 5042.
**Reproducer**
```mlir
module {
func.func @f(%src: tensor, %dest: tensor, %tile_size: index) -> tensor {
%dest_dyn = tensor.cast %dest : tensor to tensor
%pack = linalg.pack %src
inner_dims_pos = [0, 1]
inner_tiles = [%tile_size, 1]
into %dest_dyn : tensor -> tensor
%cast_back = tensor.cast %pack : tensor to tensor
return %cast_back : tensor
}
}
```
**Command**
```
mlir-opt --canonicalize reproduce.mlir
```
**Expected behavior**
`FoldTensorCastPackOp` should bail out (return failure) when an inner tile size is not a compile-time constant, rather than unconditionally asserting.
**Actual behavior**
```
mlir-opt: mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp:5042:
Assertion `getConstantIntValue(tile).value() == dimSize && "tile size and dim size don't match\!"` failed.
Aborted (core dumped)
```
**Call chain**
```
--canonicalize
→ FoldTensorCastPackOp::matchAndRewrite (LinalgOps.cpp:6023)
→ getNewMixedTileSizes (LinalgOps.cpp:5022)
→ getConstantIntValue(tile) → nullopt (tile is dynamic)
→ optional::value() ← abort: bad_optional_access / assert
```
**Related**: #187975, #188405 (same root cause, same helper function, but for `linalg.unpack`). PR #188000 fixes the unpack case and also fixes the shared helper, so the pack variant will be fixed by the same PR.
Contributor guide
Research direction
Start in mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp at getNewMixedTileSizes and FoldTensorCastPackOp::matchAndRewrite, then run the supplied reproducer with mlir-opt --canonicalize. Done means the dynamic inner tile size no longer aborts during canonicalization and the pack pattern bails out as described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100