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.