<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:SimSun;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@SimSun";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;
        font-weight:normal;
        font-style:normal;
        text-decoration:none none;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span style="color:#1F497D">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">I think an non exception intrinsic is needed, because it is a commend to request backend not to emit instructions that may raise exception.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">Thanks<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">Pengfei<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> llvm-dev <llvm-dev-bounces@lists.llvm.org> <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 <sepavloff@gmail.com><br>
<b>Cc:</b> LLVM Developers <llvm-dev@lists.llvm.org>; Clang Dev <cfe-dev@lists.llvm.org><br>
<b>Subject:</b> Re: [llvm-dev] [cfe-dev] Intrinsic llvm::isnan<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></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?
<o:p></o:p></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?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></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?<o:p></o:p></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"<o:p></o:p></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"<o:p></o:p></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Mon, Aug 23, 2021 at 9:50 AM Serge Pavlov <<a href="mailto:sepavloff@gmail.com">sepavloff@gmail.com</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<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.<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></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.<o:p></o:p></p>
<div>
<p class="MsoNormal"><br clear="all">
<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">Thanks,<br>
--Serge<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></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:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<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)?<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></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:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<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?<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><br clear="all">
<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">Thanks,<br>
--Serge<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></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:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal">I'm confused about the definition of:<o:p></o:p></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><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></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:<o:p></o:p></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"<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">i1 @llvm.experimental.constrained.fcmp.f64(double %x, double %x, metadata !"uno", metadata !"fpexcept.ignore")<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></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?<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></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:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal"><br clear="all">
<o:p></o:p></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:<o:p></o:p></p>
</div>
</div>
</div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<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.<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><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.<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal"> <o:p></o:p></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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">As for the latter, the main point of confusion is,<br>
why is `@llvm.isnan` still used in non-StrictFP code?<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<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.<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">There was no such intention. The primary motivation was strict fp exceptions.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<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><o:p></o:p></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><o:p></o:p></p>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</body>
</html>