[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:12:28 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Akun (AkunCube)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/223609.diff


2 Files Affected:

- (modified) mlir/lib/Dialect/Utils/StaticValueUtils.cpp (+5-2) 
- (modified) mlir/test/Dialect/Tensor/canonicalize.mlir (+14) 


``````````diff
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).

``````````

</details>


https://github.com/llvm/llvm-project/pull/223609


More information about the Mlir-commits mailing list