[compiler-rt] [builtins] Avoid using long double in generic sources (PR #69754)

Alexander Richardson via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 24 09:34:17 PDT 2023


https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/69754

>From 679e90689221f1ac85b54d74367763fc8332e7a3 Mon Sep 17 00:00:00 2001
From: Alex Richardson <alexrichardson at google.com>
Date: Fri, 20 Oct 2023 12:11:26 -0700
Subject: [PATCH] [builtins] Avoid using long double in generic sources

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.
---
 compiler-rt/lib/builtins/divxc3.c             |  8 ++++----
 compiler-rt/lib/builtins/extendxftf2.c        |  2 +-
 compiler-rt/lib/builtins/fixunsxfdi.c         |  4 ++--
 compiler-rt/lib/builtins/fixunsxfsi.c         |  4 ++--
 compiler-rt/lib/builtins/fixunsxfti.c         |  4 ++--
 compiler-rt/lib/builtins/fixxfdi.c            |  4 ++--
 compiler-rt/lib/builtins/fixxfti.c            |  4 ++--
 compiler-rt/lib/builtins/floatdixf.c          |  4 ++--
 compiler-rt/lib/builtins/floattixf.c          |  4 ++--
 compiler-rt/lib/builtins/floatundixf.c        |  4 ++--
 compiler-rt/lib/builtins/floatuntixf.c        |  4 ++--
 compiler-rt/lib/builtins/fp_extend.h          |  2 +-
 compiler-rt/lib/builtins/fp_trunc.h           |  2 +-
 compiler-rt/lib/builtins/i386/floatdixf.S     |  2 +-
 compiler-rt/lib/builtins/i386/floatundixf.S   |  2 +-
 compiler-rt/lib/builtins/int_types.h          | 13 ++++++++-----
 compiler-rt/lib/builtins/mulxc3.c             | 12 ++++++------
 compiler-rt/lib/builtins/powixf2.c            |  4 ++--
 compiler-rt/lib/builtins/ppc/multc3.c         |  3 +--
 compiler-rt/lib/builtins/trunctfxf2.c         |  2 +-
 compiler-rt/lib/builtins/x86_64/floatdixf.c   |  4 ++--
 compiler-rt/lib/builtins/x86_64/floatundixf.S |  2 +-
 22 files changed, 48 insertions(+), 46 deletions(-)

diff --git a/compiler-rt/lib/builtins/divxc3.c b/compiler-rt/lib/builtins/divxc3.c
index 97ffd2eac2114c1..cbf5299a14e811b 100644
--- a/compiler-rt/lib/builtins/divxc3.c
+++ b/compiler-rt/lib/builtins/divxc3.c
@@ -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) =
diff --git a/compiler-rt/lib/builtins/extendxftf2.c b/compiler-rt/lib/builtins/extendxftf2.c
index 6cb8a63122f2262..c1d97b5cfa15150 100644
--- a/compiler-rt/lib/builtins/extendxftf2.c
+++ b/compiler-rt/lib/builtins/extendxftf2.c
@@ -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);
 }
 
diff --git a/compiler-rt/lib/builtins/fixunsxfdi.c b/compiler-rt/lib/builtins/fixunsxfdi.c
index c8a8061b2cf0f90..957c263aa3c504e 100644
--- a/compiler-rt/lib/builtins/fixunsxfdi.c
+++ b/compiler-rt/lib/builtins/fixunsxfdi.c
@@ -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))
diff --git a/compiler-rt/lib/builtins/fixunsxfsi.c b/compiler-rt/lib/builtins/fixunsxfsi.c
index 154abcbd35e7b26..a0abb82b7917ce5 100644
--- a/compiler-rt/lib/builtins/fixunsxfsi.c
+++ b/compiler-rt/lib/builtins/fixunsxfsi.c
@@ -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))
diff --git a/compiler-rt/lib/builtins/fixunsxfti.c b/compiler-rt/lib/builtins/fixunsxfti.c
index 508554e4f8f628b..be3f75f04f7fb44 100644
--- a/compiler-rt/lib/builtins/fixunsxfti.c
+++ b/compiler-rt/lib/builtins/fixunsxfti.c
@@ -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))
diff --git a/compiler-rt/lib/builtins/fixxfdi.c b/compiler-rt/lib/builtins/fixxfdi.c
index 86cf3767b75d446..35d7083f56b0bbb 100644
--- a/compiler-rt/lib/builtins/fixxfdi.c
+++ b/compiler-rt/lib/builtins/fixxfdi.c
@@ -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)
diff --git a/compiler-rt/lib/builtins/fixxfti.c b/compiler-rt/lib/builtins/fixxfti.c
index 90e03116e7ca6ab..95038dfafd5d5c7 100644
--- a/compiler-rt/lib/builtins/fixxfti.c
+++ b/compiler-rt/lib/builtins/fixxfti.c
@@ -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)
diff --git a/compiler-rt/lib/builtins/floatdixf.c b/compiler-rt/lib/builtins/floatdixf.c
index ad5deb2d4bf5515..3d9e664e481425a 100644
--- a/compiler-rt/lib/builtins/floatdixf.c
+++ b/compiler-rt/lib/builtins/floatdixf.c
@@ -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
diff --git a/compiler-rt/lib/builtins/floattixf.c b/compiler-rt/lib/builtins/floattixf.c
index 23796f1bb56f49c..c80bc714459c3ba 100644
--- a/compiler-rt/lib/builtins/floattixf.c
+++ b/compiler-rt/lib/builtins/floattixf.c
@@ -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
diff --git a/compiler-rt/lib/builtins/floatundixf.c b/compiler-rt/lib/builtins/floatundixf.c
index 85264adac197652..3e3c6556d65bf70 100644
--- a/compiler-rt/lib/builtins/floatundixf.c
+++ b/compiler-rt/lib/builtins/floatundixf.c
@@ -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;
diff --git a/compiler-rt/lib/builtins/floatuntixf.c b/compiler-rt/lib/builtins/floatuntixf.c
index efd8a27a0875e46..4c53775229ea066 100644
--- a/compiler-rt/lib/builtins/floatuntixf.c
+++ b/compiler-rt/lib/builtins/floatuntixf.c
@@ -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;
diff --git a/compiler-rt/lib/builtins/fp_extend.h b/compiler-rt/lib/builtins/fp_extend.h
index fcd3102bbf9da24..961e521846a21ae 100644
--- a/compiler-rt/lib/builtins/fp_extend.h
+++ b/compiler-rt/lib/builtins/fp_extend.h
@@ -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.
diff --git a/compiler-rt/lib/builtins/fp_trunc.h b/compiler-rt/lib/builtins/fp_trunc.h
index 5e81eb73f94103d..141fe63e132d96d 100644
--- a/compiler-rt/lib/builtins/fp_trunc.h
+++ b/compiler-rt/lib/builtins/fp_trunc.h
@@ -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;
diff --git a/compiler-rt/lib/builtins/i386/floatdixf.S b/compiler-rt/lib/builtins/i386/floatdixf.S
index 19dd0835a9c5497..486e3b004fa38d5 100644
--- a/compiler-rt/lib/builtins/i386/floatdixf.S
+++ b/compiler-rt/lib/builtins/i386/floatdixf.S
@@ -4,7 +4,7 @@
 
 #include "../assembly.h"
 
