<div dir="ltr"><div>According to IEEE 754, the following operations are "non-computational", and should not signal if provided with an sNAN argument.<br></div><div><div>I've annotated each with -> C function/macro equivalent, taken from the table in the C standard draft.<br></div><div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>enum class(source) -> fpclassify, signbit,
issignaling</div></div><div><div><div>boolean isSignMinus(source) -> signbit</div></div></div><div><div><div>boolean isNormal(source) -> isnormal</div></div></div><div><div><div>boolean isFinite(source) -> isfinite</div></div></div><div><div><div>boolean isZero(source) -> iszero</div></div></div><div><div><div>boolean isSubnormal(source) -> issubnormal</div></div></div><div><div><div>boolean isInfinite(source) -> isinf</div></div></div><div><div><div>boolean isNaN(source) -> isnan</div></div></div><div><div><div>boolean isSignaling(source) -> issignaling</div></div></div><div><div><div>boolean isCanonical(source) -> iscanonical</div></div></div><div><div><div>enum radix(source) -> FLT_RADIX constant</div></div></div><div><div><div>boolean totalOrder(source, source) -> totalorder</div></div></div><div><div><div>boolean totalOrderMag(source, source) -> totalordermag</div></div></div><div><div><br></div></div><div><div>(Decimal numbers:)</div><div>boolean sameQuantum(source, source) -> samequantum</div></div><div><div><br></div></div></blockquote><div><div>The following list are "quiet-computational" operations, which also should not signal when provided with an sNAN:</div><div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>sourceFormat copy(source) -> memcpy, memmove,+(x) -- (Somewhat surprisingly, "x = y" is implementation-defined to be either a "copy" (non-signaling) or a "convertFormat" (signaling), even when x and y are the same type.)</div></div><div><div>sourceFormat negate(source) -> -(x)</div></div><div><div>sourceFormat abs(source) -> fabs</div></div><div><div><br></div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>(Decimal numbers):</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>decimalEncoding encodeDecimal(decimal) -> encodedec</div></div><div><div>decimal decodeDecimal(decimalEncoding) -> decodedec</div></div><div><div>binaryEncoding encodeBinary(decimal) -> encodebin</div></div><div><div>decimal decodeBinary(binaryEncoding) -> decodebin</div></div></blockquote><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Aug 23, 2021 at 3:42 PM Sanjay Patel via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-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"><div>Ok, does this edit to the LangRef make sense for the definition of "ignore":</div><div>"optimization passes may assume that the
exception status flags will not be read and that floating-point exceptions **will**
be masked" --></div><div>"optimization passes may assume that the
exception status flags will not be read and that floating-point exceptions **may**
be masked"</div><div><br></div><div>It's still not clear to me if there's a benefit from having an intrinsic vs. one more exception mode ("none" or "off").</div><div>That answer might depend on how many more of these intrinsics we'll need? <cmath> has these:<br></div><div>isfinite()</div><div>isinf()</div><div>isnormal()</div><div>signbit()<br></div><div><br></div><div>others?<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Aug 23, 2021 at 2:25 PM Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</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 lang="EN-US">
<div>
<p class="MsoNormal">> Why would a target be allowed to lower the constrained fcmp intrinsic with "ignore" to an operation that might raise an exception?
<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Because the “fpexcept.ignore” argument means that exceptions are being ignored. That is, it doesn’t matter whether exceptions are raised or not. It’s a promise that exceptions are not unmasked or being explicitly checked in this part of
 the code.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The “fpexcept.ignore” argument isn’t used for the fully strict mode. It is used for two cases:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">1) To get back to the “default” state (in combination with “fpround.tonearest”) when a non-constrained operation is inlined into a function that has constrained operations.<u></u><u></u></p>
<p class="MsoNormal">2) To enable dynamic rounding (-frounding-math) without requiring strict exception semantics.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Regarding NaN comparison support in the presence of fast-math flags, I think this is an excellent reason to have the intrinsic. I needed this for a (non-C/C++) downstream compiler before the llvm.isnan intrinsic was introduced and found
 that the only ways to achieve it were either to introduce an intrinsic for the comparison or to remove the ‘nnan’ flag everywhere.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">-Andy<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border-color:rgb(225,225,225) currentcolor currentcolor;border-style:solid none none;border-width:1pt medium medium;padding:3pt 0in 0in">
