[Mlir-commits] [mlir] [mlir][tensor] Fix element-count overflow assertion in reshape verifier (PR #222117)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Sep 8 12:48:21 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Stanislav Bardyuk (kodlan)

<details>
<summary>Changes</summary>

verifyTensorReshapeOp (shared by tensor.collapse_shape and
tensor.expand_shape) compares the static element counts of the two types
with ShapedType::getNumElements(), which asserts when the product does not
fit in int64_t since 8756292abb00. So a type like
tensor<4611686018427387904x2xf32> (2^63 elements) makes the verifier abort
in an assertions build instead of reporting anything:

```mlir
%0 = tensor.collapse_shape %arg0 [[0], [1]] : tensor<4611686018427387904x2xf32> into tensor<4611686018427387904x2xf32>
```

Use the checked ShapedType::tryGetNumElements() instead and reject the op
with a regular diagnostic when either count overflows. Rejecting rather
than skipping the check keeps the empty-reassociation case
(`collapse_shape [] : tensor<4611686018427387904x2xf32> into tensor<f32>`)
invalid, since that count comparison is the only check that catches it,
and it avoids relying on wrapped multiplication in release builds. It also
catches grouped cases whose per-group product wraps to a plausible value
(e.g. `[[0, 1]] : tensor<4294967296x4294967296xf32> into tensor<0xf32>`).

The per-group products in reshapeLikeShapesAreCompatible and
inferCollapsedType, and the count check in tensor.reshape, still use plain
multiplication (no assertion, but wrap on overflow); left for a follow-up.

Fixes #<!-- -->221590

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


2 Files Affected:

- (modified) mlir/lib/Dialect/Tensor/IR/TensorOps.cpp (+8-5) 
- (modified) mlir/test/Dialect/Tensor/invalid.mlir (+24) 


``````````diff
diff --git a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp
index fb14c1953fd22..3084a769458cd 100644
--- a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp
+++ b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp
@@ -2071,12 +2071,15 @@ static LogicalResult verifyTensorReshapeOp(TensorReshapeOp op,
 
   // Reshape must preserve the number of elements when statically known.
   if (expandedType.hasStaticShape() && collapsedType.hasStaticShape()) {
-    int64_t expandedNumElements = expandedType.getNumElements();
-    int64_t collapsedNumElements = collapsedType.getNumElements();
-    if (expandedNumElements != collapsedNumElements) {
+    std::optional<int64_t> expandedNumElements =
+        ShapedType::tryGetNumElements(expandedType.getShape());
+    std::optional<int64_t> collapsedNumElements =
+        ShapedType::tryGetNumElements(collapsedType.getShape());
+    if (!expandedNumElements || !collapsedNumElements)
+      return op.emitOpError("number of elements exceeds the int64 range");
+    if (*expandedNumElements != *collapsedNumElements)
       return op.emitOpError("number of elements must be preserved: ")
-             << expandedNumElements << " != " << collapsedNumElements;
-    }
+             << *expandedNumElements << " != " << *collapsedNumElements;
   }
 
   auto maps = op.getReassociationMaps();
diff --git a/mlir/test/Dialect/Tensor/invalid.mlir b/mlir/test/Dialect/Tensor/invalid.mlir
index a526d7ed61722..8fa233f993640 100644
--- a/mlir/test/Dialect/Tensor/invalid.mlir
+++ b/mlir/test/Dialect/Tensor/invalid.mlir
@@ -723,3 +723,27 @@ func.func @no_fold_invalid_collapse() -> tensor<i64> {
     return %0 : tensor<i64>
 }
 
+// -----
+
+func.func @collapse_shape_num_elements_overflow(%arg0: tensor<4611686018427387904x2xf32>) {
+  // expected-error at +1 {{'tensor.collapse_shape' op number of elements exceeds the int64 range}}
+  %0 = tensor.collapse_shape %arg0 [[0], [1]] : tensor<4611686018427387904x2xf32> into tensor<4611686018427387904x2xf32>
+  return
+}
+
+// -----
+
+func.func @collapse_shape_num_elements_overflow_to_scalar(%arg0: tensor<4611686018427387904x2xf32>) {
+  // expected-error at +1 {{'tensor.collapse_shape' op number of elements exceeds the int64 range}}
+  %0 = tensor.collapse_shape %arg0 [] : tensor<4611686018427387904x2xf32> into tensor<f32>
+  return
+}
+
+// -----
+
+func.func @expand_shape_num_elements_overflow(%arg0: tensor<4611686018427387904x2xf32>) {
+  // expected-error at +1 {{'tensor.expand_shape' op number of elements exceeds the int64 range}}
+  %0 = tensor.expand_shape %arg0 [[0], [1]] output_shape [4611686018427387904, 2] : tensor<4611686018427387904x2xf32> into tensor<4611686018427387904x2xf32>
+  return
+}
+

``````````

</details>


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


More information about the Mlir-commits mailing list