<div dir="ltr"><div dir="ltr">On Thu, 16 Sept 2021 at 11:18, Arthur O'Dwyer via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><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"><div dir="ltr"><div dir="ltr">On Thu, Sep 16, 2021 at 1:31 PM Serge Pavlov <<a href="mailto:sepavloff@gmail.com" target="_blank">sepavloff@gmail.com</a>> wrote:</div><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"><div dir="ltr"><div class="gmail_quote"><div><div dir="ltr" class="gmail_attr">On Tue, Sep 14, 2021 at 12:50 AM Serge Pavlov <<a href="mailto:sepavloff@gmail.com" target="_blank">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"><div>On Mon, Sep 13, 2021 at 11:46 PM 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">… is guaranteed to work, and I read that fast-math enables the compiler to reason about constructs like `x + 0` being equal to `x`, then I’m going to be very confused when:<br></blockquote><div>You are right, this was a bad idea. Compiler may optimize out `isnan` but only when it deduces that the value cannot be NaN, but not due to the user's promise. It is especially important for `isinf`. Addition of two finite values may produce infinity and there is no universal way to predict it. It is probably not an issue for types like float or double, but ML cores use halfs or even minifloats, where overflow is much more probable. If in the code:<br></div><div>```</div><div>float r = a + b;</div><div>if (isinf(r)) {...</div><div>```</div>`isinf` were optimized out just because -ffinite-math-only is in effect, the user cannot check if overflow did not occur.</div></div></div></blockquote></div><div> </div><div>Rules proposed by Richard are also formulated using arguments, not results. Now there is no intention to optimize such a case.</div></div></div></blockquote><div><br></div><div>Infinity (HUGE_VAL) is already not NaN, so this example doesn't have anything to do with the NaN cases being discussed.</div><div>However, let's rephrase as a NaN situation:</div><div><br></div><div>    bool f1(float a, float b) {</div><div>        float r = a + b;</div><div>        return isnan(r);</div><div>    }<br></div><div>    bool result = f1(-HUGE_VAL, HUGE_VAL);  // expect "true"</div><div><br></div><div>Here, `a + b` can produce quiet-NaN (if `a` is -HUGE_VAL and `b` is +HUGE_VAL).</div><div>By Richard Smith's -ffast-math proposal as I understand it, this quiet-NaN result would be treated "as if" it were a signaling NaN.</div><div>Under IEEE 754, no operation ever produces a signaling NaN, so unfortunately IEEE 754 can't guide us here; but intuitively, I think we'd all say that merely <i>producing</i> a signaling NaN would not itself <i>cause</i> a signal. So we store the quiet-NaN result in `r`.</div><div>Then we ask whether `isnan(r)`. The quiet-NaN result in `r` is used. By Richard Smith's -ffast-math proposal as I understand it, any operation <i>would</i> produce an unspecified result if it would raise a signal; but in fact `isnan(r)` is a non-signaling operation, so even though we're treating quiet-NaN as signaling-NaN, isnan(r) never raises any signal. So this code has <i>well-defined behavior</i> in -ffast-math mode.</div><div>(And because the code's behavior is well-defined, therefore `isnan(r)` has its usual meaning. When `r` holds a quiet-NaN, as in this case, `isnan(r)` will correctly return `true`.)</div></div></div></blockquote><div><br></div><div>For what it's worth, this is indeed exactly what I meant. Thanks for clarifying!</div><div> </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 class="gmail_quote"><div>I've googled, but failed to discover, whether comparison against a signaling NaN is expected to signal. That is,</div><div><br></div><div><div>    bool f2(float a, float b) {</div><div>        float r = a + b;</div><div>        return (r != r);</div><div>    }<br></div><div>    bool result = f2(-HUGE_VAL, HUGE_VAL);  // expect "true" in IEEE754 mode, but perhaps "false" in -ffast-math mode</div><div><br></div></div><div>I'm really <i>hoping</i> that comparison is a signaling operation. If it is, then according to Richard Smith's proposal as I understand it, the compiler would be free to optimize `(r != r)` into `(false)` in -ffast-math mode.  (And, as a corollary, the compiler would <i>not</i> generally be free to transform `isnan(r)` into `(r != r)`, because the latter expression has more preconditions than the former.)</div><div><br></div><div>–Arthur</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 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"><div lang="EN-US"><div><div style="border-top:none;border-right:none;border-bottom:none;border-left:1.5pt solid blue;padding:0in 0in 0in 4pt"><div><div><div><div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

</blockquote></div></div>
</blockquote></div></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></div>