[Resolved] Is there a good way to implement `isnan` op?

As title.
Firstly, I want use call_pure_extern, but isnan is related to platform when using LLVM (depends on libc).

Float32 Float64
Win _isnanf _isnan/isnan
OSX __isnanf __isnand/isnan
Linux isnanf isnan

Then I want to use x!=x to check if a float number is NaN.
However, there are 2 problems.

  1. An expression like a = (b != b) will be rewrite to a = 0.
  2. In LLVM codegen, fcmp use one but not une, so that it cannot be used to check NaN.

Compared with call libc function, I prefer we use unordered flag of LLVM. However, I can not be sure what is the performance cost it will introduce into. We should benchmark it. If there is performance downgrade, we should provide one flag and keep ordered flag of LLVM be default.

Is there a flag or function call to disable rewriting?

I don’t fully understand what is the meaning of disable rewriting. If you ask the flag of LLVM, for NE, should be here:

You could try it and decide what to do next.

I have tried to change this to UNE, however, I cannot get expected result.


In the built C code, it assigns a const 0.

You could debug why it doesn’t work.

Maybe you could print the fast math flags of builder_. builder_->getFastMathFlags() I suspect we set it in somewhere be NoNan or fast LLVM Language Reference Manual — LLVM 21.0.0git documentation

The problem is that we need to avoid both HalideIR simplification (i.e. a == a simplifies to True), and b) LLVM IR simplification (similar problem). I believe a clean approach is to follow Halide, which introduces an is_nan operator (https://github.com/halide/Halide/blob/176b2fa96cb62a4a7a785952c4f576bc99d1a6d4/test/correctness/isnan.cpp#L41, https://github.com/halide/Halide/blob/7a47735b148bceb4a9afcd81f7d286c27126aaba/src/IROperator.cpp#L1886-L1898), which is specifically lowered in LLVM codegen to handle the fast math flags (https://github.com/halide/Halide/blob/ac204e9197041a21c42258f253e6cbccad2bdf1f/src/CodeGen_LLVM.cpp#L3143-L3162) and in C source to use the standard x != x trick (https://github.com/halide/Halide/blob/b7e13681a072f8d887a1752c54ceea45c2e3faa1/src/CodeGen_C.cpp#L109).

2 Likes