[builtins] Avoid using long double in generic sources (#69754)

Use of long double can be error-prone since it could be one of 80-bit
extended precision float, IEEE 128-bit float, or IBM 128-bit float.
Instead use an explicit xf_float typedef for the remaining cases where
long double is being used in the implementation. This patch does not
touch
the PPC specializations which still use long double.
This commit is contained in:
Alexander Richardson 2023-10-24 17:15:47 -07:00 committed by GitHub
parent 2282af26ea
commit 05a4212cc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 48 additions and 48 deletions

View File

@ -17,16 +17,16 @@
// Returns: the quotient of (a + ib) / (c + id)
COMPILER_RT_ABI Lcomplex __divxc3(long double __a, long double __b,
long double __c, long double __d) {
COMPILER_RT_ABI Lcomplex __divxc3(xf_float __a, xf_float __b, xf_float __c,
xf_float __d) {
int __ilogbw = 0;
long double __logbw = crt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));
xf_float __logbw = crt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));
if (crt_isfinite(__logbw)) {
__ilogbw = (int)__logbw;
__c = crt_scalbnl(__c, -__ilogbw);
__d = crt_scalbnl(__d, -__ilogbw);
}
long double __denom = __c * __c + __d * __d;
xf_float __denom = __c * __c + __d * __d;
Lcomplex z;
COMPLEX_REAL(z) = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);
COMPLEX_IMAGINARY(z) =

View File

