AIX library functions frexpl(), ldexpl(), and modfl() are for 128-bit IBM long double, i.e. __ibm128. Other *l() functions, e.g., acosl(), are for 64-bit long double. The AIX Clang compiler currently maps builtin functions __builtin_frexpl(), __builtin_ldexpl(), and __builtin_modfl() to frexpl(), ldexpl(), and modfl() in 64-bit long double mode which results in seg-faults or incorrect return values. This patch changes to map __builtin_frexpl(), __builtin_ldexpl(), and __builtin_modfl() to double version lib functions frexp(), ldexp() and modf() in 64-bit long double mode. The following is from AIX <math.h>.
/* * frexpl(), ldexpl(), and modfl() have preexisting shared versions which are * 128-bit only. 64-bit versions must be made available for C99 for the * default 64-bit long double. These cannot simply be macros because the * actual routines will be the incorrect form in 64-bit mode if the user * forces the actual routines to be used through undef or macro suppression * per the standard. */ #if defined(_ISOC99_SOURCE) && !defined(__LONGDOUBLE128) static long double _NOTHROW(frexpl, (long double __x, int *__i)) { return (long double) frexp((double) __x, __i); } static long double _NOTHROW(ldexpl, (long double __x, int __i)) { return (long double) ldexp((double) __x, __i); } #ifndef __MODFL static long double _NOTHROW(modfl, (long double __x, long double *__y)) { return (long double) modf((double) __x, (double *) __y); } #endif #endif
I feel like we should be clear about which 128-bit double format we are talking about, since it may not be immediately clear for folks who aren't intimately familiar with AIX. Maybe we can reference __ibm128 or ibm 128-bit, so it's clear what we mean.