This change introduces a new intrinsic, llvm.is.fclass, which checks
if the provided floating point number belongs to the specifies value
class. It implements the checks made by C standard library functions
isnan, isinf, isfinite, isnormal, issubnormal, issignaling
and corresponding IEEE-754 operations.
The primary motivation for this intrinsic is the support of strict FP
mode. In this mode using compare instructions or other FP operations is
not possible, because if the value is a signaling NaN, floating point
exception Invalid is raised, but the aforementioned functions must
never raise exceptions.
Currently there are two solutions for this problem, both are
implemented partially. One of them is using integer operations to
implement the check. It was implemented in https://reviews.llvm.org/D95948
for isnan. It solves the problem of exceptions, but offers one
solution for all targets, although some can do the check in more
efficient way.
The other, implemented in https://reviews.llvm.org/D96568, introduced a
hook 'clang::TargetCodeGenInfo::testFPKind', which injects a target
specific code into IR to implement isnan. It is convenient for
targets that has dedicated instruction to determine FP data class.
However using target-specific intrinsic complicates analysis and can
prevent some optimizations.
Using a special intrinsic to represent a value class check allows
representing data class test with enough flexibility. During IR
transformations it represents the check in target-independent way and
prevents it from undesired transformations. In the instruction selector
it allows efficient lowering depending on the target and used mode.
This implementation is an extended variant of llvm.isnan introduced
in https://reviews.llvm.org/D104854. It is limited to minimal intrinsic
support. Target-specific treatment will be implemented in separate
patches.
*Quiet