[LLVMdev] [RFC] New function attributes for errno-setting functions

Hal Finkel hfinkel at anl.gov
Thu Sep 12 17:44:14 PDT 2013


Hello,

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:

int fd = open(...);
if (fd == -1) {
  perror("oops");
}
double f = sqrt(a);

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:

int fd = open(...);
double f = sqrt(a);
if (fd == -1) {
  perror("oops");
}

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.

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:

  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?].

  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).

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?

Thanks again,
Hal

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-dev mailing list