[Mlir-commits] [mlir] [mlir][tensor] Fix crash when canonicalizing extract_slice with a poi… (PR #223609)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Sep 14 23:11:48 PDT 2026
https://github.com/AkunCube created https://github.com/llvm/llvm-project/pull/223609
tensor.extract_slice with a ub.poison value in its dynamic offset/size list crashes the canonicalizer with a std::optional assertion:
```mlir
%p = ub.poison : index
%s = tensor.extract_slice %t[%p] [4] [1] : tensor<8xf32> to tensor<4xf32>
```
During canonicalization, OpWithOffsetSizesAndStridesConstantArgumentFolder calls foldDynamicIndexList, which matches constant operands with m_Constant (any op carrying the ConstantLike trait). ub.poison folds to a PoisonAttr, not an IntegerAttr, so getConstantIntValue returns std::nullopt and the unconditional dereference trips the "this->_M_is_engaged()" assertion.
Only fold the matched constant when it is an integer constant and skip non-integer constants such as poison. Since foldDynamicIndexList is shared, the guard also hardens its other callers (SCF/AMDGPU/Shard).
Add a regression test in `mlir/test/Dialect/Tensor/canonicalize.mlir` that used to crash.
Fixes: https://github.com/llvm/llvm-project/issues/223333
>From 2febdc04ee701f1f88f2f2e86066052147e41520 Mon Sep 17 00:00:00 2001
From: cubehan3 <cubehan3 at gmail.com>
Date: Tue, 15 Sep 2026 06:08:44 +0000
Subject: [PATCH] [mlir][tensor] Fix crash when canonicalizing extract_slice
with a poison offset
---
mlir/lib/Dialect/Utils/StaticValueUtils.cpp | 7 +++++--
mlir/test/Dialect/Tensor/canonicalize.mlir | 14 ++++++++++++++
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp
index 3f66d86e48991..aa62fdc01c79d 100644
--- a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp
+++ b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp
@@ -449,10 +449,13 @@ LogicalResult foldDynamicIndexList(SmallVectorImpl<OpFoldResult> &ofrs,
continue;
Attribute attr;
if (matchPattern(cast<Value>(ofr), m_Constant(&attr))) {
+ std::optional<int64_t> mayIntVal = getConstantIntValue(attr);
+ if (!mayIntVal)
+ continue;
// Note: All ofrs have index type.
- if (onlyNonNegative && *getConstantIntValue(attr) < 0)
+ if (onlyNonNegative && *mayIntVal < 0)
continue;
- if (onlyNonZero && *getConstantIntValue(attr) == 0)
+ if (onlyNonZero && *mayIntVal == 0)
continue;
ofr = attr;
valuesChanged = true;
diff --git a/mlir/test/Dialect/Tensor/canonicalize.mlir b/mlir/test/Dialect/Tensor/canonicalize.mlir
index d8db9d502fb99..217ce64cb9868 100644
--- a/mlir/test/Dialect/Tensor/canonicalize.mlir
+++ b/mlir/test/Dialect/Tensor/canonicalize.mlir
@@ -431,6 +431,20 @@ func.func @from_elements_with_poison() -> tensor<1xindex> {
// -----
+// Ensure tensor.extract_slice with a poison offset doesn't crash. The poison
+// value is not a constant integer, so it must not be folded into a static
+// offset.
+// CHECK-LABEL: func @extract_slice_with_poison_offset
+func.func @extract_slice_with_poison_offset(%t: tensor<8xf32>) -> tensor<4xf32> {
+ // CHECK: %[[POISON:.*]] = ub.poison : index
+ // CHECK: %[[SLICE:.*]] = tensor.extract_slice %arg0[%[[POISON]]] [4] [1]
+ %p = ub.poison : index
+ %s = tensor.extract_slice %t[%p] [4] [1] : tensor<8xf32> to tensor<4xf32>
+ return %s : tensor<4xf32>
+}
+
+// -----
+
// Ensure tensor.from_elements with a vector element type doesn't crash
// when the elements fold to constants (DenseElementsAttr does not support
// non-scalar element types via the Attribute overload).
More information about the Mlir-commits
mailing list