[LLVMdev] [RFC] Identifying access to errno

Hal Finkel hfinkel at anl.gov
Sat Nov 23 06:14:35 PST 2013


Hello,

On some systems (Linux/glibc, for example), some libm math functions (like cos(double)) might set errno. It is important that we model this, in general, to prevent miscompilation (we would not, for example, want to reorder a call to cos in between a call to open and a call to perror). However, almost no code in the wild checks errno after calls to libm math functions, and this errno-setting behavior prevents vectorization and other useful loop optimizations, CSE, etc. Also, currently, the scalar llvm.<libm function> intrinsics are subtly broken on systems where the underlying libm functions may set errno, because the intrinsics are readonly, and may be implemented by calls to the libm function (which might set errno), exposing us to reordering problems (as in the example above).

I think that we could do a better job if we modeled this more explicitly. In theory errno could be anything (because POSIX allows errno to be a macro "of type int"), but in practice, I think the the following rules will do:

 1. Assume that all unknown external functions might read/write errno
 2. Assume that all i32 pointers might point to errno (although we might be able to do better by somehow leveraging TBAA for "int"?)

Here's a quick overview of how errno is implemented on different systems:

 - Traditional POSIX (not thread safe):

   extern int errno;

 - DragonFly libc:

   extern __thread int errno;

 - Android libc:

   extern volatile int*   __errno(void);
   #define  errno   (*__errno())

 - Darwin libc:

   int * __error(void);
   #define errno (*__error())

 - musl libc:

   extern int *__errno_location(void);
   #define errno (*__errno_location())

Does anyone see any problems with making stronger (type-based) assumptions re: errno (and, thus, on what things may alias with calls to errno-setting-libm functions)? Also, I don't know if we support LTO-ing the libc implementation, and if that could cause any problems with this? What if, for globals, we insisted that the global be named "errno"?

Thanks again,
Hal

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



More information about the llvm-dev mailing list