This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new 84d05e9a24 [LLVM][Codegen] Cast NaN to bool gives true (#18772)
84d05e9a24 is described below

commit 84d05e9a24e1587886eef7552f9d80c475637e7e
Author: Nguyen Duy Loc <[email protected]>
AuthorDate: Fri Feb 13 19:21:27 2026 +0700

    [LLVM][Codegen] Cast NaN to bool gives true (#18772)
    
    Due to some recent changes to CI, PR #18646 will be closed and a new PR
    created. This PR was created by opening a new pull request on the main
    branch.
    - Update test code: using tvmscript instead of schedule te.
    
    ### Summary
    Cast NaN to bool gives true to ensure consistency with the existing
    framework (C, C++, Python, Torch, NumPy, OnnxRuntime, ...).
    
    ### Steps to Reproduce
    - Python:
    ```
    bool(float('nan'))
    ```
    > True
    
    - Torch:
    ```
    torch.tensor(float("nan"), dtype=torch.float32).to(torch.bool)
    ```
    > tensor(True)
    
    - Numpy:
    ```
    import numpy as np
    bool(np.nan)
    ```
    > True
    
    - TVM:
    ```
    class Module:
        def main(x: R.Tensor((), dtype="float32")) -> R.Tensor((), 
dtype="bool"):
            with R.dataflow():
                gv: R.Tensor((), dtype="bool") = R.astype(x, dtype="bool")
                R.output(gv)
            return gv
    x = np.array(float("nan"), dtype="float32")
    ```
    > False
    
    ### Expected
    - TVM:
    ```
    class Module:
        def main(x: R.Tensor((), dtype="float32")) -> R.Tensor((), 
dtype="bool"):
            with R.dataflow():
                gv: R.Tensor((), dtype="bool") = R.astype(x, dtype="bool")
                R.output(gv)
            return gv
    x = np.array(float("nan"), dtype="float32")
    ```
    > True
    
    ### Resolved
    - Replace the instruction `fcmp one` with `fcmp une` in LLVM.
    - Citation:
    https://releases.llvm.org/20.1.0/docs/LangRef.html#fcmp-instruction
    <img width="400" height="200" alt="PR1-18605"
    
src="https://github.com/user-attachments/assets/cffeebd8-dfe6-436e-9c4c-61e1e84d5439";
    />
    
    - Related:
    +
    
https://stackoverflow.com/questions/9158567/nan-to-bool-conversion-true-or-false
    +
    
https://stackoverflow.com/questions/15686318/why-do-not-a-number-values-equal-true-when-cast-as-boolean-in-python-numpy
    
    - Fixed: #18605
---
 src/target/llvm/codegen_llvm.cc                  |  2 +-
 tests/python/codegen/test_target_codegen_llvm.py | 24 ++++++++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/target/llvm/codegen_llvm.cc b/src/target/llvm/codegen_llvm.cc
index 0a2ae8b09e..b7004dec32 100644
--- a/src/target/llvm/codegen_llvm.cc
+++ b/src/target/llvm/codegen_llvm.cc
@@ -928,7 +928,7 @@ llvm::Value* CodeGenLLVM::CreateCast(DataType from, 
DataType to, llvm::Value* va
   } else if (to.is_bool()) {
     if (from.is_float()) {
       llvm::Constant* zero = llvm::ConstantFP::get(DTypeToLLVMType(from), 0.);
-      return builder_->CreateFCmpONE(value, zero);
+      return builder_->CreateFCmpUNE(value, zero);
     } else {
       llvm::Constant* zero = llvm::ConstantInt::get(DTypeToLLVMType(from), 0);
       return builder_->CreateICmpNE(value, zero);
diff --git a/tests/python/codegen/test_target_codegen_llvm.py 
b/tests/python/codegen/test_target_codegen_llvm.py
index da58f5bb45..78f2abf523 100644
--- a/tests/python/codegen/test_target_codegen_llvm.py
+++ b/tests/python/codegen/test_target_codegen_llvm.py
@@ -370,6 +370,30 @@ def test_llvm_bool():
     tvm.testing.assert_allclose(c.numpy(), c_np)
 
 
[email protected]_llvm
+def test_llvm_cast_float_to_bool():
+    @I.ir_module
+    class Module:
+        @T.prim_func
+        def main(A: T.Buffer((4,), "float32"), C: T.Buffer((4,), "bool")):
+            T.func_attr({"tir.noalias": True})
+            for i in range(4):
+                with T.sblock("C"):
+                    v_i = T.axis.spatial(4, i)
+                    T.reads(A[v_i])
+                    T.writes(C[v_i])
+                    C[v_i] = T.Cast("bool", A[v_i])
+
+    n = 4
+    f = tvm.compile(Module, target="llvm")
+    dev = tvm.cpu(0)
+    a = tvm.runtime.tensor(np.array([0.0, 1.0, np.nan, np.inf], 
dtype="float32"), dev)
+    c = tvm.runtime.empty((n,), dtype="bool", device=dev)
+    f(a, c)
+    c_np = np.array([False, True, True, True], dtype="bool")
+    tvm.testing.assert_allclose(c.numpy(), c_np)
+
+
 @tvm.testing.requires_llvm
 def test_rank_zero():
     @I.ir_module

Reply via email to