[Mlir-commits] [mlir] [mlir][tosa] Simplify pad shape inference and verification (PR #233064)
Mehdi Amini
llvmlistbot at llvm.org
Sat Oct 17 03:04:45 PDT 2026
https://github.com/joker-eph created https://github.com/llvm/llvm-project/pull/233064
Treat constant padding amounts as ordinary integers during shape inference. Remove the example assigning a dynamic-padding meaning to negative values.
Keep PadOp verification local to operand and result types. Check padding length through its shape type and drop checks of constant operand contents and derived output extents.
Assisted-by: Codex
>From 96ca0c332191d8bddf3629fd14e8f399e90d86cf Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Sat, 17 Oct 2026 03:02:25 -0700
Subject: [PATCH] [mlir][tosa] Simplify pad shape inference and verification
Treat constant padding amounts as ordinary integers during shape
inference. Remove the example assigning a dynamic-padding meaning to
negative values.
Keep PadOp verification local to operand and result types. Check padding
length through its shape type and drop checks of constant operand
contents and derived output extents.
Add regression coverage for constant arithmetic and computed padding
operands.
Assisted-by: Codex
---
mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td | 8 ----
mlir/lib/Dialect/Tosa/IR/TosaOps.cpp | 44 ++-----------------
mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir | 11 +++++
mlir/test/Dialect/Tosa/verifier.mlir | 18 +++-----
4 files changed, 19 insertions(+), 62 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
index 339061b2aee837..6936578f63d364 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
@@ -2115,14 +2115,6 @@ def Tosa_PadOp : Tosa_InferShapedTypeOp<"pad", [Pure]> {
%padding = tosa.const_shape values(dense<[1, 2, 3, 4]> : tensor<4xindex>) : () -> !tosa.shape<4>
tosa.pad %arg0, %padding, %pad_const : (tensor<1x2xf32>, !tosa.shape<4>, tensor<1xf32>) -> tensor<4x9xf32>
```
-
- Example 2:
-
- ```mlir
- %pad_const = "tosa.const"() <{values = dense<3.14> : tensor<1xf32>}> : () -> tensor<1xf32>
- %padding = tosa.const_shape values(dense<[-1, 2, 3, 4]> : tensor<4xindex>) : () -> !tosa.shape<4>
- tosa.pad %arg0, %padding, %pad_const : (tensor<1x2xf32>, !tosa.shape<4>, tensor<1xf32>) -> tensor<?x9xf32>
- ```
}];
let arguments = (ins
diff --git a/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp b/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
index 838d039cb2c24a..d65ff4f02b08e7 100644
--- a/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
+++ b/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
@@ -2327,12 +2327,6 @@ LogicalResult tosa::PadOp::inferReturnTypeComponents(
}
auto padFront = paddingValues[i * 2];
auto padBack = paddingValues[i * 2 + 1];
- if (padFront < 0 || padBack < 0) {
- // if either padding for dim i is -1, output dim is unknown
- outputShape.push_back(ShapedType::kDynamic);
- continue;
- }
-
outputShape.push_back(inputShape.getDimSize(i) + padFront + padBack);
}
@@ -2367,43 +2361,11 @@ LogicalResult tosa::PadOp::verify() {
return failure();
auto inputRank = inputType.getRank();
- DenseIntElementsAttr paddingAttr;
- if (!matchPattern(getPadding(), m_Constant(&paddingAttr)))
- return success();
-
- auto paddingValues = paddingAttr.getValues<APInt>();
- if (paddingValues.size() != static_cast<size_t>(inputRank * 2))
+ auto paddingRank = cast<tosa::shapeType>(getPadding().getType()).getRank();
+ if (paddingRank != inputRank * 2)
return emitOpError() << "padding tensor must have " << inputRank
<< " * 2 = " << inputRank * 2 << " elements, but got "
- << paddingValues.size();
-
- auto inputShape = inputType.getShape();
- auto outputShape = outputType.getShape();
-
- for (int64_t i = 0; i < inputRank; ++i) {
- int64_t padStart = paddingValues[i * 2].getSExtValue();
- int64_t padEnd = paddingValues[i * 2 + 1].getSExtValue();
-
- if ((padStart < 0 && padStart != -1) || (padEnd < 0 && padEnd != -1)) {
- return emitOpError()
- << "invalid padding values at dimension " << i
- << ": values must be non-negative or -1 for dynamic padding, got ["
- << padStart << ", " << padEnd << "]";
- }
-
- // Skip shape verification for dynamic input/output
- if (inputShape[i] == ShapedType::kDynamic ||
- outputShape[i] == ShapedType::kDynamic)
- continue;
-
- if (outputShape[i] != inputShape[i] + padStart + padEnd) {
- return emitOpError() << "mismatch in output shape at dimension " << i
- << ": expected " << inputShape[i] << " + "
- << padStart << " + " << padEnd << " = "
- << (inputShape[i] + padStart + padEnd)
- << ", but got " << outputShape[i];
- }
- }
+ << paddingRank;
return success();
}
diff --git a/mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir b/mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir
index 4673f22460ea75..7ffdcbfcf99c43 100644
--- a/mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir
+++ b/mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir
@@ -838,6 +838,17 @@ func.func @test_padding_simple(%arg0 : tensor<1x2xf32>) -> () {
// -----
+// CHECK-LABEL: @test_padding_constant_arithmetic
+func.func @test_padding_constant_arithmetic(%arg0 : tensor<10x20xf32>) {
+ %0 = tosa.const_shape values(dense<[-1, 2, 3, 4]> : tensor<4xindex>) : () -> !tosa.shape<4>
+ %1 = "tosa.const"() <{values = dense<3.14> : tensor<1xf32>}> : () -> tensor<1xf32>
+ // CHECK: tosa.pad %arg0, %0, %1 : (tensor<10x20xf32>, !tosa.shape<4>, tensor<1xf32>) -> tensor<11x27xf32>
+ %2 = tosa.pad %arg0, %0, %1 : (tensor<10x20xf32>, !tosa.shape<4>, tensor<1xf32>) -> tensor<?x?xf32>
+ return
+}
+
+// -----
+
// CHECK-LABEL: @test_slice
func.func @test_slice(%arg0 : tensor<?xi32>) -> () {
// CHECK-DAG: %[[SIZE:.+]] = tosa.const_shape values(dense<2> : tensor<1xindex>) : () -> !tosa.shape<1>
diff --git a/mlir/test/Dialect/Tosa/verifier.mlir b/mlir/test/Dialect/Tosa/verifier.mlir
index 45b4f7739273fd..4eb15048e7d80f 100644
--- a/mlir/test/Dialect/Tosa/verifier.mlir
+++ b/mlir/test/Dialect/Tosa/verifier.mlir
@@ -688,19 +688,11 @@ func.func @test_pad_invalid_padding_rank(%arg0: tensor<13x21xf32>) {
}
// -----
-func.func @test_pad_output_mismatch(%arg0: tensor<13x21x3xi8>, %arg1: tensor<1xi8>) -> tensor<13x21x3xi8> {
- %0 = tosa.const_shape values(dense<[0, 0, 0, 1, 0, 1]> : tensor<6xindex>) : () -> !tosa.shape<6>
- // expected-error at +1 {{mismatch in output shape at dimension 1: expected 21 + 0 + 1 = 22, but got 21}}
- %1 = tosa.pad %arg0, %0, %arg1 : (tensor<13x21x3xi8>, !tosa.shape<6>, tensor<1xi8>) -> tensor<13x21x3xi8>
- return %1 : tensor<13x21x3xi8>
-}
-
-// -----
-func.func @test_pad_invalid_padding_value(%arg0: tensor<10xi8>, %arg1: tensor<1xi8>) -> tensor<10xi8> {
- %0 = tosa.const_shape values(dense<[-2, 2]> : tensor<2xindex>) : () -> !tosa.shape<2>
- // expected-error at +1 {{invalid padding values at dimension 0: values must be non-negative or -1 for dynamic padding, got [-2, 2]}}
- %1 = tosa.pad %arg0, %0, %arg1 : (tensor<10xi8>, !tosa.shape<2>, tensor<1xi8>) -> tensor<10xi8>
- return %1 : tensor<10xi8>
+func.func @test_pad_computed_padding_rank(%arg0: tensor<13x21x3xf32>, %arg1: tensor<1xf32>) {
+ %0 = tosa.dim %arg0 axis(0) : (tensor<13x21x3xf32>) -> !tosa.shape<1>
+ // expected-error at +1 {{'tosa.pad' op padding tensor must have 3 * 2 = 6 elements, but got 1}}
+ %1 = tosa.pad %arg0, %0, %arg1 : (tensor<13x21x3xf32>, !tosa.shape<1>, tensor<1xf32>) -> tensor<13x21x3xf32>
+ return
}
// -----
More information about the Mlir-commits
mailing list