@ -17,7 +17,7 @@
#define DST_QUAD
#include "fp_extend_impl.inc"
COMPILER_RT_ABI tf_float __extendxftf2(long double a) {
COMPILER_RT_ABI tf_float __extendxftf2(xf_float a) {
return __extendXfYf2__(a);
}

View File

@ -32,8 +32,8 @@
#pragma warning(disable : 4700)
#endif
COMPILER_RT_ABI du_int __fixunsxfdi(long double a) {
long_double_bits fb;
COMPILER_RT_ABI du_int __fixunsxfdi(xf_float a) {
xf_bits fb;
fb.f = a;
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
if (e < 0 || (fb.u.high.s.low & 0x00008000))

View File

@ -32,8 +32,8 @@
#pragma warning(disable : 4700)
#endif
COMPILER_RT_ABI su_int __fixunsxfsi(long double a) {
long_double_bits fb;
COMPILER_RT_ABI su_int __fixunsxfsi(xf_float a) {
xf_bits fb;
fb.f = a;
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
if (e < 0 || (fb.u.high.s.low & 0x00008000))

View File

@ -25,8 +25,8 @@
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
// mmmm mmmm mmmm
COMPILER_RT_ABI tu_int __fixunsxfti(long double a) {
long_double_bits fb;
COMPILER_RT_ABI tu_int __fixunsxfti(xf_float a) {
xf_bits fb;
fb.f = a;
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
if (e < 0 || (fb.u.high.s.low & 0x00008000))

View File

@ -31,10 +31,10 @@
#pragma warning(disable : 4700)
#endif
COMPILER_RT_ABI di_int __fixxfdi(long double a) {
COMPILER_RT_ABI di_int __fixxfdi(xf_float a) {
const di_int di_max = (di_int)((~(du_int)0) / 2);
const di_int di_min = -di_max - 1;
long_double_bits fb;
xf_bits fb;
fb.f = a;
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
if (e < 0)

View File

@ -24,10 +24,10 @@
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
// mmmm mmmm mmmm
COMPILER_RT_ABI ti_int __fixxfti(long double a) {
COMPILER_RT_ABI ti_int __fixxfti(xf_float a) {
const ti_int ti_max = (ti_int)((~(tu_int)0) / 2);
const ti_int ti_min = -ti_max - 1;
long_double_bits fb;
xf_bits fb;
fb.f = a;
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
if (e < 0)

View File

@ -23,7 +23,7 @@
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
// mmmm mmmm mmmm
COMPILER_RT_ABI long double __floatdixf(di_int a) {
COMPILER_RT_ABI xf_float __floatdixf(di_int a) {
if (a == 0)
return 0.0;
const unsigned N = sizeof(di_int) * CHAR_BIT;
@ -31,7 +31,7 @@ COMPILER_RT_ABI long double __floatdixf(di_int a) {
a = (a ^ s) - s;
int clz = __builtin_clzll(a);
int e = (N - 1) - clz; // exponent
long_double_bits fb;
xf_bits fb;
fb.u.high.s.low = ((su_int)s & 0x00008000) | // sign
(e + 16383); // exponent
fb.u.low.all = a << clz; // mantissa

View File

@ -23,7 +23,7 @@
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
// mmmm mmmm mmmm
COMPILER_RT_ABI long double __floattixf(ti_int a) {
COMPILER_RT_ABI xf_float __floattixf(ti_int a) {
if (a == 0)
return 0.0;
const unsigned N = sizeof(ti_int) * CHAR_BIT;
@ -63,7 +63,7 @@ COMPILER_RT_ABI long double __floattixf(ti_int a) {
a <<= (LDBL_MANT_DIG - sd);
// a is now rounded to LDBL_MANT_DIG bits
}
long_double_bits fb;
xf_bits fb;
fb.u.high.s.low = ((su_int)s & 0x8000) | // sign
(e + 16383); // exponent
fb.u.low.all = (du_int)a; // mantissa

View File

@ -22,13 +22,13 @@
// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
// mmmm mmmm mmmm
COMPILER_RT_ABI long double __floatundixf(du_int a) {
COMPILER_RT_ABI xf_float __floatundixf(du_int a) {
if (a == 0)
return 0.0;
const unsigned N = sizeof(du_int) * CHAR_BIT;
int clz = __builtin_clzll(a);
int e = (N - 1) - clz; // exponent
long_double_bits fb;
xf_bits fb;
fb.u.high.s.low = (e + 16383); // exponent
fb.u.low.all = a << clz; // mantissa
return fb.f;

View File

@ -23,7 +23,7 @@
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
// mmmm mmmm mmmm
COMPILER_RT_ABI long double __floatuntixf(tu_int a) {
COMPILER_RT_ABI xf_float __floatuntixf(tu_int a) {
if (a == 0)
return 0.0;
const unsigned N = sizeof(tu_int) * CHAR_BIT;
@ -61,7 +61,7 @@ COMPILER_RT_ABI long double __floatuntixf(tu_int a) {
a <<= (LDBL_MANT_DIG - sd);
// a is now rounded to LDBL_MANT_DIG bits
}
long_double_bits fb;
xf_bits fb;
fb.u.high.s.low = (e + 16383); // exponent
fb.u.low.all = (du_int)a; // mantissa
return fb.f;

View File

@ -50,7 +50,7 @@ static inline int src_rep_t_clz_impl(src_rep_t a) {
#define src_rep_t_clz src_rep_t_clz_impl
#elif defined SRC_80
typedef long double src_t;
typedef xf_float src_t;
typedef __uint128_t src_rep_t;
#define SRC_REP_C (__uint128_t)
// sign bit, exponent and significand occupy the lower 80 bits.

View File

@ -60,7 +60,7 @@ static const int dstSigFracBits = 52;
static const int dstExpBits = 11;
#elif defined DST_80
typedef long double dst_t;
typedef xf_float dst_t;
typedef __uint128_t dst_rep_t;
#define DST_REP_C (__uint128_t)
static const int dstBits = 80;

View File

@ -4,7 +4,7 @@
#include "../assembly.h"
// long double __floatdixf(di_int a);
// xf_float __floatdixf(di_int a);
#ifdef __i386__

View File

@ -4,7 +4,7 @@
#include "../assembly.h"
// long double __floatundixf(du_int a);16
// xf_float __floatundixf(du_int a);16
#ifdef __i386__

View File

@ -165,6 +165,14 @@ typedef struct {
#define HAS_80_BIT_LONG_DOUBLE 0
#endif
#if HAS_80_BIT_LONG_DOUBLE
typedef long double xf_float;
typedef union {
uqwords u;
xf_float f;
} xf_bits;
#endif
#ifdef __powerpc64__
// From https://gcc.gnu.org/wiki/Ieee128PowerPC:
// PowerPC64 uses the following suffixes:
@ -213,11 +221,6 @@ typedef union {
#endif
#if CRT_HAS_FLOATING_POINT
typedef union {
uqwords u;
long double f;
} long_double_bits;
#if __STDC_VERSION__ >= 199901L
typedef float _Complex Fcomplex;
typedef double _Complex Dcomplex;

View File

@ -17,12 +17,12 @@
// Returns: the product of a + ib and c + id
COMPILER_RT_ABI Lcomplex __mulxc3(long double __a, long double __b,
long double __c, long double __d) {
long double __ac = __a * __c;
long double __bd = __b * __d;
long double __ad = __a * __d;
long double __bc = __b * __c;
COMPILER_RT_ABI Lcomplex __mulxc3(xf_float __a, xf_float __b, xf_float __c,
xf_float __d) {
xf_float __ac = __a * __c;
xf_float __bd = __b * __d;
xf_float __ad = __a * __d;
xf_float __bc = __b * __c;
Lcomplex z;
COMPLEX_REAL(z) = __ac - __bd;
COMPLEX_IMAGINARY(z) = __ad + __bc;

View File

@ -16,9 +16,9 @@
// Returns: a ^ b
COMPILER_RT_ABI long double __powixf2(long double a, int b) {
COMPILER_RT_ABI xf_float __powixf2(xf_float a, int b) {
const int recip = b < 0;
long double r = 1;
xf_float r = 1;
while (1) {
if (b & 1)
r *= a;

View File

@ -19,8 +19,7 @@
} \
}
long double _Complex __multc3(long double a, long double b, long double c,
long double d) {
xf_float _Complex __multc3(xf_float a, xf_float b, xf_float c, xf_float d) {
long double ac = __gcc_qmul(a, c);
long double bd = __gcc_qmul(b, d);
long double ad = __gcc_qmul(a, d);

View File

@ -18,8 +18,6 @@
#define DST_80
#include "fp_trunc_impl.inc"
COMPILER_RT_ABI long double __trunctfxf2(tf_float a) {
return __truncXfYf2__(a);
}
COMPILER_RT_ABI xf_float __trunctfxf2(tf_float a) { return __truncXfYf2__(a); }
#endif

View File

@ -2,12 +2,12 @@
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// long double __floatdixf(di_int a);
// xf_float __floatdixf(di_int a);
#ifdef __x86_64__
#include "../int_lib.h"
long double __floatdixf(int64_t a) { return (long double)a; }
xf_float __floatdixf(int64_t a) { return (xf_float)a; }
#endif // __i386__

View File

@ -4,7 +4,7 @@
#include "../assembly.h"
// long double __floatundixf(du_int a);
// xf_float __floatundixf(du_int a);
#ifdef __x86_64__