[Mlir-commits] [mlir] [mlir][Tosa] Handle empty block-scaled reshape shapes (PR #220872)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Sep 3 04:07:27 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-tosa
@llvm/pr-subscribers-mlir
Author: Mehdi Amini (joker-eph)
<details>
<summary>Changes</summary>
Guard the inferred scale shape before accessing its last dimension, and reject rank-zero block-scaled reshape shapes before the unranked-input early exit. Preserve dynamic scale dimensions instead of applying block-size arithmetic to their sentinel.
Found by Coverity.
Assisted-by: Codex
---
Full diff: https://github.com/llvm/llvm-project/pull/220872.diff
2 Files Affected:
- (modified) mlir/lib/Dialect/Tosa/IR/TosaOps.cpp (+10-7)
- (modified) mlir/test/Dialect/Tosa/verifier.mlir (+9)
``````````diff
diff --git a/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp b/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
index 7d4d4f0d27a84..c4117d95fed11 100644
--- a/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
+++ b/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
@@ -3192,7 +3192,8 @@ LogicalResult tosa::ReshapeBlockScaledOp::inferReturnTypeComponents(
llvm::SmallVector<int64_t> newScaleShapeValue;
if (numInputs == 2) {
newScaleShapeValue.assign(newShapeValue.begin(), newShapeValue.end());
- if (ShapedType::isStatic(newScaleShapeValue.back()))
+ if (!newScaleShapeValue.empty() &&
+ ShapedType::isStatic(newScaleShapeValue.back()))
newScaleShapeValue.back() /= blockSize;
}
@@ -3203,7 +3204,8 @@ LogicalResult tosa::ReshapeBlockScaledOp::inferReturnTypeComponents(
for (size_t idx = 0; idx < newShapeValue.size(); idx++) {
if (ShapedType::isDynamic(newScaleShapeValue[idx])) {
newScaleShapeValue[idx] = newShapeValue[idx];
- if (idx == (newShapeValue.size() - 1))
+ if (idx + 1 == newShapeValue.size() &&
+ ShapedType::isStatic(newScaleShapeValue[idx]))
newScaleShapeValue[idx] /= blockSize;
}
}
@@ -3234,10 +3236,14 @@ llvm::LogicalResult tosa::ReshapeBlockScaledOp::verify() {
return failure();
}
+ const uint32_t blockSize = BlockSizeAttr::getBlockSizeValue(getBlockSize());
+ if (inputList.size() == 2 &&
+ cast<tosa::shapeType>(getNewValueShape().getType()).getRank() == 0)
+ return emitOpError("requires new shape to have a rank greater than 0");
+
const auto inputType = llvm::cast<ShapedType>(inputList[0].getType());
if (!inputType.hasRank())
return success();
- const uint32_t blockSize = BlockSizeAttr::getBlockSizeValue(getBlockSize());
if (inputList.size() == 2) {
if (blockSize != BlockSizeAttr::getBlockSizeValue(BlockSize::BLOCK_SIZE_32))
@@ -3302,7 +3308,7 @@ llvm::LogicalResult tosa::ReshapeBlockScaledOp::verify() {
return emitOpError("expect block size to be 1, got ") << blockSize;
}
- // Get the new value shape dimension values
+ // Get the new value shape dimension values.
SmallVector<int64_t> shapeValues;
if (!tosa::getConstShapeValues(getNewValueShape().getDefiningOp(),
shapeValues)) {
@@ -3311,9 +3317,6 @@ llvm::LogicalResult tosa::ReshapeBlockScaledOp::verify() {
}
if (inputList.size() == 2) {
- if (static_cast<int64_t>(shapeValues.size()) == 0)
- return emitOpError("requires new shape to have a rank greater than 0");
-
const int64_t lastShapeDim = shapeValues.back();
if (ShapedType::isStatic(lastShapeDim) && lastShapeDim % blockSize != 0)
return emitOpError("expect last dimension of new shape (")
diff --git a/mlir/test/Dialect/Tosa/verifier.mlir b/mlir/test/Dialect/Tosa/verifier.mlir
index 803ded01698a1..cd71fffbe9962 100644
--- a/mlir/test/Dialect/Tosa/verifier.mlir
+++ b/mlir/test/Dialect/Tosa/verifier.mlir
@@ -2268,6 +2268,15 @@ func.func @test_reshape_block_scaled_rank0_scale_input(%arg0 : tensor<64xf8E4M3F
// -----
+func.func @test_reshape_block_scaled_rank0_shape_unranked_inputs(%arg0 : tensor<*xf8E4M3FN>, %arg1 : tensor<*xf8E8M0FNU>) -> () {
+ %s = tosa.const_shape {values = dense<> : tensor<0xindex>} : () -> !tosa.shape<0>
+ // expected-error at +1 {{'tosa.reshape_block_scaled' op requires new shape to have a rank greater than 0}}
+ %0:2 = "tosa.reshape_block_scaled"(%arg0, %arg1, %s) {block_size = #tosa.block_size<BLOCK_SIZE_32> : i32} : (tensor<*xf8E4M3FN>, tensor<*xf8E8M0FNU>, !tosa.shape<0>) -> (tensor<*xf8E4M3FN>, tensor<*xf8E8M0FNU>)
+ return
+}
+
+// -----
+
func.func @test_reshape_non_block_scaled_block_size_mismatch(%arg0: tensor<13x21x3xf32>) -> tensor<1x819xf32> {
%s = tosa.const_shape {values = dense<[1, 819]> : tensor<2xindex>} : () -> !tosa.shape<2>
// expected-error at +1 {{'tosa.reshape_block_scaled' op expect block size to be 1, got 32}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/220872
More information about the Mlir-commits
mailing list