<p class="MsoNormal"><b>From:</b> llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>> <b>On Behalf Of
</b>Sanjay Patel via llvm-dev<br>
<b>Sent:</b> Monday, August 23, 2021 10:56 AM<br>
<b>To:</b> Wang, Pengfei <<a href="mailto:Pengfei.Wang@intel.com" target="_blank">Pengfei.Wang@intel.com</a>><br>
<b>Cc:</b> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>; Clang Dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: [llvm-dev] [cfe-dev] Intrinsic llvm::isnan<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">Why would a target be allowed to lower the constrained fcmp intrinsic with "ignore" to an operation that might raise an exception?
<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">If that scenario does not exist, then make the definition of fcmp "ignore" stronger by saying that it *requires* a lowering that does not raise an exception.
<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">If refining the definition of "ignore" in this case is too hard to reconcile with other FP ops, how about adding another exception mode ("none") to specify that exceptions are guaranteed not to be raised?<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Aug 23, 2021 at 11:04 AM Wang, Pengfei <<a href="mailto:pengfei.wang@intel.com" target="_blank">pengfei.wang@intel.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-color:currentcolor currentcolor currentcolor rgb(204,204,204);border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">AFAIU, the fpexcept metadata is just a hint for optimizations, which have to respect the sequence of FP instructions. “ignore” is not a command to ask
 backend to mask the exception. It just tells optimizations the exceptions are not concerned by user, so that the FP instructions can be scheduled.</span><u></u><u></u></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">I think an non exception intrinsic is needed, because it is a commend to request backend not to emit instructions that may raise exception.</span><u></u><u></u></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">Thanks</span><u></u><u></u></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">Pengfei</span><u></u><u></u></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)"> </span><u></u><u></u></p>
<div style="border-style:solid none none;border-width:1pt medium medium;padding:3pt 0in 0in;border-color:currentcolor">
<p class="MsoNormal"><b>From:</b> llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>>
<b>On Behalf Of </b>Sanjay Patel via llvm-dev<br>
<b>Sent:</b> Monday, August 23, 2021 10:13 PM<br>
<b>To:</b> Serge Pavlov <<a href="mailto:sepavloff@gmail.com" target="_blank">sepavloff@gmail.com</a>><br>
<b>Cc:</b> LLVM Developers <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>>; Clang Dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: [llvm-dev] [cfe-dev] Intrinsic llvm::isnan<u></u><u></u></p>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">If the FP state is not made invisible/irrelevant by "fpexcept.ignore", then why is that argument on this intrinsic call at all?
<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Ie, why is that argument not used by the backend to decide to lower to a CMP instruction or special isnan instruction or library call?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">An example would be helpful - in what case would these two lower differently given that SNAN always raises a visible exception?<u></u><u></u></p>
</div>
<div>
<div>
<p class="MsoNormal">call i1 @llvm.experimental.constrained.fcmp.f64(double %x, double %x, metadata !"uno", metadata !"fpexcept.ignore") ; "floating-point exceptions will be masked"<u></u><u></u></p>
</div>
<div>
<div>
<p class="MsoNormal">call i1 @llvm.experimental.constrained.fcmp.f64(double %x, double %x, metadata !"uno", metadata !"fpexcept.strict")  ; "this mode can also be used with code that unmasks FP exceptions"<u></u><u></u></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Aug 23, 2021 at 9:50 AM Serge Pavlov <<a href="mailto:sepavloff@gmail.com" target="_blank">sepavloff@gmail.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<div>
<p class="MsoNormal">When codegen lowers this call, it does not know if this is a regular compare and it may create CMP instruction, as for default environment, or this is 'isnan' for which it should
 generate different code, which does not influence FP state.<u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">On most architectures compare instructions change FP state, in default environment it is just ignored, but actually hardware registers can be modified, For 'isnan' instructions
 must actually leave FP state intact.<u></u><u></u></p>
