[Mlir-commits] [mlir] [mlir][tosa] Interpret boolean values correctly in cast folder (PR #147078)

Luke Hutton llvmlistbot at llvm.org
Fri Jul 4 08:25:01 PDT 2025


https://github.com/lhutton1 created https://github.com/llvm/llvm-project/pull/147078

Previously the cast folder would sign extend boolean values, leading "true" to be casted to a value of -1 instead of 1. This change ensures i1 values are zero extended, since i1 is used as a boolean value in TOSA. According to the TOSA spec, the result of a boolean cast with value "true" to another integer type should give a result of 1.

Fixes https://github.com/llvm/llvm-project/issues/57951

>From 55a11177ac79d49c087f596c7b837f69ae75e25e Mon Sep 17 00:00:00 2001
From: Luke Hutton <luke.hutton at arm.com>
Date: Fri, 4 Jul 2025 11:42:49 +0000
Subject: [PATCH] [mlir][tosa] Interpret boolean values correctly in cast
 folder

Previously the cast folder would sign extend boolean values, leading
"true" to be casted to a value of -1 instead of 1. This change
ensures i1 values are zero extended, since i1 is used as a boolean
value in TOSA.

Fixes https://github.com/llvm/llvm-project/issues/57951

Change-Id: I21486cae0b8ad1cf7901e7b3eb92c1ad56c3797c
---
 mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp |  6 ++++--
 mlir/test/Dialect/Tosa/canonicalize.mlir           | 11 +++++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
index 1d21096e8920b..e2a2f2935b6b4 100644
--- a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
+++ b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
@@ -1301,7 +1301,8 @@ OpFoldResult CastOp::fold(FoldAdaptor adaptor) {
     }
 
     if (llvm::isa<IntegerType>(inETy) && llvm::isa<IntegerType>(outETy)) {
-      auto unsignIn = llvm::cast<IntegerType>(inETy).isUnsignedInteger();
+      const auto inIntType = llvm::cast<IntegerType>(inETy);
+      auto unsignIn = inIntType.isUnsignedInteger();
       bool trunc =
           inETy.getIntOrFloatBitWidth() > outETy.getIntOrFloatBitWidth();
       auto intVal = operand.getSplatValue<APInt>();
@@ -1309,7 +1310,8 @@ OpFoldResult CastOp::fold(FoldAdaptor adaptor) {
 
       if (trunc) {
         intVal = intVal.trunc(bitwidth);
-      } else if (unsignIn) {
+      // i1 types are boolean in TOSA
+      } else if (unsignIn || inIntType.isInteger(1)) {
         intVal = intVal.zext(bitwidth);
       } else {
         intVal = intVal.sext(bitwidth);
diff --git a/mlir/test/Dialect/Tosa/canonicalize.mlir b/mlir/test/Dialect/Tosa/canonicalize.mlir
index 27280807b0282..11c8d54fda055 100644
--- a/mlir/test/Dialect/Tosa/canonicalize.mlir
+++ b/mlir/test/Dialect/Tosa/canonicalize.mlir
@@ -1338,3 +1338,14 @@ func.func @no_fold_mul_result_exceeds_i32() -> tensor<i32> {
     %3 = tosa.mul %0, %1, %2 : (tensor<i32>, tensor<i32>, tensor<1xi8>) -> tensor<i32>
     return %3 : tensor<i32>
 }
+
+// -----
+
+// CHECK-LABEL: @test_fold_i1_to_i32_cast
+// CHECK: %[[OUT:.*]] = "tosa.const"() <{values = dense<1> : tensor<i32>}> : () -> tensor<i32>
+// CHECK: return %[[OUT]] : tensor<i32>
+func.func @test_fold_i1_to_i32_cast() -> tensor<i32> {
+  %0 = "tosa.const"() <{values = dense<1> : tensor<i1>}> : () -> tensor<i1>
+  %1 = "tosa.cast"(%0) : (tensor<i1>) -> tensor<i32>
+  return %1 : tensor<i32>
+}



More information about the Mlir-commits mailing list