<div dir="ltr">I was also wrong about reinterpret_cast, sorry. `reinterpret_cast<uint32_t>(float)` is an invalid construct. The working construct is `reinterpret_cast<uint32_t&>(x)`. It however possesses the same drawback, it requires `x` be in memory.<div><br></div><div><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 Sat, Sep 11, 2021 at 11:20 AM Serge Pavlov <<a href="mailto:sepavloff@gmail.com">sepavloff@gmail.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="ltr" class="gmail_attr">On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <<a href="mailto:ctetreau@quicinc.com" target="_blank">ctetreau@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"><div>The problem is that math code is often templated, so `template <typename T> MyMatrixT<T> safeMul(const MyMatrixT<T> & lhs …` is going to be in a header.<br></div></div></blockquote><div dir="ltr"><br></div><div dir="ltr">No problem, the user can write:</div><div dir="ltr">```</div><div>#ifdef <span style="color:rgb(0,0,0);font-family:monospace;font-size:medium">__FAST_MATH__</span></div>#undef isnan<br>#define isnan(x) false<div>#endif<br><div dir="ltr">```<br>and put it somewhere in the headers.</div><div dir="ltr"><br></div><div dir="ltr">On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <<a href="mailto:ctetreau@quicinc.com" target="_blank">ctetreau@quicinc.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Regardless, my position isn’t “there is no NaN”. My position is “you cannot count on operations on NaN working”. </blockquote></div><div dir="ltr"><br></div><div>Exactly. Attempts to express the condition of -ffast-math as restrictions on types are not fruitful. I think it is the reason why GCC documentation does not use simple and clear "there is no NaN" but prefers more complicated wording about arithmetic.</div><div><br></div><div>On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <<a href="mailto:ctetreau@quicinc.com" target="_blank">ctetreau@quicinc.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I think working around these sorts of issues is something that C and C++ developers are used to. These sorts of “inconsistent” between compilers behaviors is something we accept because we know it comes with improved performance. In this case, the fix is easy, so I don’t think this corner case is worth supporting. Especially when the fix is also just one line:<br>```<br>#define myIsNan(x) (reinterpret_cast<uint32_t>(x) == THE_BIT_PATTERN_OF_MY_SENTINEL_NAN)<br>```</blockquote></div><div dir="ltr"><br></div><div>It won't work in this way. If `x == 5.0`, then `reinterpret_cast<uint32_t>(x) == 5`. What you need there is a bitcast. Standard C does not have such. To emulate it a reinterpret_cast of memory can be used: `<span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant-ligatures:inherit;font-variant-caps:inherit;font-weight:inherit;white-space:inherit;font-size:13px">*</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">reinterpret_cast</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant-ligatures:inherit;font-variant-caps:inherit;font-weight:inherit;white-space:inherit;font-size:13px"><</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">int</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant-ligatures:inherit;font-variant-caps:inherit;font-weight:inherit;white-space:inherit;font-size:13px"> *>(&x)`. Another way is to use a union. Both these solutions require operations with memory, which is not good for performance, especially on GPU and ML cores. Of course, a smart compiler can eliminate memory operation, but it does not have to do it always, as it is only optimization. Moving a value between float and integer pipelines also may incur a performance penalty. At the same time this check often may be done with a single instruction.</span></div><div dir="ltr"><br><div><div dir="ltr">Thanks,<br>--Serge</div></div></div></div></div>
</blockquote></div>