<div>
<p class="MsoNormal"><br clear="all">
<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">Thanks,<br>
--Serge<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Aug 23, 2021 at 8:43 PM Sanjay Patel <<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<div>
<p class="MsoNormal">You're saying that the function definition text overrides the argument definition text. Why are we choosing that interpretation rather than the inverse (and documenting it one way
 or the other)?<u></u><u></u></p>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Aug 23, 2021 at 9:38 AM Serge Pavlov <<a href="mailto:sepavloff@gmail.com" target="_blank">sepavloff@gmail.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<div>
<p class="MsoNormal">> How is this call in LLVM different than the semantics of "isnan(x)" that is required by IEEE-754 or the C standard?<u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">If either of the arguments of `llvm.experimental.constrained.fcmp` is signaling NaN, this function should raise an 'Invalid' exception. 'isnan' never raises exceptions.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><br clear="all">
<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">Thanks,<br>
--Serge<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Aug 23, 2021 at 8:10 PM Sanjay Patel <<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<div>
<div>
<p class="MsoNormal">I'm confused about the definition of:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><a href="https://llvm.org/docs/LangRef.html#llvm-experimental-constrained-fcmp-and-llvm-experimental-constrained-fcmps-intrinsics" target="_blank">https://llvm.org/docs/LangRef.html#llvm-experimental-constrained-fcmp-and-llvm-experimental-constrained-fcmps-intrinsics</a><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">These intrinsics require an "exception behavior" argument. That argument can take the value “fpexcept.ignore” which is defined as:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">"optimization passes may assume that the exception status flags will not be read and that floating-point exceptions will be masked"<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">i1 @llvm.experimental.constrained.fcmp.f64(double %x, double %x, metadata !"uno", metadata !"fpexcept.ignore")<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">How is this call in LLVM different than the semantics of "isnan(x)" that is required by IEEE-754 or the C standard?<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Aug 23, 2021 at 9:00 AM Serge Pavlov via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<div>
<div>
<p class="MsoNormal"><br clear="all">
<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Aug 23, 2021 at 6:12 PM Roman Lebedev <<a href="mailto:lebedev.ri@gmail.com" target="_blank">lebedev.ri@gmail.com</a>> wrote:<u></u><u></u></p>
</div>
</div>
</div>
<div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<p class="MsoNormal">Thank you for posting the RFC!<br>
<br>
I do not believe we should conflate StrictFP support, and<br>
`-ffast-math` handling, these are two separate/separatable concerns.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">You are right, they are separate, but they originate from the implementation of the same function and can be solved with the same solution.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<p class="MsoNormal" style="margin-bottom:12pt"><br>
As for the latter, right now i'm not convinced that we should<br>
second-guess/override explicit user request.<br>
This is inconsistent, and does not match how at least the GCC deals with it.<br>
I think changing the status-quo (before said patch) should be a separate RFC,<br>
and that change should be undone until after that RFC is accepted.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Actually we have two explicit user requests, a call of 'isnan' and an option '-ffast-math'. IMHO they do not contradict each other as 'isnan' is not an arithmetic operation. There
 is a discussion in <a href="https://reviews.llvm.org/D18513#387418" target="_blank">
https://reviews.llvm.org/D18513#387418</a>, which also expresses the opinion that limitations imposed by '-ffast-math' should be applied only to 'math' functions but not to 'tests'. As for GCC behavior, they agree that this behavior is a bag: <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949" target="_blank">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949</a>.
 Intel and Microsoft compilers do not replace 'isnan' with assumed value.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<p class="MsoNormal">As for the latter, the main point of confusion is,<br>
why is `@llvm.isnan` still used in non-StrictFP code?<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">We have to introduce an intrinsic to represent `isnan` in strictfp environment. It is natural to use it for the default environment as well. Besides, a target may have a more efficient
 way to represent `isnan` than unordered comparison.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<p class="MsoNormal">The argument that we need `@llvm.isnan` because we *might* transition<br>
