[Mlir-commits] [mlir] [mlir][tosa] Move RESCALE zero-point value checks from the verifier to tosa-validate (PR #234443)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Oct 21 18:06:23 PDT 2026
https://github.com/Wijkqwe created https://github.com/llvm/llvm-project/pull/234443
Part of #233457.
Move the RESCALE input/output zero-point value constraints out of
`RescaleOp::verify()` into the `ERROR_IF` checks in `tosa-validate`,
matching the TOSA specification, where these are conformance rules rather
than dialect well-formedness requirements.
- `TosaOps.cpp`: drop the zp value checks from `RescaleOp::verify()`;
type checks stay in the verifier.
- `TosaValidation.cpp`: add the same checks to `checkErrorIfRescale()`,
reusing the op's verify helpers, gated on `strict-op-spec-alignment`.
The accepted/rejected set and diagnostics are unchanged.
- `TosaToLinalg.cpp`: add a fail-closed backstop in `RescaleConverter` so
conversion without validation rejects invalid zps instead of silently
lowering incorrect arithmetic.
Tests: move the six zp tests from `invalid.mlir` to `error_if_check.mlir`;
add input/output zp cases to `tosa-to-linalg-invalid.mlir`.
Assisted-by: AI.
>From 12f3e481b177872738bfb8f54ca5a598c87bac05 Mon Sep 17 00:00:00 2001
From: wzy <WZYqwe2004 at outlook.com>
Date: Wed, 21 Oct 2026 21:19:47 +0800
Subject: [PATCH 1/2] it just works
---
mlir/lib/Dialect/Tosa/IR/TosaOps.cpp | 8 --------
mlir/lib/Dialect/Tosa/Transforms/TosaValidation.cpp | 11 +++++++++++
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp b/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
index 99c352ab8ed3c3..35cc7d355cb80c 100644
--- a/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
+++ b/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
@@ -5005,14 +5005,6 @@ LogicalResult RescaleOp::verify() {
.failed())
return failure();
- FailureOr<int64_t> maybeIZp = getInputZeroPoint();
- if (succeeded(maybeIZp) && verifyInputZeroPoint(*maybeIZp).failed())
- return failure();
-
- FailureOr<int64_t> maybeOZp = getOutputZeroPoint();
- if (succeeded(maybeOZp) && verifyOutputZeroPoint(*maybeOZp).failed())
- return failure();
-
const auto multiplierType = llvm::cast<ShapedType>(getMultiplier().getType());
// multiplier element type must be i32 for scale32 = true
if (getScale32() && !multiplierType.getElementType().isInteger(32)) {
diff --git a/mlir/lib/Dialect/Tosa/Transforms/TosaValidation.cpp b/mlir/lib/Dialect/Tosa/Transforms/TosaValidation.cpp
index 5d465065497abf..7879ff101a62f7 100644
--- a/mlir/lib/Dialect/Tosa/Transforms/TosaValidation.cpp
+++ b/mlir/lib/Dialect/Tosa/Transforms/TosaValidation.cpp
@@ -1345,6 +1345,17 @@ LogicalResult checkErrorIfRescale(Operation *op) {
if (outWidth == 32 && outputUnsigned)
return op->emitOpError() << "i32 output type cannot be unsigned.";
+ // ERROR_IF(zp != 0 && !is_same<in_t, i8_t>)
+ // ERROR_IF(zp != 0 && zp != 32768 && is_same<in_t, u16_t>)
+ // Reuse the op's helpers so the ERROR_IF rules stay in a single place.
+ if (FailureOr<int64_t> maybeIZp = rescale.getInputZeroPoint();
+ succeeded(maybeIZp) && rescale.verifyInputZeroPoint(*maybeIZp).failed())
+ return failure();
+
+ if (FailureOr<int64_t> maybeOZp = rescale.getOutputZeroPoint();
+ succeeded(maybeOZp) && rescale.verifyOutputZeroPoint(*maybeOZp).failed())
+ return failure();
+
return success();
}
>From 6a1297bf88d3becc42ab629b1dc3d7083bd2826a Mon Sep 17 00:00:00 2001
From: wzy <WZYqwe2004 at outlook.com>
Date: Thu, 22 Oct 2026 08:36:56 +0800
Subject: [PATCH 2/2] fixed bug and added tests
---
.../Conversion/TosaToLinalg/TosaToLinalg.cpp | 15 +++-
.../TosaToLinalg/tosa-to-linalg-invalid.mlir | 28 +++++++
mlir/test/Dialect/Tosa/error_if_check.mlir | 72 ++++++++++++++++++
mlir/test/Dialect/Tosa/invalid.mlir | 73 -------------------
4 files changed, 113 insertions(+), 75 deletions(-)
diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
index 867ebbd6ce5ef0..5cf4625913a067 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
@@ -1831,6 +1831,19 @@ class RescaleConverter : public OpRewritePattern<tosa::RescaleOp> {
return rewriter.notifyMatchFailure(
op, "only support integer output types up to 32 bits");
+ // Zero points are already validated by tosa-validate under
+ // strict-op-spec-alignment, but reject invalid values here as well so
+ // that conversion without validation fails instead of silently
+ // generating incorrect arithmetic.
+ FailureOr<int64_t> maybeIZp = op.getInputZeroPoint();
+ if (succeeded(maybeIZp) && op.verifyInputZeroPoint(*maybeIZp).failed())
+ return rewriter.notifyMatchFailure(
+ op, "input zero point must be zero for non-int8 integer types");
+ FailureOr<int64_t> maybeOZp = op.getOutputZeroPoint();
+ if (succeeded(maybeOZp) && op.verifyOutputZeroPoint(*maybeOZp).failed())
+ return rewriter.notifyMatchFailure(
+ op, "output zero point must be zero for non-int8 integer types");
+
SmallVector<Value> dynDims;
for (int i = 0; i < outputTy.getRank(); i++) {
if (outputTy.isDynamicDim(i)) {
@@ -1904,8 +1917,6 @@ class RescaleConverter : public OpRewritePattern<tosa::RescaleOp> {
// broadcastMap = affine_map<(d0, d1) -> ()>
// It would affect as broadcast for scalar values in linalg::GenericOp.
AffineMap broadcastMap = AffineMap::get(rank, 0, {}, rewriter.getContext());
- FailureOr<int64_t> maybeIZp = op.getInputZeroPoint();
- FailureOr<int64_t> maybeOZp = op.getOutputZeroPoint();
// The inputZp and outputZp may be either constant or non-constant,
// depending on whether dynamic extension is enabled.
// - If the zp's are non-constant, add them as an inputs to
diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir
index 3a0b6b87eb1df7..20ccceb50308a6 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir
@@ -70,6 +70,34 @@ func.func @rescale_unsupported_i48_output(%arg0: tensor<2xi8>) -> tensor<2xi48>
// -----
+// CHECK-LABEL: @rescale_invalid_input_zp
+func.func @rescale_invalid_input_zp(%arg0: tensor<2xi32>) -> tensor<2xi32> {
+ %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
+ %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
+ %input_zp = "tosa.const"() <{values = dense<1> : tensor<1xi32>}> : () -> tensor<1xi32>
+ %output_zp = "tosa.const"() <{values = dense<0> : tensor<1xi32>}> : () -> tensor<1xi32>
+ // expected-error at +2 {{'tosa.rescale' op expect input_zp of 0, got 1}}
+ // expected-error at +1 {{failed to legalize operation 'tosa.rescale'}}
+ %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(false) : (tensor<2xi32>, tensor<1xi32>, tensor<1xi8>, tensor<1xi32>, tensor<1xi32>) -> tensor<2xi32>
+ return %0 : tensor<2xi32>
+}
+
+// -----
+
+// CHECK-LABEL: @rescale_invalid_output_zp
+func.func @rescale_invalid_output_zp(%arg0: tensor<2xi32>) -> tensor<2xi32> {
+ %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
+ %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
+ %input_zp = "tosa.const"() <{values = dense<0> : tensor<1xi32>}> : () -> tensor<1xi32>
+ %output_zp = "tosa.const"() <{values = dense<-1> : tensor<1xi32>}> : () -> tensor<1xi32>
+ // expected-error at +2 {{'tosa.rescale' op expect output_zp of 0, got -1}}
+ // expected-error at +1 {{failed to legalize operation 'tosa.rescale'}}
+ %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(false) : (tensor<2xi32>, tensor<1xi32>, tensor<1xi8>, tensor<1xi32>, tensor<1xi32>) -> tensor<2xi32>
+ return %0 : tensor<2xi32>
+}
+
+// -----
+
func.func @test_add_2d_different_ranks(%arg0: tensor<3x4xf32>, %arg1: tensor<2x3x4xf32>) -> tensor<2x3x4xf32> {
// expected-error at +1 {{'tosa.add' op operands don't have matching ranks}}
%0 = "tosa.add"(%arg0, %arg1) : (tensor<3x4xf32>, tensor<2x3x4xf32>) -> tensor<2x3x4xf32>
diff --git a/mlir/test/Dialect/Tosa/error_if_check.mlir b/mlir/test/Dialect/Tosa/error_if_check.mlir
index b87f124f64ac27..6edd8a8efe4dc5 100644
--- a/mlir/test/Dialect/Tosa/error_if_check.mlir
+++ b/mlir/test/Dialect/Tosa/error_if_check.mlir
@@ -260,6 +260,78 @@ func.func @test_error_i32_unsigned_output(%arg0: tensor<1xi8>) -> tensor<1xi32>
// -----
+func.func @test_rescale_invalid_input_zp_i32(%arg0: tensor<13x21x3xi32>) -> tensor<13x21x3xi32> {
+ %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
+ %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
+ %input_zp = "tosa.const"() <{values = dense<1> : tensor<1xi32>}> : () -> tensor<1xi32>
+ %output_zp = "tosa.const"() <{values = dense<0> : tensor<1xi32>}> : () -> tensor<1xi32>
+ // expected-error at +1 {{'tosa.rescale' op expect input_zp of 0, got 1}}
+ %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(false) : (tensor<13x21x3xi32>, tensor<1xi32>, tensor<1xi8>, tensor<1xi32>, tensor<1xi32>) -> tensor<13x21x3xi32>
+ return %0 : tensor<13x21x3xi32>
+}
+
+// -----
+
+func.func @test_rescale_invalid_input_zp_s16(%arg0: tensor<13x21x3xi16>) -> tensor<13x21x3xi16> {
+ %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
+ %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
+ %input_zp = "tosa.const"() <{values = dense<1> : tensor<1xi16>}> : () -> tensor<1xi16>
+ %output_zp = "tosa.const"() <{values = dense<0> : tensor<1xi16>}> : () -> tensor<1xi16>
+ // expected-error at +1 {{'tosa.rescale' op expect input_zp of 0, got 1}}
+ %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(false) : (tensor<13x21x3xi16>, tensor<1xi32>, tensor<1xi8>, tensor<1xi16>, tensor<1xi16>) -> tensor<13x21x3xi16>
+ return %0 : tensor<13x21x3xi16>
+}
+
+// -----
+
+func.func @test_rescale_invalid_input_zp_u16(%arg0: tensor<13x21x3xi16>) -> tensor<13x21x3xi16> {
+ %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
+ %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
+ %input_zp = "tosa.const"() <{values = dense<1> : tensor<1xi16>}> : () -> tensor<1xi16>
+ %output_zp = "tosa.const"() <{values = dense<0> : tensor<1xi16>}> : () -> tensor<1xi16>
+ // expected-error at +1 {{'tosa.rescale' op expect input_zp of 0 or 32768 for unsigned int16 input, got 1}}
+ %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(true) output_unsigned(false) : (tensor<13x21x3xi16>, tensor<1xi32>, tensor<1xi8>, tensor<1xi16>, tensor<1xi16>) -> tensor<13x21x3xi16>
+ return %0 : tensor<13x21x3xi16>
+}
+
+// -----
+
+func.func @test_rescale_invalid_output_zp_i32(%arg0: tensor<13x21x3xi32>) -> tensor<13x21x3xi32> {
+ %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
+ %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
+ %input_zp = "tosa.const"() <{values = dense<0> : tensor<1xi32>}> : () -> tensor<1xi32>
+ %output_zp = "tosa.const"() <{values = dense<-1> : tensor<1xi32>}> : () -> tensor<1xi32>
+ // expected-error at +1 {{'tosa.rescale' op expect output_zp of 0, got -1}}
+ %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(false) : (tensor<13x21x3xi32>, tensor<1xi32>, tensor<1xi8>, tensor<1xi32>, tensor<1xi32>) -> tensor<13x21x3xi32>
+ return %0 : tensor<13x21x3xi32>
+}
+
+// -----
+
+func.func @test_rescale_invalid_output_zp_s16(%arg0: tensor<13x21x3xi16>) -> tensor<13x21x3xi16> {
+ %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
+ %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
+ %input_zp = "tosa.const"() <{values = dense<0> : tensor<1xi16>}> : () -> tensor<1xi16>
+ %output_zp = "tosa.const"() <{values = dense<-1> : tensor<1xi16>}> : () -> tensor<1xi16>
+ // expected-error at +1 {{'tosa.rescale' op expect output_zp of 0, got -1}}
+ %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(true) output_unsigned(false) : (tensor<13x21x3xi16>, tensor<1xi32>, tensor<1xi8>, tensor<1xi16>, tensor<1xi16>) -> tensor<13x21x3xi16>
+ return %0 : tensor<13x21x3xi16>
+}
+
+// -----
+
+func.func @test_rescale_invalid_output_zp_u16(%arg0: tensor<13x21x3xi16>) -> tensor<13x21x3xi16> {
+ %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
+ %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
+ %input_zp = "tosa.const"() <{values = dense<0> : tensor<1xi16>}> : () -> tensor<1xi16>
+ %output_zp = "tosa.const"() <{values = dense<-1> : tensor<1xi16>}> : () -> tensor<1xi16>
+ // expected-error at +1 {{'tosa.rescale' op expect output_zp of 0 or 32768 for unsigned int16 output, got 65535}}
+ %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(true) : (tensor<13x21x3xi16>, tensor<1xi32>, tensor<1xi8>, tensor<1xi16>, tensor<1xi16>) -> tensor<13x21x3xi16>
+ return %0 : tensor<13x21x3xi16>
+}
+
+// -----
+
func.func @test_cond_if_then_not_isolated_from_above(%arg0: tensor<f32>, %arg1: tensor<f32>, %arg2: tensor<i1>) -> tensor<f32> {
// expected-error at +1 {{'tosa.cond_if' op is not conformant to the TOSA specification. It requires the 'then' region is isolated from above.}}
%0 = "tosa.cond_if"(%arg2, %arg1) ({
diff --git a/mlir/test/Dialect/Tosa/invalid.mlir b/mlir/test/Dialect/Tosa/invalid.mlir
index bf05491164f404..6f6d6fcd543595 100644
--- a/mlir/test/Dialect/Tosa/invalid.mlir
+++ b/mlir/test/Dialect/Tosa/invalid.mlir
@@ -1468,79 +1468,6 @@ func.func @test_rescale_invalid_shift_type(%arg0: tensor<13x21x3xi32>) -> tensor
// -----
-func.func @test_rescale_invalid_input_zp_i32(%arg0: tensor<13x21x3xi32>) -> tensor<13x21x3xi32> {
- %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
- %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
- %input_zp = "tosa.const"() <{values = dense<1> : tensor<1xi32>}> : () -> tensor<1xi32>
- %output_zp = "tosa.const"() <{values = dense<0> : tensor<1xi32>}> : () -> tensor<1xi32>
- // expected-error at +1 {{'tosa.rescale' op expect input_zp of 0, got 1}}
- %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(false) : (tensor<13x21x3xi32>, tensor<1xi32>, tensor<1xi8>, tensor<1xi32>, tensor<1xi32>) -> tensor<13x21x3xi32>
- return %0 : tensor<13x21x3xi32>
-}
-
-// -----
-
-func.func @test_rescale_invalid_input_zp_s16(%arg0: tensor<13x21x3xi16>) -> tensor<13x21x3xi16> {
- %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
- %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
- %input_zp = "tosa.const"() <{values = dense<1> : tensor<1xi16>}> : () -> tensor<1xi16>
- %output_zp = "tosa.const"() <{values = dense<0> : tensor<1xi16>}> : () -> tensor<1xi16>
- // expected-error at +1 {{'tosa.rescale' op expect input_zp of 0, got 1}}
- %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(false) : (tensor<13x21x3xi16>, tensor<1xi32>, tensor<1xi8>, tensor<1xi16>, tensor<1xi16>) -> tensor<13x21x3xi16>
- return %0 : tensor<13x21x3xi16>
-}
-
-// -----
-
-func.func @test_rescale_invalid_input_zp_u16(%arg0: tensor<13x21x3xi16>) -> tensor<13x21x3xi16> {
- %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
- %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
- %input_zp = "tosa.const"() <{values = dense<1> : tensor<1xi16>}> : () -> tensor<1xi16>
- %output_zp = "tosa.const"() <{values = dense<0> : tensor<1xi16>}> : () -> tensor<1xi16>
- // expected-error at +1 {{'tosa.rescale' op expect input_zp of 0 or 32768 for unsigned int16 input, got 1}}
- %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(true) output_unsigned(false) : (tensor<13x21x3xi16>, tensor<1xi32>, tensor<1xi8>, tensor<1xi16>, tensor<1xi16>) -> tensor<13x21x3xi16>
- return %0 : tensor<13x21x3xi16>
-}
-
-
-// -----
-
-func.func @test_rescale_invalid_output_zp_i32(%arg0: tensor<13x21x3xi32>) -> tensor<13x21x3xi32> {
- %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
- %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
- %input_zp = "tosa.const"() <{values = dense<0> : tensor<1xi32>}> : () -> tensor<1xi32>
- %output_zp = "tosa.const"() <{values = dense<-1> : tensor<1xi32>}> : () -> tensor<1xi32>
- // expected-error at +1 {{'tosa.rescale' op expect output_zp of 0, got -1}}
- %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(false) : (tensor<13x21x3xi32>, tensor<1xi32>, tensor<1xi8>, tensor<1xi32>, tensor<1xi32>) -> tensor<13x21x3xi32>
- return %0 : tensor<13x21x3xi32>
-}
-
-// -----
-
-func.func @test_rescale_invalid_output_zp_s16(%arg0: tensor<13x21x3xi16>) -> tensor<13x21x3xi16> {
- %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
- %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
- %input_zp = "tosa.const"() <{values = dense<0> : tensor<1xi16>}> : () -> tensor<1xi16>
- %output_zp = "tosa.const"() <{values = dense<-1> : tensor<1xi16>}> : () -> tensor<1xi16>
- // expected-error at +1 {{'tosa.rescale' op expect output_zp of 0, got -1}}
- %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(true) output_unsigned(false) : (tensor<13x21x3xi16>, tensor<1xi32>, tensor<1xi8>, tensor<1xi16>, tensor<1xi16>) -> tensor<13x21x3xi16>
- return %0 : tensor<13x21x3xi16>
-}
-
-// -----
-
-func.func @test_rescale_invalid_output_zp_u16(%arg0: tensor<13x21x3xi16>) -> tensor<13x21x3xi16> {
- %multiplier = "tosa.const"() <{values = dense<1073741824> : tensor<1xi32> }> : () -> tensor<1xi32>
- %shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
- %input_zp = "tosa.const"() <{values = dense<0> : tensor<1xi16>}> : () -> tensor<1xi16>
- %output_zp = "tosa.const"() <{values = dense<-1> : tensor<1xi16>}> : () -> tensor<1xi16>
- // expected-error at +1 {{'tosa.rescale' op expect output_zp of 0 or 32768 for unsigned int16 output, got 65535}}
- %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp scale32(true) rounding_mode<SINGLE_ROUND> per_channel(false) input_unsigned(false) output_unsigned(true) : (tensor<13x21x3xi16>, tensor<1xi32>, tensor<1xi8>, tensor<1xi16>, tensor<1xi16>) -> tensor<13x21x3xi16>
- return %0 : tensor<13x21x3xi16>
-}
-
-// -----
-
func.func @test_rescale_invalid_multiplier_i16(%arg0: tensor<13x21x3xi16>) -> tensor<13x21x3xi16> {
%multiplier = "tosa.const"() <{values = dense<19689> : tensor<1xi16> }> : () -> tensor<1xi16>
%shift = "tosa.const"() <{values = dense<30> : tensor<1xi8> }> : () -> tensor<1xi8>
More information about the Mlir-commits
mailing list