<div dir="ltr">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?<div><br><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 7:00 PM James Y Knight <<a href="mailto:jyknight@google.com">jyknight@google.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 dir="ltr"><div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">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:<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">The working construct is `reinterpret_cast<uint32_t&>(x)`. It however possesses the same drawback, it requires `x` be in memory.</div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">We're getting rather far afield of the thread topic here, but .. that is UB, don't do that.</div><div dir="auto"><br></div><div dir="auto">Instead, always memcpy, e.g.</div><div dir="auto">uint32_t y;</div><div dir="auto">memcpy(&y, &flo, sizeof(uint32_t));</div><div dir="auto"><br></div><div dir="auto">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>). </div><div dir="auto"><br></div><div dir="auto">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.</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
</blockquote></div></div></div>
</div>
</blockquote></div>