<div dir="ltr">Hi all,<br><br>Some time ago a new intrinsic `llvm.isnan` was introduced, which was intended to represent IEEE-754 operation `isNaN` as well as a family of C library functions `isnan*`. Then a concern was raised (see  <a href="https://reviews.llvm.org/D104854">https://reviews.llvm.org/D104854</a>) that this functionality should be removed. Discussion in the subsequent RFC (<a href="https://lists.llvm.org/pipermail/llvm-dev/2021-August/152257.html">https://lists.llvm.org/pipermail/llvm-dev/2021-August/152257.html</a>) came to consensus that such intrinsic is necessary. Nevertheless the patches related to the new intrinsic were reverted. I have to restart the discussion in hope to convince the community that this intrinsic and other classification functions are necessary.<br><br>There are two main reasons why this intrinsic is necessary:<br>   1. It allows correct implementation of `isnan` if strict floating point semantics is in effect,<br>       2. It allows preserving the check in -ffast-math compilation.<br><br>To facilitate the discussion let's concentrate on the first problem.<br><br>Previously the frontend intrinsic `__builtin_isnan` was converted into `cmp uno` during IR generation in clang codegen. This solution is not suitable if FP exceptions are not ignored, because compare instructions raise exceptions if its argument is signaling NaN. Both IEEE-754 (5.7.2) an C standard  (<a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf">http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf</a>, F.3p6) demand that this function does not raise floating point exceptions.  There was no target-independent IR construct that could represent `isnan`.<br><br>This drawback was significant enough and some attempts to alleviate it were undertaken. In <a href="https://reviews.llvm.org/D95948">https://reviews.llvm.org/D95948</a> `isnan` was implemented using integer operations in strictfp functions. It however is not suitable for targets where a more efficient way exists, like dedicated instruction. Another solution was implemented in <a href="https://reviews.llvm.org/D96568">https://reviews.llvm.org/D96568</a>, where a hook `clang::TargetCodeGenInfo::testFPKind` was introduced, which injects target specific code into IR. Such a solution makes IR more target-dependent and prevents some IR-level optimizations.<br><br>To have a solution suitable for all cases, a new intrinsic function `llvm.isnan` was introduced (<a href="https://reviews.llvm.org/D104854">https://reviews.llvm.org/D104854</a>). It protects the check from undesirable optimizations and preserves it till selector, where it can be lowered in optimal for a particular target way.<br><br>Other classification functions also need their own intrinsics. In strictfp mode even a check for zero (`iszero`) cannot be made by comparing a value against zero, - if the value is signaling NaN, FP exceptions would be raised. James Y Knight in the previous discussion (<a href="https://lists.llvm.org/pipermail/llvm-dev/2021-August/152282.html">https://lists.llvm.org/pipermail/llvm-dev/2021-August/152282.html</a>) listed such "non-computational" functions, which should not signal if provided with an sNAN argument.<br><br>It looks like new intrinsic is the only consistent and in target-agnostic way to implement these checks in all environments including the case when FP exceptions are not ignored.<br><br>Any feedback is welcome.<div><br><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">Thanks,<br>--Serge<br></div></div></div></div>