[cfe-dev] Do we need intrinsics for floating-point classification functions?

Serge Pavlov via cfe-dev cfe-dev at lists.llvm.org
Thu Sep 2 05:33:21 PDT 2021

Hi all,

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
https://reviews.llvm.org/D104854) that this functionality should be
removed. Discussion in the subsequent RFC (
https://lists.llvm.org/pipermail/llvm-dev/2021-August/152257.html) 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.

There are two main reasons why this intrinsic is necessary:
1. It allows correct implementation of `isnan` if strict floating point
semantics is in effect,
2. It allows preserving the check in -ffast-math compilation.

To facilitate the discussion let's concentrate on the first problem.

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  (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf,
F.3p6) demand that this function does not raise floating point exceptions.
There was no target-independent IR construct that could represent `isnan`.

This drawback was significant enough and some attempts to alleviate it were
undertaken. In https://reviews.llvm.org/D95948 `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 https://reviews.llvm.org/D96568, 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.

To have a solution suitable for all cases, a new intrinsic function
`llvm.isnan` was introduced (https://reviews.llvm.org/D104854). It protects
the check from undesirable optimizations and preserves it till selector,
where it can be lowered in optimal for a particular target way.

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 (
https://lists.llvm.org/pipermail/llvm-dev/2021-August/152282.html) listed
such "non-computational" functions, which should not signal if provided
with an sNAN argument.

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.

Any feedback is welcome.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20210902/a38fae3f/attachment.html>

More information about the cfe-dev mailing list