llvm / llvm/llvm-project

[MLIR][Linalg][Canonicalize] Crash in FoldTensorCastPackOp::matchAndRewrite via getNewMixedTileSizes when tile size is dynamic (assert/bad_optional_access on non-constant tile)

Open
#189,313 4 comments 1 reaction 0 assignees View on GitHub
crash mlir
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.