[Mlir-commits] [mlir] [mlir][TOSA] Fix folding of fp casts to bool (PR #232254)

Dhruv Chauhan llvmlistbot at llvm.org
Thu Oct 15 03:13:38 PDT 2026


https://github.com/dchauhan-arm created https://github.com/llvm/llvm-project/pull/232254

Fold floating point splat casts to i1 using a nonzero comparison instead of rounding to an integer.

Add regression test for signed zero and positive and negative fraction values.

>From b4f14b03e40b596327d5dc2da72e1856ac5575e4 Mon Sep 17 00:00:00 2001
From: Dhruv Chauhan <dhruv.chauhan at arm.com>
Date: Thu, 15 Oct 2026 11:01:39 +0100
Subject: [PATCH] [mlir][TOSA] Fix folding of fp casts to bool

Fold floating point splat casts to i1 using a nonzero comparison instead
of rounding to an integer.

Add regression test for signed zero and positive and negative fraction
values.
---
 .../Dialect/Tosa/IR/TosaCanonicalizations.cpp |  4 +++-
 mlir/test/Dialect/Tosa/canonicalize.mlir      | 19 +++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
index f97446c294247c..a482e82e153019 100644
--- a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
+++ b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp
@@ -2063,10 +2063,12 @@ OpFoldResult CastOp::fold(FoldAdaptor adaptor) {
     }
 
     if (llvm::isa<FloatType>(inETy) && llvm::isa<IntegerType>(outETy)) {
+      auto floatVal = operand.getSplatValue<APFloat>();
+      if (outETy.isInteger(1))
+        return SplatElementsAttr::get(outTy, !floatVal.isZero());
       auto unsign = llvm::cast<IntegerType>(outETy).isUnsignedInteger();
       auto intVal = APSInt(
           llvm::cast<IntegerType>(outETy).getIntOrFloatBitWidth(), unsign);
-      auto floatVal = operand.getSplatValue<APFloat>();
       bool exact;
       floatVal.convertToInteger(intVal, llvm::RoundingMode::NearestTiesToEven,
                                 &exact);
diff --git a/mlir/test/Dialect/Tosa/canonicalize.mlir b/mlir/test/Dialect/Tosa/canonicalize.mlir
index 48e429846b6692..c29d9f74fa7a29 100644
--- a/mlir/test/Dialect/Tosa/canonicalize.mlir
+++ b/mlir/test/Dialect/Tosa/canonicalize.mlir
@@ -1524,6 +1524,25 @@ func.func @test_fold_i32_to_i1_cast() -> tensor<i1> {
 
 // -----
 
+// Fold both signed zeros to false and nonzero fractions to true.
+// CHECK-LABEL: @test_fold_f32_to_i1_cast
+// CHECK-DAG: %[[FALSE:.*]] = tosa.const values(dense<false> : tensor<i1>)
+// CHECK-DAG: %[[TRUE:.*]] = tosa.const values(dense<true> : tensor<i1>)
+// CHECK: return %[[FALSE]], %[[FALSE]], %[[TRUE]], %[[TRUE]]
+func.func @test_fold_f32_to_i1_cast() -> (tensor<i1>, tensor<i1>, tensor<i1>, tensor<i1>) {
+  %zero = "tosa.const"() <{values = dense<0.0> : tensor<f32>}> : () -> tensor<f32>
+  %neg_zero = "tosa.const"() <{values = dense<-0.0> : tensor<f32>}> : () -> tensor<f32>
+  %positive = "tosa.const"() <{values = dense<0.01> : tensor<f32>}> : () -> tensor<f32>
+  %negative = "tosa.const"() <{values = dense<-0.01> : tensor<f32>}> : () -> tensor<f32>
+  %0 = tosa.cast %zero : (tensor<f32>) -> tensor<i1>
+  %1 = tosa.cast %neg_zero : (tensor<f32>) -> tensor<i1>
+  %2 = tosa.cast %positive : (tensor<f32>) -> tensor<i1>
+  %3 = tosa.cast %negative : (tensor<f32>) -> tensor<i1>
+  return %0, %1, %2, %3 : tensor<i1>, tensor<i1>, tensor<i1>, tensor<i1>
+}
+
+// -----
+
 // CHECK-LABEL: @test_canonicalize_non_narrowing_cast_i8_to_i32
 // CHECK: %[[OUT:.*]] = tosa.cast %arg0 input_unsigned(false) : (tensor<13x21x3xi8>) -> tensor<13x21x3xi32>
 // CHECK: return %[[OUT]] : tensor<13x21x3xi32>



More information about the Mlir-commits mailing list