Description
mlir-opt --canonicalize --inline crashes with std::bad_optional_access in getNewMixedTileSizes when canonicalizing a linalg.unpack op that has a tensor.cast as its source and a dynamic (non-constant) tile size. The FoldTensorCastUnPackOp pattern fires and calls getNewMixedTileSizes, which calls getConstantIntValue(tile).value() unconditionally. When the tile size is a dynamic index SSA value rather than a compile-time constant, getConstantIntValue returns std::nullopt and .value() aborts.
Reproducer
module {
func.func @get_tile() -> index {
%c256 = arith.constant 256 : index
return %c256 : index
}
func.func @f(%A: tensor<1x3x8x1xi32>) -> tensor<7x3xi32> {
%tile_size = func.call @get_tile() : () -> index
%empty = tensor.empty() : tensor<7x3xi32>
%cast = tensor.cast %A : tensor<1x3x8x1xi32> to tensor<?x3x?x1xi32>
%unpack = linalg.unpack %cast
inner_dims_pos = [0, 1]
inner_tiles = [%tile_size, 1]
into %empty : tensor<?x3x?x1xi32> -> tensor<7x3xi32>
return %unpack : tensor<7x3xi32>
}
}
Command
mlir-opt --canonicalize --inline reproduce.mlir
Expected behavior
FoldTensorCastUnPackOp should bail out (return failure) when a tile size is not a compile-time constant, rather than unconditionally calling .value() on the result of getConstantIntValue. Alternatively it should only fire when all tile sizes are statically known.
Actual behavior
mlir-opt: optional:1013: std::optional<long>::value() &&: Assertion `this->_M_is_engaged()' failed.
Aborted (core dumped)
The crash is in getNewMixedTileSizes at LinalgOps.cpp:5025, called from FoldTensorCastUnPackOp::matchAndRewrite at LinalgOps.cpp:6479.
Call chain
--canonicalize (runs after --inline propagates call)
→ FoldTensorCastUnPackOp::matchAndRewrite (LinalgOps.cpp:6479)
→ getNewMixedTileSizes (LinalgOps.cpp:5025)
→ getConstantIntValue(tile) → nullopt (tile is dynamic)
→ optional::value() ← abort: bad_optional_access
Description
mlir-opt --canonicalize --inlinecrashes withstd::bad_optional_accessingetNewMixedTileSizeswhen canonicalizing alinalg.unpackop that has atensor.castas its source and a dynamic (non-constant) tile size. TheFoldTensorCastUnPackOppattern fires and callsgetNewMixedTileSizes, which callsgetConstantIntValue(tile).value()unconditionally. When the tile size is a dynamicindexSSA value rather than a compile-time constant,getConstantIntValuereturnsstd::nulloptand.value()aborts.Reproducer
Command
Expected behavior
FoldTensorCastUnPackOpshould bail out (return failure) when a tile size is not a compile-time constant, rather than unconditionally calling.value()on the result ofgetConstantIntValue. Alternatively it should only fire when all tile sizes are statically known.Actual behavior
The crash is in
getNewMixedTileSizesatLinalgOps.cpp:5025, called fromFoldTensorCastUnPackOp::matchAndRewriteatLinalgOps.cpp:6479.Call chain