-// long double __floatdixf(di_int a);
+// xf_float __floatdixf(di_int a);
 
 #ifdef __i386__
 
diff --git a/compiler-rt/lib/builtins/i386/floatundixf.S b/compiler-rt/lib/builtins/i386/floatundixf.S
index 30b4d9f4b96c21c..778c3dc0cc766eb 100644
--- a/compiler-rt/lib/builtins/i386/floatundixf.S
+++ b/compiler-rt/lib/builtins/i386/floatundixf.S
@@ -4,7 +4,7 @@
 
 #include "../assembly.h"
 
-// long double __floatundixf(du_int a);16
+// xf_float __floatundixf(du_int a);16
 
 #ifdef __i386__
 
diff --git a/compiler-rt/lib/builtins/int_types.h b/compiler-rt/lib/builtins/int_types.h
index f705844610f6ac5..18bf0a7f3bf9939 100644
--- a/compiler-rt/lib/builtins/int_types.h
+++ b/compiler-rt/lib/builtins/int_types.h
@@ -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;
diff --git a/compiler-rt/lib/builtins/mulxc3.c b/compiler-rt/lib/builtins/mulxc3.c
index 2f7f14c28453363..6abaab0fbbe479f 100644
--- a/compiler-rt/lib/builtins/mulxc3.c
+++ b/compiler-rt/lib/builtins/mulxc3.c
@@ -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;
diff --git a/compiler-rt/lib/builtins/powixf2.c b/compiler-rt/lib/builtins/powixf2.c
index 3edfe9fd7af5976..ab8c694ada2aebb 100644
--- a/compiler-rt/lib/builtins/powixf2.c
+++ b/compiler-rt/lib/builtins/powixf2.c
@@ -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;
diff --git a/compiler-rt/lib/builtins/ppc/multc3.c b/compiler-rt/lib/builtins/ppc/multc3.c
index f1fd6816d6c87db..93007c855256609 100644
--- a/compiler-rt/lib/builtins/ppc/multc3.c
+++ b/compiler-rt/lib/builtins/ppc/multc3.c
@@ -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);
diff --git a/compiler-rt/lib/builtins/trunctfxf2.c b/compiler-rt/lib/builtins/trunctfxf2.c
index 6a84477879f0f7c..f9ec7192e56103e 100644
--- a/compiler-rt/lib/builtins/trunctfxf2.c
+++ b/compiler-rt/lib/builtins/trunctfxf2.c
@@ -18,7 +18,7 @@
 #define DST_80
 #include "fp_trunc_impl.inc"
 
-COMPILER_RT_ABI long double __trunctfxf2(tf_float a) {
+COMPILER_RT_ABI xf_float __trunctfxf2(tf_float a) {
   return __truncXfYf2__(a);
 }
 
diff --git a/compiler-rt/lib/builtins/x86_64/floatdixf.c b/compiler-rt/lib/builtins/x86_64/floatdixf.c
index cf8450ce6f4288e..54636e283a0e001 100644
--- a/compiler-rt/lib/builtins/x86_64/floatdixf.c
+++ b/compiler-rt/lib/builtins/x86_64/floatdixf.c
@@ -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__
diff --git a/compiler-rt/lib/builtins/x86_64/floatundixf.S b/compiler-rt/lib/builtins/x86_64/floatundixf.S
index 9e3bcedcb7e4bf2..cf7286f0d6c0efc 100644
--- a/compiler-rt/lib/builtins/x86_64/floatundixf.S
+++ b/compiler-rt/lib/builtins/x86_64/floatundixf.S
@@ -4,7 +4,7 @@
 
 #include "../assembly.h"
 
-// long double __floatundixf(du_int a);
+// xf_float __floatundixf(du_int a);
 
 #ifdef __x86_64__
 



More information about the llvm-commits mailing list