<div dir="ltr"><div dir="ltr">`isnan` does not begin with an underscore, so it is not a reserved identifier. Why is its redefinition an UB?<div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">Thanks,<br>--Serge<br></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 13, 2021 at 9:03 PM Krzysztof Parzyszek <<a href="mailto:kparzysz@quicinc.com">kparzysz@quicinc.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" style="overflow-wrap: break-word;">
<div class="gmail-m_-4779430008634356985WordSection1">
<p class="MsoNormal">If the compiler provides “isnan”, the user can’t redefine it.  Redefining/undefining any function or a macro provided by a compiler is UB.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The “old” behavior can be tuned with #pragmas to restore the functionality of NaNs where needed.<u></u><u></u></p>
<p class="MsoNormal">The “old” behavior doesn’t have a problem with “has_nan”---it returns “true”.  What other issues are there?<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal"><span style="font-size:9pt;font-family:Consolas">-- </span>
<span style="font-size:9pt;font-family:Consolas"><u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:8pt;font-family:Consolas">Krzysztof Parzyszek 
<a href="mailto:kparzysz@quicinc.com" target="_blank"><span style="color:rgb(5,99,193)">kparzysz@quicinc.com</span></a>   AI tools development<u></u><u></u></span></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(225,225,225);padding:3pt 0in 0in">
<p class="MsoNormal"><b>From:</b> cfe-dev <<a href="mailto:cfe-dev-bounces@lists.llvm.org" target="_blank">cfe-dev-bounces@lists.llvm.org</a>> <b>On Behalf Of
</b>Serge Pavlov via cfe-dev<br>
<b>Sent:</b> Monday, September 13, 2021 8:50 AM<br>
<b>To:</b> James Y Knight <<a href="mailto:jyknight@google.com" target="_blank">jyknight@google.com</a>><br>
<b>Cc:</b> llvm-dev <<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: [cfe-dev] [llvm-dev] Should isnan be optimized out in fast-math mode?<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<p align="center" style="text-align:center"><strong><span style="font-size:10.5pt;font-family:Arial,sans-serif;color:black;background:yellow">WARNING:</span></strong><span style="font-size:10.5pt;font-family:Arial,sans-serif;color:black;background:yellow">
 This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros.</span><u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">Let's weigh the alternatives.<br>
<br>
We are discussing two approaches for handling `isnan` and similar functions in -ffinite-math-only mode:<br>
1. "Old" behavior: "with -ffinite-math-only you are telling that there are no NaNs", so `isnan` may be optimized to `false`.<br>
2. "New" behavior: with -ffinite-math-only you are telling that the operands of arithmetic operations are not NaNs but otherwise NaN may be used. As `isnan` is not an arithmetic operation, it should be preserved.<br>
<br>
Advantages of the "old" behavior are:<br>
- " it’s intuitively clear".<br>
- It is close to the GCC current behavior.<br>
<br>
Advantages of the "new" behavior are:<br>
- `isnan` is still available to the user, which allows, for instance, validation of working data or selection between fast and slow path.<br>
- NaN is available and may be used, for instance, as sentinel.<br>
- Consistency between compiler and library implementations, both would behave similarly.<br>
- In most real cases the "old" behavior can be easily obtained by redefinition of `isnan`.<br>
- It is free from issues like "what returns numeric_limits<float>::has_quite_NaN()?".<br>
<br>
It is unlikely that "old" behavior gives noticeable performance gain. Anyway, `isnan` may be redefined to `false` if it actually does.<br>
<br>
Intuitive clarity of the "old" way is questionable for users, because it is not clear why functions like `isnan` silently disappeared or what body should have specializations of `numeric_limit` methods.<br>
<br>
There are cases when checking for NaN is needed even in -ffinite-math-only mode. To make it, users have to use workarounds like doing integer arithmetic on float values, which reduce clarity of code, make it unportable and slower.<br>
<br>
Are there any other advantages/disadvantages of these approaches? <u></u><u></u></p>
<div>
<p class="MsoNormal"><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, Sep 13, 2021 at 7:00 PM James Y Knight <<a href="mailto:jyknight@google.com" target="_blank">jyknight@google.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1pt solid rgb(204,204,204);padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal">On Mon, Sep 13, 2021, 2:02 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-top:none;border-right:none;border-bottom:none;border-left:1pt solid rgb(204,204,204);padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<div>
<p class="MsoNormal">The working construct is `reinterpret_cast<uint32_t&>(x)`. It however possesses the same drawback, it requires `x` be in memory.<u></u><u></u></p>
</div>
</blockquote>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">We're getting rather far afield of the thread topic here, but .. that is UB, don't do that.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Instead, always memcpy, e.g.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">uint32_t y;<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">memcpy(&y, &flo, sizeof(uint32_t));<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Or use a wrapper like std::bit_cast or absl::bit_cast (<a href="https://github.com/abseil/abseil-cpp/blob/cfbf5bf948a2656bda7ddab59d3bcb29595c144c/absl/base/casts.h#L106" target="_blank">https://github.com/abseil/abseil-cpp/blob/cfbf5bf948a2656bda7ddab59d3bcb29595c144c/absl/base/casts.h#L106</a>). <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">This has effectively no runtime overhead, the compiler is extremely good at deleting calls to memcpy when it has a constant smallish size. And remember that
<i>every</i> local variable started out in memory. Only through optimizations does the memory location and the loads/stores for every access get eliminated.<u></u><u></u></p>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>

</blockquote></div></div>