[TOSA] Fix negate maxValue computation (#126295)

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.
This commit is contained in:
Thomas Preud'homme 2025-02-08 09:23:32 +00:00 committed by GitHub
parent 95922d8334
commit 027aa70ea4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 20 additions and 5 deletions

View File

@ -146,11 +146,13 @@ 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>(

View File

@ -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
}