[Mlir-commits] [mlir] 3b5f2e7 - [mlir][tosa] Honor input_unsigned when lowering tosa.cast to linalg (#228233)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Oct 5 01:40:09 PDT 2026


Author: Maher Ahmed Maher Shola
Date: 2026-10-05T09:40:01+01:00
New Revision: 3b5f2e77cf531e0d6b138bf5eca56b3ac4f439a8

URL: https://github.com/llvm/llvm-project/commit/3b5f2e77cf531e0d6b138bf5eca56b3ac4f439a8
DIFF: https://github.com/llvm/llvm-project/commit/3b5f2e77cf531e0d6b138bf5eca56b3ac4f439a8.diff

LOG: [mlir][tosa] Honor input_unsigned when lowering tosa.cast to linalg (#228233)

The TosaToLinalg lowering ignored the `input_unsigned` attribute of
`tosa.cast` (added in #215838), so unsigned inputs were converted as
signed: an i8 0xFF cast to i32 gave -1 instead of 255.

When the attribute is set, use `arith.uitofp` for int -> float and
`arith.extui` for widening int -> int, since the TOSA 1.1 CAST
pseudocode zero-extends the input. Narrowing and int -> bool are
unchanged.

AI disclosure: I found this bug with a testing harness built with Claude
(Claude Code). The bug were reviewed by me . The fix and the test were
built and tested by me



Assisted-by: Claude

Added: 
    

Modified: 
    mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
    mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
index 069e6f1d1ae59..b2a8360ee0c2b 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
@@ -585,6 +585,9 @@ static Value createLinalgBodyCalculationForElementwiseOp(
     bool bitExtend =
         srcTy.getIntOrFloatBitWidth() < dstTy.getIntOrFloatBitWidth();
 
+    // With `input_unsigned`, the integer input is read as unsigned.
+    bool inputUnsigned = cast<tosa::CastOp>(op).getInputUnsigned();
+
     if (srcTy == dstTy)
       return args.front();
 
@@ -617,6 +620,11 @@ static Value createLinalgBodyCalculationForElementwiseOp(
                                      unrealizedCast);
     }
 
+    // Unsigned inputs are converted with UIToFP.
+    if (inputUnsigned && arith::UIToFPOp::areCastCompatible(srcTy, dstTy))
+      return createWithDefaultProperties<arith::UIToFPOp>(rewriter, loc,
+                                                          resultTypes, args);
+
     // All other si-to-fp conversions should be handled by SIToFP.
     if (arith::SIToFPOp::areCastCompatible(srcTy, dstTy))
       return arith::SIToFPOp::create(rewriter, loc, resultTypes, args,
@@ -733,6 +741,12 @@ static Value createLinalgBodyCalculationForElementwiseOp(
                                    args.front(), zero);
     }
 
+    // Unsigned inputs are zero-extended.
+    if (inputUnsigned && isa<IntegerType>(srcTy) && isa<IntegerType>(dstTy) &&
+        bitExtend)
+      return createWithDefaultProperties<arith::ExtUIOp>(rewriter, loc,
+                                                         resultTypes, args);
+
     if (isa<IntegerType>(srcTy) && isa<IntegerType>(dstTy) && bitExtend)
       return arith::ExtSIOp::create(rewriter, loc, resultTypes, args,
                                     ArrayRef<NamedAttribute>());

diff  --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
index 96fcda1108634..9aa6d72405426 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir
@@ -792,6 +792,29 @@ func.func @test_simple_ui8(%arg0: tensor<1xi8>) -> () {
 
 // -----
 
+// CHECK-LABEL: @test_cast_input_unsigned
+func.func @test_cast_input_unsigned(%arg0: tensor<1xi8>, %arg1: tensor<1xi16>, %arg2: tensor<1xi32>) -> () {
+  // CHECK: linalg.generic
+  // CHECK: arith.uitofp %{{.*}} : i8 to f32
+  %0 = tosa.cast %arg0 input_unsigned(true) : (tensor<1xi8>) -> tensor<1xf32>
+
+  // CHECK: linalg.generic
+  // CHECK: arith.extui %{{.*}} : i16 to i32
+  %1 = tosa.cast %arg1 input_unsigned(true) : (tensor<1xi16>) -> tensor<1xi32>
+
+  // CHECK: linalg.generic
+  // CHECK: arith.trunci %{{.*}} : i32 to i16
+  %2 = tosa.cast %arg2 input_unsigned(true) : (tensor<1xi32>) -> tensor<1xi16>
+
+  // CHECK: linalg.generic
+  // CHECK: arith.cmpi ne
+  %3 = tosa.cast %arg0 input_unsigned(true) : (tensor<1xi8>) -> tensor<1xi1>
+
+  return
+}
+
+// -----
+
 // CHECK-LABEL: @test_i8
 func.func @test_i8(%arg0: tensor<1xi8>) -> () {
   // CHECK: linalg.generic


        


More information about the Mlir-commits mailing list