in and out of StrictFP section does not seem to hold for me, because<br>
<a href="https://llvm.org/docs/LangRef.html#constrainedfp" target="_blank">https://llvm.org/docs/LangRef.html#constrainedfp</a> says:<br>
<br>
> If any FP operation in a function is constrained then they all must be constrained. This is required for correct LLVM IR.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">There was no such intention. The primary motivation was strict fp exceptions.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt;border-color:currentcolor currentcolor currentcolor rgb(204,204,204)">
<p class="MsoNormal"><br>
So presumably when codegen'ing a function, we already know that we<br>
will use StrictFP ops, and that should be the knob to use `@llvm.isnan`,<br>
i think.<br>
<br>
<br>
Roman<br>
<br>
<br>
<br>
<br>
On Mon, Aug 23, 2021 at 1:57 PM Serge Pavlov via cfe-dev<br>
<<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br>
><br>
> Hi all,<br>
><br>
> Some time ago a new intrinsic `llvm.isnan` was introduced, which is intended to represent IEEE-754 operation `isNaN` as well as a family of C library functions `isnan*`. Recently during post-commit review concern was raised (see 
<a href="https://reviews.llvm.org/D104854" target="_blank">https://reviews.llvm.org/D104854</a>) that this functionality must have had RFC to make sure there is consensus on semantics.<br>
><br>
> Previously the frontend intrinsic `__builtin_isnan` was converted into `cmp uno` during IR generation in clang codegen. There are two main reasons why this solution is not satisfactory.<br>
><br>
> 1.  Strict floating-point semantics.<br>
><br>
> If FP exceptions are not ignored, `cmp uno` must be replaced with its constrained counterpart, namely `llvm.experimental.constrained.fcmp` or `llvm.experimental.constrained.fcmps`. None of them is compatible with the semantics of `isnan`. 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. Both the constrained
 compare intrinsics raise an exception if either operand is a SNAN (<a href="https://llvm.org/docs/LangRef.html#id1131" target="_blank">https://llvm.org/docs/LangRef.html#id1131</a>). So there was no target-independent IR construct that could express `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>
> 2. Compilation with -ffast-math<br>
><br>
> The option '-ffast-math' is often used for performance critical code, as it can produce faster code. In this case the user must ensure that NaNs are not used as operand values. `isnan` is just proposed for such checks, but it was unusable when `isnan` was
 represented by compare instruction, because the latter may be optimized out. One of use cases is data in memory, which is processed by a function compiled with `-ffast-math`. Some items in the data are NaNs to denote absence of values.<br>
><br>
> This point requires some remarks about using NaNs when a function is compiled with `-ffast-math`. GCC manual does not specify how this option works, it only states about `-ffinite-math-only` (<a href="https://gcc.gnu.org/onlinedocs/gcc-11.2.0/gcc/Optimize-Options.html#Optimize-Options" target="_blank">https://gcc.gnu.org/onlinedocs/gcc-11.2.0/gcc/Optimize-Options.html#Optimize-Options</a>):<br>
><br>
> `Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or +-Infs.`<br>
><br>
> `isnan` does not do any arithmetic, only check, so this statement apparently does not apply to it. There is a GCC bug report
<a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949" target="_blank">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949</a>, where investigation conforms that std::isnan() and std::fpclassify() should works with NaNs as specified even in -ffast-math
 mode.<br>
><br>
> Extending NaN restrictions in -ffast-math mode to functions like `isnan` does not make code faster, but is a source of broken user expectations. If a user writes `isnan` they usually expect an actual check. Silently removing the check is a stronger action
 than assuming that float value contains only real numbers.<br>
><br>
> Intrinsic `llvm.isnan` solves these problems. It<br>
> - represents the check throughout the IR pipeline and saves it from undesired optimizations,<br>
> - is lowered in selector, which can choose the most suitable implementation for particular target,<br>
> - helps keeping IR target-independent,<br>
> - facilitates program analysis as the operation is presented explicitly and is not hidden behind general nodes.<br>
><br>
> Note that `llvm.isnan` is optimized out if its argument is an operation with `nnan` flag, this behavior agrees with the definition of this flag in LLVM documentation.<br>
><br>
> Any feedback is welcome.<br>
><br>
> Thanks,<br>
> --Serge<br>
> _______________________________________________<br>
> cfe-dev mailing list<br>
> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" target="_blank">
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><u></u><u></u></p>
</blockquote>
</div>
</div>
<p class="MsoNormal">_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><u></u><u></u></p>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>

</blockquote></div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>