[Mlir-commits] [mlir] [mlir][tensor] Fix element-count overflow assertion in reshape verifier (PR #222117)
Stanislav Bardyuk
llvmlistbot at llvm.org
Tue Sep 8 12:47:24 PDT 2026
https://github.com/kodlan created https://github.com/llvm/llvm-project/pull/222117
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
>From 866dd48c31b1a72c50469a9a8aee1ee464cad8b5 Mon Sep 17 00:00:00 2001
From: Stanislav Bardyuk <sbardyuk at google.com>
Date: Tue, 8 Sep 2026 19:43:34 +0000
Subject: [PATCH] [mlir][tensor] Fix element-count overflow assertion in
reshape verifier
verifyTensorReshapeOp compared the static element counts of the expanded
and collapsed types with ShapedType::getNumElements(), which asserts on
int64 overflow. Use tryGetNumElements() and reject the op with a
diagnostic when either count is not representable.
Fixes #221590
---
mlir/lib/Dialect/Tensor/IR/TensorOps.cpp | 13 ++++++++-----
mlir/test/Dialect/Tensor/invalid.mlir | 24 ++++++++++++++++++++++++
2 files changed, 32 insertions(+), 5 deletions(-)
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
+}
+
More information about the Mlir-commits
mailing list