<div dir="ltr"><div>Yes, that looks like a bug. The transform is ok in general for negative numbers, but -Inf is a special-case for pow(), right?<br></div><div>If so, we probably need an extra check of the input with "isKnownNeverInfinity()". If there are other errno divergences for edge case values, we may need to check other conditions.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Sep 12, 2020 at 9:37 PM Hubert Tong via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-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"><div>The transformation in <span style="font-family:monospace">LibCallSimplifier::replacePowWithSqrt</span> with respect to -Inf uses a select instruction, which based on the observed behaviour, incorporates the side effects of the unchosen branch. This means that (for <span style="font-family:monospace">pow</span>) a call to <span style="font-family:monospace">sqrt(</span>-Inf<span style="font-family:monospace">)</span> is materialized. Such a call is specified as having a domain error (C17 subclause 7.12.7.5) since the operand is less than zero. Contrast this with <span style="font-family:monospace">pow(</span>-Inf<span style="font-family:monospace">, 0.5)</span>, which is specified by C17 subclause F.10.4.4 as having a result of +Inf (indicating an exact result for the operation and, since IEEE Std 754-2008 subclause 9.1.1 states that domain errors are to be indicated by a NaN result, a lack of a domain error).</div><div><br></div><div>It is noted that the above statements were made notwithstanding the ERRORS section of pow() in POSIX.1-2017 XSH Chapter 3, which specifies a domain error except perhaps by deference to the C standard due to a conflict between the POSIX and the C wording.</div><div><br></div><div>The transformation in question causes EDOM for 
<span style="font-family:monospace">pow(</span>-Inf<span style="font-family:monospace">, 0.5)</span>

 even on platforms where the system library implementation of <span style="font-family:monospace">pow</span> does not cause this situation to arise.</div><div><br></div><div>A sample program that (on some platforms, such as Linux on x86-64) completes successfully with optimizations off, and aborts with LLVM's optimization follows; <span style="font-family:monospace">-fmath-errno</span> does not help, and it is not expected to, because it is designed to retain setting errno to non-zero (not to prevent spuriously setting errno).</div><div><br></div><div><span style="font-family:monospace">#include <errno.h><br>volatile double inf = -__builtin_inf();<br><br>double pow(double, double);<br>void abort(void);<br>int main(void) {<br>  errno = 0;<br>  pow(inf, 0.5);<br>  if (errno != 0) abort();<br>}</span></div><div><br></div><div>Compiler Explorer link: <a href="https://godbolt.org/z/5Wr66M" target="_blank">https://godbolt.org/z/5Wr66M</a></div><div><br></div><div>Is the transformation actually valid in some way? If not, I see no instances where the LibCallSimplier generates conditional branches. Retaining the transformation 
in some way 

without generating conditional branches would probably involve bailing out if infinities are still in play.<br></div><div><br></div></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>