<div dir="ltr"><div>Thank you for restarting this proposal. It's a bit more work, but let's make sure we have a good design, so we don't miss any details.</div><div><br></div><div><div>What optimizations/analysis does this intrinsic enable **in IR** in strict-FP mode?<br></div><div>If
 it is only constant folding, we don't need to add an intrinsic. We fold
 lots of math library calls with no corresponding LLVM intrinsic under 
llvm::ConstantFoldCall().</div><div>We also do transforms based on operands/uses of library calls in SimplifyLibCalls.</div><div><br></div><div>So I'm really asking: why do we translate isnan() in clang into something else in the first place? The backend can lower that call into whatever suits the target without involving LLVM IR. <br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 2, 2021 at 8:33 AM Serge Pavlov via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><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" target="_blank">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" target="_blank">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" target="_blank">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" target="_blank">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" target="_blank">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" target="_blank">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" target="_blank">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">Thanks,<br>--Serge<br></div></div></div></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>