[Mlir-commits] [mlir] [mlir][tosa] Fix negate lowering to skip no-op casts (PR #173299)

Vitalii Shutov llvmlistbot at llvm.org
Mon Dec 22 11:08:19 PST 2025


https://github.com/Lallapallooza updated https://github.com/llvm/llvm-project/pull/173299

>From 5338aaaaf2f625be44a83a4c41193be596efb64b Mon Sep 17 00:00:00 2001
From: Vitalii Shutov <vitalii.shutov at arm.com>
Date: Mon, 22 Dec 2025 18:55:22 +0000
Subject: [PATCH] [mlir][tosa] Fix negate lowering to skip no-op casts

Change-Id: Ie45b1665c84e6636d44e1a1dee550db26b500a86
---
 .../Conversion/TosaToLinalg/TosaToLinalg.cpp  | 20 ++++++++++++-------
 .../TosaToLinalg/tosa-to-linalg.mlir          | 10 ++++++++++
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
index 99b5a2cb0a501..6db924dd090c8 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
@@ -226,18 +226,22 @@ static Value createLinalgBodyCalculationForElementwiseOp(
             rewriter, loc, rewriter.getIntegerAttr(intermediateType, zpAdd));
       } else {
         intermediateType = rewriter.getIntegerType(intermediateBitWidth);
-        auto arg1 =
-            arith::ExtSIOp::create(rewriter, loc, intermediateType, args[1]);
-        auto arg2 =
-            arith::ExtSIOp::create(rewriter, loc, intermediateType, args[2]);
+        Value arg1 = args[1];
+        Value arg2 = args[2];
+        // Avoid verifier-invalid no-op sign-extends; only widen when needed.
+        if (arg1.getType() != intermediateType)
+          arg1 = arith::ExtSIOp::create(rewriter, loc, intermediateType, arg1);
+        if (arg2.getType() != intermediateType)
+          arg2 = arith::ExtSIOp::create(rewriter, loc, intermediateType, arg2);
         zpAddValue =
             arith::AddIOp::create(rewriter, loc, intermediateType, arg1, arg2);
       }
 
       // The negation can be applied by doing:
       //  outputValue = inZp + outZp - inputValue
-      auto ext =
-          arith::ExtSIOp::create(rewriter, loc, intermediateType, args[0]);
+      Value ext = args[0];
+      if (ext.getType() != intermediateType)
+        ext = arith::ExtSIOp::create(rewriter, loc, intermediateType, ext);
       auto sub = arith::SubIOp::create(rewriter, loc, zpAddValue, ext);
 
       // Clamp to the negation range.
@@ -249,7 +253,9 @@ static Value createLinalgBodyCalculationForElementwiseOp(
           APInt::getSignedMaxValue(inputBitWidth).getSExtValue());
       auto clamp = clampIntHelper(loc, sub, min, max, rewriter, false);
 
-      // Truncate to the final value.
+      // Truncate to the final value, skipping no-op trunci when widths match.
+      if (clamp.getType() == elementTy)
+        return clamp;
       return arith::TruncIOp::create(rewriter, loc, elementTy, clamp);
     }
   }
diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
index e84ed80f173b0..e6bd800a0cf0a 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
@@ -2645,3 +2645,13 @@ func.func @mul_no_const_shift(%arg0: tensor<2x3xi32>, %arg1: tensor<2x3xi32>, %a
   %0 = tosa.mul %arg0, %arg1, %arg2 : (tensor<2x3xi32>, tensor<2x3xi32>, tensor<1xi8>) -> tensor<2x3xi32>
   return %0 : tensor<2x3xi32>
 }
+// -----
+
+// CHECK-LABEL: @negate_i64_no_noop_cast
+// CHECK: linalg.generic
+// CHECK-NOT: arith.extsi {{.*}} : i64 to i64
+// CHECK-NOT: arith.trunci {{.*}} : i64 to i64
+func.func @negate_i64_no_noop_cast(%arg0: tensor<4xi64>, %in_zp: tensor<1xi64>, %out_zp: tensor<1xi64>) -> tensor<4xi64> {
+  %neg = tosa.negate %arg0, %in_zp, %out_zp : (tensor<4xi64>, tensor<1xi64>, tensor<1xi64>) -> tensor<4xi64>
+  return %neg : tensor<4xi64>
+}



More information about the Mlir-commits mailing list