-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[TOSA] Fix negate maxValue computation #126295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
getInput1Zp() returns an unsigned value which means in case of negative zero point value the max intermediate value computation currently goes wrong. Use getInput1ZpAttr() instead which returns an APInt and allows easy sign extension to int64_t.
@llvm/pr-subscribers-mlir @llvm/pr-subscribers-mlir-tosa Author: Thomas Preud'homme (RoboTux) ChangesgetInput1Zp() returns an unsigned value which means in case of negative Full diff: https://github.com/llvm/llvm-project/pull/126295.diff 2 Files Affected:
diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
index e4f055ea2f5c41b..de6a156ed3f5729 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
@@ -146,11 +146,11 @@ static Value createLinalgBodyCalculationForElementwiseOp(
return rewriter.create<arith::NegFOp>(loc, resultTypes, args);
if (isa<IntegerType>(elementTy)) {
- auto inputZpAttr = cast<tosa::NegateOp>(op).getInput1Zp();
- auto outputZpAttr = cast<tosa::NegateOp>(op).getOutputZp();
+ auto inputZpAttr = cast<tosa::NegateOp>(op).getInput1ZpAttr();
+ auto outputZpAttr = cast<tosa::NegateOp>(op).getOutputZpAttr();
- const int64_t inZp = inputZpAttr ? *inputZpAttr : 0;
- const int64_t outZp = outputZpAttr ? *outputZpAttr : 0;
+ const int64_t inZp = inputZpAttr ? inputZpAttr.getValue().getSExtValue() : 0;
+ const int64_t outZp = outputZpAttr ? outputZpAttr.getValue().getSExtValue() : 0;
if (!inZp && !outZp) {
auto constant = rewriter.create<arith::ConstantOp>(
diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
index 3031434e6d4ba1f..d8ba28a3ce8871d 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
@@ -911,12 +911,25 @@ func.func @test_negate_quantized(%arg0: tensor<1xi8>) -> () {
// CHECK: linalg.yield [[TRUNC]]
%2 = tosa.negate %arg0 {input1_zp = 32640 : i32, output_zp = 0 : i32} : (tensor<1xi8>) -> tensor<1xi8>
+ // CHECK: linalg.generic
+ // CHECK: ^bb0(%[[BBARG0:.+]]: i8,
+ // CHECK: [[C_128:%.+]] = arith.constant -128
+ // CHECK: [[EXT:%.+]] = arith.extsi %[[BBARG0]] : i8 to i16
+ // CHECK: [[SUB:%.+]] = arith.subi [[C_128]], [[EXT]]
+ // CHECK: [[MIN:%.+]] = arith.constant -128
+ // CHECK: [[MAX:%.+]] = arith.constant 127
+ // CHECK: [[LBOUND:%.+]] = arith.maxsi [[MIN]], [[SUB]]
+ // CHECK: [[UBOUND:%.+]] = arith.minsi [[MAX]], [[LBOUND]]
+ // CHECK: [[TRUNC:%.+]] = arith.trunci [[UBOUND]]
+ // CHECK: linalg.yield [[TRUNC]]
+ %3 = tosa.negate %arg0 {input1_zp = -128 : i32, output_zp = 0 : i32} : (tensor<1xi8>) -> tensor<1xi8>
+
// CHECK: linalg.generic
// CHECK: ^bb0(%[[BBARG0:.+]]: i8,
// CHECK: [[ZERO:%.+]] = arith.constant 0
// CHECK: [[SUB:%.+]] = arith.subi [[ZERO]],
// CHECK: linalg.yield [[SUB]]
- %3 = tosa.negate %arg0 {quantization_info = #tosa.unary_quant<input_zp = 0, output_zp = 0>} : (tensor<1xi8>) -> tensor<1xi8>
+ %4 = tosa.negate %arg0 {quantization_info = #tosa.unary_quant<input_zp = 0, output_zp = 0>} : (tensor<1xi8>) -> tensor<1xi8>
return
}
|
@llvm/pr-subscribers-mlir-linalg Author: Thomas Preud'homme (RoboTux) ChangesgetInput1Zp() returns an unsigned value which means in case of negative Full diff: https://github.com/llvm/llvm-project/pull/126295.diff 2 Files Affected:
diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
index e4f055ea2f5c41b..de6a156ed3f5729 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
@@ -146,11 +146,11 @@ static Value createLinalgBodyCalculationForElementwiseOp(
return rewriter.create<arith::NegFOp>(loc, resultTypes, args);
if (isa<IntegerType>(elementTy)) {
- auto inputZpAttr = cast<tosa::NegateOp>(op).getInput1Zp();
- auto outputZpAttr = cast<tosa::NegateOp>(op).getOutputZp();
+ auto inputZpAttr = cast<tosa::NegateOp>(op).getInput1ZpAttr();
+ auto outputZpAttr = cast<tosa::NegateOp>(op).getOutputZpAttr();
- const int64_t inZp = inputZpAttr ? *inputZpAttr : 0;
- const int64_t outZp = outputZpAttr ? *outputZpAttr : 0;
+ const int64_t inZp = inputZpAttr ? inputZpAttr.getValue().getSExtValue() : 0;
+ const int64_t outZp = outputZpAttr ? outputZpAttr.getValue().getSExtValue() : 0;
if (!inZp && !outZp) {
auto constant = rewriter.create<arith::ConstantOp>(
diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
index 3031434e6d4ba1f..d8ba28a3ce8871d 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
@@ -911,12 +911,25 @@ func.func @test_negate_quantized(%arg0: tensor<1xi8>) -> () {
// CHECK: linalg.yield [[TRUNC]]
%2 = tosa.negate %arg0 {input1_zp = 32640 : i32, output_zp = 0 : i32} : (tensor<1xi8>) -> tensor<1xi8>
+ // CHECK: linalg.generic
+ // CHECK: ^bb0(%[[BBARG0:.+]]: i8,
+ // CHECK: [[C_128:%.+]] = arith.constant -128
+ // CHECK: [[EXT:%.+]] = arith.extsi %[[BBARG0]] : i8 to i16
+ // CHECK: [[SUB:%.+]] = arith.subi [[C_128]], [[EXT]]
+ // CHECK: [[MIN:%.+]] = arith.constant -128
+ // CHECK: [[MAX:%.+]] = arith.constant 127
+ // CHECK: [[LBOUND:%.+]] = arith.maxsi [[MIN]], [[SUB]]
+ // CHECK: [[UBOUND:%.+]] = arith.minsi [[MAX]], [[LBOUND]]
+ // CHECK: [[TRUNC:%.+]] = arith.trunci [[UBOUND]]
+ // CHECK: linalg.yield [[TRUNC]]
+ %3 = tosa.negate %arg0 {input1_zp = -128 : i32, output_zp = 0 : i32} : (tensor<1xi8>) -> tensor<1xi8>
+
// CHECK: linalg.generic
// CHECK: ^bb0(%[[BBARG0:.+]]: i8,
// CHECK: [[ZERO:%.+]] = arith.constant 0
// CHECK: [[SUB:%.+]] = arith.subi [[ZERO]],
// CHECK: linalg.yield [[SUB]]
- %3 = tosa.negate %arg0 {quantization_info = #tosa.unary_quant<input_zp = 0, output_zp = 0>} : (tensor<1xi8>) -> tensor<1xi8>
+ %4 = tosa.negate %arg0 {quantization_info = #tosa.unary_quant<input_zp = 0, output_zp = 0>} : (tensor<1xi8>) -> tensor<1xi8>
return
}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
getInput1Zp() returns an unsigned value which means in case of negative zero point value the max intermediate value computation currently goes wrong. Use getInput1ZpAttr() instead which returns an APInt and allows easy sign extension to int64_t.
getInput1Zp() returns an unsigned value which means in case of negative
zero point value the max intermediate value computation currently goes
wrong. Use getInput1ZpAttr() instead which returns an APInt and allows
easy sign extension to int64_t.