<div dir="ltr">Food for thought: If you have a codebase which can't use -fno-math-errno, because it relies on errno values from math functions, it may be a more effective long-term strategy to work on modernizing your codebase, eliminating the dependencies on errno, rather than going through the trouble of adding even more complexity to compilers to keep errno support limping along.<div>
<br></div><div>Of course, whether this actually makes sense for you in your situation depends on many factors.</div><div><br></div><div>Dan</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Sep 12, 2013 at 5:44 PM, Hal Finkel <span dir="ltr"><<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
<br>
Our current handling of -fno-math-errno (and this -ffast-math) in Clang is broken on systems for which libm functions do actually set errno. This is because, when -fno-math-errno is in effect, libm functions like sqrt, sin, cos, etc. are marked as readnone. As a result, these calls can be reordered with respect to other calls that set errno, and can clobber errno before it can be read. For example:<br>

<br>
int fd = open(...);<br>
if (fd == -1) {<br>
  perror("oops");<br>
}<br>
double f = sqrt(a);<br>
<br>
If we're on a system (like Linux, for example), where sqrt might set errno to EDOM when a is negative, we can have a problem if some optimization rearranges the code to something like this:<br>
<br>
int fd = open(...);<br>
double f = sqrt(a);<br>
if (fd == -1) {<br>
  perror("oops");<br>
}<br>
<br>
if the open fails, and a is -2.0, then perror will print the wrong error string (thus confusing the user). This is not really a problem with the optimization because sqrt was marked as readnone. On the other hand, we don't want to tag sqrt and writing to some arbitrary external state variable, because this will prevent autovectorization, will prevent CSE from collecting duplicate calls to sqrt, and a host of other important optimizations.<br>

<br>
To fix this problem, I think that we need to stop treating errno as some arbitrary external state, and model is explicitly. Functions need to be able carry two additional attributes:<br>
<br>
  1. 'writes-only-errno' - An attribute to indicate that the function may set errno, and that is the only external state to which it might write. This is useful because getModRefInfo queries can return more accurate answers when comparing to pointers that we know cannot point to errno (such as alloca'd memory and functions) [is this allowed at all?].<br>

<br>
  2. 'errno-ignored' - Set when -fno-math-errno is in effect, indicating that it is safe to assume that the user does not care about any value of errno set by this function. This will allow CSE and autovectorization to happen (by modifying those passes to specifically query this attribute).<br>

<br>
With these new attributes, the functions are, on systems for which libm functions might set errno, not marked readnone or readonly. This will prevent unwanted reordering. Thoughts?<br>
<br>
Thanks again,<br>
Hal<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Hal Finkel<br>
Assistant Computational Scientist<br>
Leadership Computing Facility<br>
Argonne National Laboratory<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</font></span></blockquote></div><br></div>