[compiler-rt] [builtins] Support building the 128-bit float functions on ld80 platforms (PR #68132)

Alexander Richardson via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 17 18:29:37 PDT 2023


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

>From dabe1045d1450b902cc80dd54a5677e8f5984c31 Mon Sep 17 00:00:00 2001
From: Alex Richardson <alexrichardson at google.com>
Date: Tue, 17 Oct 2023 14:06:57 -0700
Subject: [PATCH] [builtins] Support building the 128-bit float functions on
 x86

GCC provides these functions (e.g. __addtf3, etc.) in libgcc on x86_64.
Since Clang supports float128, we can also enable the existing code by
using float128 for fp_t if either __FLOAT128__ or __SIZEOF_FLOAT128__
is defined instead of only supporting these builtins for platforms with
128-bit IEEE long doubles.
This commit defines a new tf_float typedef that matches a float with
attribute((mode(TF)) on each given architecture.

There are more tests that could be enabled for x86, but to keep the diff
smaller, I restricted test changes to ones that started failing as part of
this refactoring.

This change has been tested on x86 (natively) and aarch64,powerpc64,riscv64
and sparc64 via qemu-user.

This supersedes https://reviews.llvm.org/D98261.
---
 compiler-rt/lib/builtins/CMakeLists.txt       |   2 -
 compiler-rt/lib/builtins/README.txt           |  21 +-
 compiler-rt/lib/builtins/divtc3.c             |  51 +-
 compiler-rt/lib/builtins/extenddftf2.c        |   4 +-
 compiler-rt/lib/builtins/extendhftf2.c        |   4 +-
 compiler-rt/lib/builtins/extendsftf2.c        |   4 +-
 compiler-rt/lib/builtins/floattitf.c          |   2 +-
 compiler-rt/lib/builtins/floatuntitf.c        |   2 +-
 compiler-rt/lib/builtins/fp_extend.h          |   8 +-
 compiler-rt/lib/builtins/fp_lib.h             |  50 +-
 compiler-rt/lib/builtins/fp_trunc.h           |   8 +-
 compiler-rt/lib/builtins/int_math.h           |  10 +
 compiler-rt/lib/builtins/int_types.h          |  73 ++
 compiler-rt/lib/builtins/multc3.c             |  53 +-
 compiler-rt/lib/builtins/powitf2.c            |   4 +-
 compiler-rt/lib/builtins/trunctfdf2.c         |   2 +-
 compiler-rt/lib/builtins/trunctfhf2.c         |   4 +-
 compiler-rt/lib/builtins/trunctfsf2.c         |   2 +-
 compiler-rt/lib/builtins/trunctfxf2.c         |   2 +-
 compiler-rt/test/builtins/Unit/addtf3_test.c  | 154 ++---
 .../builtins/Unit/compiler_rt_fmaxl_test.c    |  13 +-
 .../builtins/Unit/compiler_rt_logbl_test.c    |  17 +-
 .../builtins/Unit/compiler_rt_scalbnl_test.c  |  15 +-
 compiler-rt/test/builtins/Unit/divtc3_test.c  | 639 +++++++++---------
 compiler-rt/test/builtins/Unit/divtf3_test.c  | 319 ++++-----
 .../test/builtins/Unit/extendxftf2_test.c     |   4 +-
 .../test/builtins/Unit/floatditf_test.c       |  80 ++-
 .../test/builtins/Unit/floattitf_test.c       |  14 +-
 .../test/builtins/Unit/floatunditf_test.c     |  73 +-
 .../test/builtins/Unit/floatunsitf_test.c     |  57 +-
 .../test/builtins/Unit/floatuntitf_test.c     |  19 +-
 compiler-rt/test/builtins/Unit/fp_test.h      |  40 +-
 .../test/builtins/Unit/trunctfxf2_test.c      |  12 +-
 33 files changed, 906 insertions(+), 856 deletions(-)

diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index 4f210a5c0fef90f..ccca2da20fd688a 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -187,8 +187,6 @@ set(BF16_SOURCES
     truncsfbf2.c
 )
 
-# TODO: Several "tf" files (and divtc3.c, but not multc3.c) are in
-# GENERIC_SOURCES instead of here.
 set(GENERIC_TF_SOURCES
   addtf3.c
   comparetf2.c
diff --git a/compiler-rt/lib/builtins/README.txt b/compiler-rt/lib/builtins/README.txt
index 5637183cc3b4551..2d213d95f333af3 100644
--- a/compiler-rt/lib/builtins/README.txt
+++ b/compiler-rt/lib/builtins/README.txt
@@ -137,49 +137,54 @@ si_int __ucmpti2(tu_int a, tu_int b);
 di_int __fixsfdi(      float a);
 di_int __fixdfdi(     double a);
 di_int __fixxfdi(long double a);
+di_int __fixtfdi(   tf_float a);
 
 ti_int __fixsfti(      float a);
 ti_int __fixdfti(     double a);
 ti_int __fixxfti(long double a);
-uint64_t __fixtfdi(long double input);  // ppc only, doesn't match documentation
+ti_int __fixtfti(   tf_float a);
 
 su_int __fixunssfsi(      float a);
 su_int __fixunsdfsi(     double a);
 su_int __fixunsxfsi(long double a);
+su_int __fixunstfsi(   tf_float a);
 
 du_int __fixunssfdi(      float a);
 du_int __fixunsdfdi(     double a);
 du_int __fixunsxfdi(long double a);
+du_int __fixunstfdi(   tf_float a);
 
 tu_int __fixunssfti(      float a);
 tu_int __fixunsdfti(     double a);
 tu_int __fixunsxfti(long double a);
-uint64_t __fixunstfdi(long double input);  // ppc only
+tu_int __fixunstfti(   tf_float a);
 
 float       __floatdisf(di_int a);
 double      __floatdidf(di_int a);
 long double __floatdixf(di_int a);
-long double __floatditf(int64_t a);        // ppc only
+tf_float    __floatditf(int64_t a);
 
 float       __floattisf(ti_int a);
 double      __floattidf(ti_int a);
 long double __floattixf(ti_int a);
+tf_float    __floattitf(ti_int a);
 
 float       __floatundisf(du_int a);
 double      __floatundidf(du_int a);
 long double __floatundixf(du_int a);
-long double __floatunditf(uint64_t a);     // ppc only
+tf_float    __floatunditf(du_int a);
 
 float       __floatuntisf(tu_int a);
 double      __floatuntidf(tu_int a);
 long double __floatuntixf(tu_int a);
+tf_float    __floatuntixf(tu_int a);
 
 //  Floating point raised to integer power
 
 float       __powisf2(      float a, int b);  // a ^ b
 double      __powidf2(     double a, int b);  // a ^ b
 long double __powixf2(long double a, int b);  // a ^ b
-long double __powitf2(long double a, int b);  // ppc only, a ^ b
+tf_float    __powitf2(   tf_float a, int b);  // a ^ b
 
 //  Complex arithmetic
 
@@ -189,8 +194,7 @@ long double __powitf2(long double a, int b);  // ppc only, a ^ b
      double _Complex __muldc3(double a, double b, double c, double d);
 long double _Complex __mulxc3(long double a, long double b,
                               long double c, long double d);
-long double _Complex __multc3(long double a, long double b,
-                              long double c, long double d); // ppc only
+   tf_float _Complex __multc3(tf_float a, tf_float b, tf_float c, tf_float d);
 
 //  (a + ib) / (c + id)
 
@@ -198,8 +202,7 @@ long double _Complex __multc3(long double a, long double b,
      double _Complex __divdc3(double a, double b, double c, double d);
 long double _Complex __divxc3(long double a, long double b,
                               long double c, long double d);
-long double _Complex __divtc3(long double a, long double b,
-                              long double c, long double d);  // ppc only
+   tf_float _Complex __divtc3(tf_float a, tf_float b, tf_float c, tf_float d);
 
 
 //         Runtime support
diff --git a/compiler-rt/lib/builtins/divtc3.c b/compiler-rt/lib/builtins/divtc3.c
index 0e4799295f32fe3..e970cef574b21dd 100644
--- a/compiler-rt/lib/builtins/divtc3.c
+++ b/compiler-rt/lib/builtins/divtc3.c
@@ -12,44 +12,45 @@
 
 #define QUAD_PRECISION
 #include "fp_lib.h"
-#include "int_lib.h"
-#include "int_math.h"
+
+#if defined(CRT_HAS_TF_MODE)
 
 // Returns: the quotient of (a + ib) / (c + id)
 
-COMPILER_RT_ABI Lcomplex __divtc3(long double __a, long double __b,
-                                  long double __c, long double __d) {
+COMPILER_RT_ABI Qcomplex __divtc3(fp_t __a, fp_t __b, fp_t __c, fp_t __d) {
   int __ilogbw = 0;
-  long double __logbw =
-      __compiler_rt_logbl(__compiler_rt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));
+  fp_t __logbw = __compiler_rt_logbtf(
+      __compiler_rt_fmaxtf(crt_fabstf(__c), crt_fabstf(__d)));
   if (crt_isfinite(__logbw)) {
     __ilogbw = (int)__logbw;
-    __c = __compiler_rt_scalbnl(__c, -__ilogbw);
-    __d = __compiler_rt_scalbnl(__d, -__ilogbw);
+    __c = __compiler_rt_scalbntf(__c, -__ilogbw);
+    __d = __compiler_rt_scalbntf(__d, -__ilogbw);
   }
-  long double __denom = __c * __c + __d * __d;
-  Lcomplex z;
-  COMPLEX_REAL(z) =
-      __compiler_rt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);
-  COMPLEX_IMAGINARY(z) =
-      __compiler_rt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw);
-  if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) {
+  fp_t __denom = __c * __c + __d * __d;
+  Qcomplex z;
+  COMPLEXTF_REAL(z) =
+      __compiler_rt_scalbntf((__a * __c + __b * __d) / __denom, -__ilogbw);
+  COMPLEXTF_IMAGINARY(z) =
+      __compiler_rt_scalbntf((__b * __c - __a * __d) / __denom, -__ilogbw);
+  if (crt_isnan(COMPLEXTF_REAL(z)) && crt_isnan(COMPLEXTF_IMAGINARY(z))) {
     if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b))) {
-      COMPLEX_REAL(z) = crt_copysignl(CRT_INFINITY, __c) * __a;
-      COMPLEX_IMAGINARY(z) = crt_copysignl(CRT_INFINITY, __c) * __b;
+      COMPLEXTF_REAL(z) = crt_copysigntf(CRT_INFINITY, __c) * __a;
+      COMPLEXTF_IMAGINARY(z) = crt_copysigntf(CRT_INFINITY, __c) * __b;
     } else if ((crt_isinf(__a) || crt_isinf(__b)) && crt_isfinite(__c) &&
                crt_isfinite(__d)) {
-      __a = crt_copysignl(crt_isinf(__a) ? 1.0 : 0.0, __a);
-      __b = crt_copysignl(crt_isinf(__b) ? 1.0 : 0.0, __b);
-      COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
-      COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
+      __a = crt_copysigntf(crt_isinf(__a) ? (fp_t)1.0 : (fp_t)0.0, __a);
+      __b = crt_copysigntf(crt_isinf(__b) ? (fp_t)1.0 : (fp_t)0.0, __b);
+      COMPLEXTF_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
+      COMPLEXTF_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
     } else if (crt_isinf(__logbw) && __logbw > 0.0 && crt_isfinite(__a) &&
                crt_isfinite(__b)) {
-      __c = crt_copysignl(crt_isinf(__c) ? 1.0 : 0.0, __c);
-      __d = crt_copysignl(crt_isinf(__d) ? 1.0 : 0.0, __d);
-      COMPLEX_REAL(z) = 0.0 * (__a * __c + __b * __d);
-      COMPLEX_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d);
+      __c = crt_copysigntf(crt_isinf(__c) ? (fp_t)1.0 : (fp_t)0.0, __c);
+      __d = crt_copysigntf(crt_isinf(__d) ? (fp_t)1.0 : (fp_t)0.0, __d);
+      COMPLEXTF_REAL(z) = 0.0 * (__a * __c + __b * __d);
+      COMPLEXTF_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d);
     }
   }
   return z;
 }
+
+#endif
diff --git a/compiler-rt/lib/builtins/extenddftf2.c b/compiler-rt/lib/builtins/extenddftf2.c
index 835076be1f2080d..a61ef53147abcfb 100644
--- a/compiler-rt/lib/builtins/extenddftf2.c
+++ b/compiler-rt/lib/builtins/extenddftf2.c
@@ -14,8 +14,6 @@
 #define DST_QUAD
 #include "fp_extend_impl.inc"
 
-COMPILER_RT_ABI fp_t __extenddftf2(double a) {
-  return __extendXfYf2__(a);
-}
+COMPILER_RT_ABI dst_t __extenddftf2(src_t a) { return __extendXfYf2__(a); }
 
 #endif
diff --git a/compiler-rt/lib/builtins/extendhftf2.c b/compiler-rt/lib/builtins/extendhftf2.c
index a2cb0f771ee9aa9..7609db6f06e4ad4 100644
--- a/compiler-rt/lib/builtins/extendhftf2.c
+++ b/compiler-rt/lib/builtins/extendhftf2.c
@@ -15,8 +15,6 @@
 #define DST_QUAD
 #include "fp_extend_impl.inc"
 
-COMPILER_RT_ABI long double __extendhftf2(_Float16 a) {
-  return __extendXfYf2__(a);
-}
+COMPILER_RT_ABI dst_t __extendhftf2(src_t a) { return __extendXfYf2__(a); }
 
 #endif
diff --git a/compiler-rt/lib/builtins/extendsftf2.c b/compiler-rt/lib/builtins/extendsftf2.c
index 0739859bcbc18fa..4ab2982ce5142ba 100644
--- a/compiler-rt/lib/builtins/extendsftf2.c
+++ b/compiler-rt/lib/builtins/extendsftf2.c
@@ -14,8 +14,6 @@
 #define DST_QUAD
 #include "fp_extend_impl.inc"
 
-COMPILER_RT_ABI fp_t __extendsftf2(float a) {
-  return __extendXfYf2__(a);
-}
+COMPILER_RT_ABI dst_t __extendsftf2(src_t a) { return __extendXfYf2__(a); }
 
 #endif
diff --git a/compiler-rt/lib/builtins/floattitf.c b/compiler-rt/lib/builtins/floattitf.c
index fff0755c3bb46a3..c0e61edee8d522d 100644
--- a/compiler-rt/lib/builtins/floattitf.c
+++ b/compiler-rt/lib/builtins/floattitf.c
@@ -67,7 +67,7 @@ COMPILER_RT_ABI fp_t __floattitf(ti_int a) {
     // a is now rounded to LDBL_MANT_DIG bits
   }
 
-  long_double_bits fb;
+  tf_bits fb;
   fb.u.high.all = (s & 0x8000000000000000LL)            // sign
                   | (du_int)(e + 16383) << 48           // exponent
                   | ((a >> 64) & 0x0000ffffffffffffLL); // significand
diff --git a/compiler-rt/lib/builtins/floatuntitf.c b/compiler-rt/lib/builtins/floatuntitf.c
index 33a81b34eeb195b..b774bb1c37c4351 100644
--- a/compiler-rt/lib/builtins/floatuntitf.c
+++ b/compiler-rt/lib/builtins/floatuntitf.c
@@ -65,7 +65,7 @@ COMPILER_RT_ABI fp_t __floatuntitf(tu_int a) {
     // a is now rounded to TF_MANT_DIG bits
   }
 
-  long_double_bits fb;
+  tf_bits fb;
   fb.u.high.all = (du_int)(e + 16383) << 48             // exponent
                   | ((a >> 64) & 0x0000ffffffffffffLL); // significand
   fb.u.low.all = (du_int)(a);
diff --git a/compiler-rt/lib/builtins/fp_extend.h b/compiler-rt/lib/builtins/fp_extend.h
index d640bdcb0ec1fa4..fcd3102bbf9da24 100644
--- a/compiler-rt/lib/builtins/fp_extend.h
+++ b/compiler-rt/lib/builtins/fp_extend.h
@@ -102,13 +102,7 @@ static const int dstSigFracBits = 52;
 static const int dstExpBits = 11;
 
 #elif defined DST_QUAD
-// TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
-#if __LDBL_MANT_DIG__ == 113
-typedef long double dst_t;
-#elif defined(__x86_64__) &&                                                   \
-    (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
-typedef __float128 dst_t;
-#endif
+typedef tf_float dst_t;
 typedef __uint128_t dst_rep_t;
 #define DST_REP_C (__uint128_t)
 static const int dstBits = sizeof(dst_t) * CHAR_BIT;
diff --git a/compiler-rt/lib/builtins/fp_lib.h b/compiler-rt/lib/builtins/fp_lib.h
index 58eb45fcc729296..43bbdd5f8736575 100644
--- a/compiler-rt/lib/builtins/fp_lib.h
+++ b/compiler-rt/lib/builtins/fp_lib.h
@@ -105,18 +105,11 @@ static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
 COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b);
 
 #elif defined QUAD_PRECISION
-#if __LDBL_MANT_DIG__ == 113 && defined(__SIZEOF_INT128__)
-// TODO: Availability of the *tf functions should not depend on long double
-// being IEEE 128, but instead on being able to use a 128-bit floating-point
-// type, which includes __float128.
-// Right now this (incorrectly) stops the builtins from being used for x86.
-#define CRT_LDBL_128BIT
-#define CRT_HAS_TF_MODE
-#define TF_C(c) c##L
+#if defined(CRT_HAS_TF_MODE)
 typedef uint64_t half_rep_t;
 typedef __uint128_t rep_t;
 typedef __int128_t srep_t;
-typedef long double fp_t;
+typedef tf_float fp_t;
 #define HALF_REP_C UINT64_C
 #define REP_C (__uint128_t)
 // Note: Since there is no explicit way to tell compiler the constant is a
@@ -207,13 +200,13 @@ static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
 #undef Word_HiMask
 #undef Word_LoMask
 #undef Word_FullMask
-#endif // __LDBL_MANT_DIG__ == 113 && __SIZEOF_INT128__
+#endif // defined(CRT_HAS_TF_MODE)
 #else
 #error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined.
 #endif
 
 #if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) ||                  \
-    defined(CRT_LDBL_128BIT)
+    (defined(QUAD_PRECISION) && defined(CRT_HAS_TF_MODE))
 #define typeWidth (sizeof(rep_t) * CHAR_BIT)
 #define exponentBits (typeWidth - significandBits - 1)
 #define maxExponent ((1 << exponentBits) - 1)
@@ -393,31 +386,40 @@ static __inline fp_t __compiler_rt_fmax(fp_t x, fp_t y) {
 #endif
 }
 
-#elif defined(QUAD_PRECISION)
-
-#if defined(CRT_LDBL_128BIT)
-static __inline fp_t __compiler_rt_logbl(fp_t x) {
+#elif defined(QUAD_PRECISION) && defined(CRT_HAS_TF_MODE)
+// The generic implementation only works for ieee754 floating point. For other
+// floating point types, continue to rely on the libm implementation for now.
+#if defined(CRT_HAS_IEEE_TF)
+static __inline tf_float __compiler_rt_logbtf(tf_float x) {
   return __compiler_rt_logbX(x);
 }
-static __inline fp_t __compiler_rt_scalbnl(fp_t x, int y) {
+static __inline tf_float __compiler_rt_scalbntf(tf_float x, int y) {
   return __compiler_rt_scalbnX(x, y);
 }
-static __inline fp_t __compiler_rt_fmaxl(fp_t x, fp_t y) {
+static __inline tf_float __compiler_rt_fmaxtf(tf_float x, tf_float y) {
   return __compiler_rt_fmaxX(x, y);
 }
-#else
-// The generic implementation only works for ieee754 floating point. For other
-// floating point types, continue to rely on the libm implementation for now.
-static __inline long double __compiler_rt_logbl(long double x) {
+#define __compiler_rt_logbl __compiler_rt_logbtf
+#define __compiler_rt_scalbnl __compiler_rt_scalbntf
+#define __compiler_rt_fmaxl __compiler_rt_fmaxtf
+#define crt_fabstf crt_fabsf128
+#define crt_copysigntf crt_copysignf128
+#elif defined(CRT_LDBL_128BIT)
+static __inline tf_float __compiler_rt_logbtf(tf_float x) {
   return crt_logbl(x);
 }
-static __inline long double __compiler_rt_scalbnl(long double x, int y) {
+static __inline tf_float __compiler_rt_scalbntf(tf_float x, int y) {
   return crt_scalbnl(x, y);
 }
-static __inline long double __compiler_rt_fmaxl(long double x, long double y) {
+static __inline tf_float __compiler_rt_fmaxtf(tf_float x, tf_float y) {
   return crt_fmaxl(x, y);
 }
-#endif // CRT_LDBL_128BIT
+#define __compiler_rt_logbl crt_logbl
+#define __compiler_rt_scalbnl crt_scalbnl
+#define __compiler_rt_fmaxl crt_fmaxl
+#else
+#error Unsupported TF mode type
+#endif
 
 #endif // *_PRECISION
 
diff --git a/compiler-rt/lib/builtins/fp_trunc.h b/compiler-rt/lib/builtins/fp_trunc.h
index f62f8bafc7995f7..5e81eb73f94103d 100644
--- a/compiler-rt/lib/builtins/fp_trunc.h
+++ b/compiler-rt/lib/builtins/fp_trunc.h
@@ -36,13 +36,7 @@ static const int srcSigFracBits = 52;
 static const int srcExpBits = 11;
 
 #elif defined SRC_QUAD
-// TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
-#if __LDBL_MANT_DIG__ == 113
-typedef long double src_t;
-#elif defined(__x86_64__) &&                                                   \
-    (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
-typedef __float128 src_t;
-#endif
+typedef tf_float src_t;
 typedef __uint128_t src_rep_t;
 #define SRC_REP_C (__uint128_t)
 static const int srcBits = sizeof(src_t) * CHAR_BIT;
diff --git a/compiler-rt/lib/builtins/int_math.h b/compiler-rt/lib/builtins/int_math.h
index 48b9580f5961b01..74d3e311db5e710 100644
--- a/compiler-rt/lib/builtins/int_math.h
+++ b/compiler-rt/lib/builtins/int_math.h
@@ -65,6 +65,11 @@
 #define crt_copysign(x, y) __builtin_copysign((x), (y))
 #define crt_copysignf(x, y) __builtin_copysignf((x), (y))
 #define crt_copysignl(x, y) __builtin_copysignl((x), (y))
+#if __has_builtin(__builtin_copysignf128)
+#define crt_copysignf128(x, y) __builtin_copysignf128((x), (y))
+#elif __has_builtin(__builtin_copysignq) || (defined(__GNUC__) && __GNUC__ >= 7)
+#define crt_copysignf128(x, y) __builtin_copysignq((x), (y))
+#endif
 #endif
 
 #if defined(_MSC_VER) && !defined(__clang__)
@@ -75,6 +80,11 @@
 #define crt_fabs(x) __builtin_fabs((x))
 #define crt_fabsf(x) __builtin_fabsf((x))
 #define crt_fabsl(x) __builtin_fabsl((x))
+#if __has_builtin(__builtin_fabsf128)
+#define crt_fabsf128(x) __builtin_fabsf128((x))
+#elif __has_builtin(__builtin_fabsq) || (defined(__GNUC__) && __GNUC__ >= 7)
+#define crt_fabsf128(x) __builtin_fabsq((x))
+#endif
 #endif
 
 #if defined(_MSC_VER) && !defined(__clang__)
diff --git a/compiler-rt/lib/builtins/int_types.h b/compiler-rt/lib/builtins/int_types.h
index e94d3154c6d4ef6..f705844610f6ac5 100644
--- a/compiler-rt/lib/builtins/int_types.h
+++ b/compiler-rt/lib/builtins/int_types.h
@@ -165,6 +165,53 @@ typedef struct {
 #define HAS_80_BIT_LONG_DOUBLE 0
 #endif
 
+#ifdef __powerpc64__
+// From https://gcc.gnu.org/wiki/Ieee128PowerPC:
+// PowerPC64 uses the following suffixes:
+// IFmode: IBM extended double
+// KFmode: IEEE 128-bit floating point
+// TFmode: Matches the default for long double. With -mabi=ieeelongdouble,
+//         it is IEEE 128-bit, with -mabi=ibmlongdouble IBM extended double
+// Since compiler-rt only implements the tf set of libcalls, we use long double
+// for the tf_float typedef.
+typedef long double tf_float;
+#define CRT_LDBL_128BIT
+#define CRT_HAS_F128
+#if __LDBL_MANT_DIG__ == 113 && !defined(__LONG_DOUBLE_IBM128__)
+#define CRT_HAS_IEEE_TF
+#define CRT_LDBL_IEEE_F128
+#endif
+#define TF_C(x) x##L
+#elif __LDBL_MANT_DIG__ == 113
+// Use long double instead of __float128 if it matches the IEEE 128-bit format.
+#define CRT_LDBL_128BIT
+#define CRT_HAS_F128
+#define CRT_HAS_IEEE_TF
+#define CRT_LDBL_IEEE_F128
+typedef long double tf_float;
+#define TF_C(x) x##L
+#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
+#define CRT_HAS___FLOAT128_KEYWORD
+#define CRT_HAS_F128
+// NB: we assume the __float128 type uses IEEE representation.
+#define CRT_HAS_IEEE_TF
+typedef __float128 tf_float;
+#define TF_C(x) x##Q
+#endif
+
+#ifdef CRT_HAS_F128
+typedef union {
+  uqwords u;
+  tf_float f;
+} tf_bits;
+#endif
+
+// __(u)int128_t is currently needed to compile the *tf builtins as we would
+// otherwise need to manually expand the bit manipulation on two 64-bit value.
+#if defined(CRT_HAS_128BIT) && defined(CRT_HAS_F128)
+#define CRT_HAS_TF_MODE
+#endif
+
 #if CRT_HAS_FLOATING_POINT
 typedef union {
   uqwords u;
@@ -175,6 +222,20 @@ typedef union {
 typedef float _Complex Fcomplex;
 typedef double _Complex Dcomplex;
 typedef long double _Complex Lcomplex;
+#if defined(CRT_LDBL_128BIT)
+typedef Lcomplex Qcomplex;
+#define CRT_HAS_NATIVE_COMPLEX_F128
+#elif defined(CRT_HAS___FLOAT128_KEYWORD)
+#if defined(__clang_major__) && __clang_major__ > 10
+// Clang prior to 11 did not support __float128 _Complex.
+typedef __float128 _Complex Qcomplex;
+#define CRT_HAS_NATIVE_COMPLEX_F128
+#elif defined(__GNUC__) && __GNUC__ >= 7
+// GCC does not allow __float128 _Complex, but accepts _Float128 _Complex.
+typedef _Float128 _Complex Qcomplex;
+#define CRT_HAS_NATIVE_COMPLEX_F128
+#endif
+#endif
 
 #define COMPLEX_REAL(x) __real__(x)
 #define COMPLEX_IMAGINARY(x) __imag__(x)
@@ -194,5 +255,17 @@ typedef struct {
 #define COMPLEX_REAL(x) (x).real
 #define COMPLEX_IMAGINARY(x) (x).imaginary
 #endif
+
+#ifdef CRT_HAS_NATIVE_COMPLEX_F128
+#define COMPLEXTF_REAL(x) __real__(x)
+#define COMPLEXTF_IMAGINARY(x) __imag__(x)
+#elif defined(CRT_HAS_F128)
+typedef struct {
+  tf_float real, imaginary;
+} Qcomplex;
+#define COMPLEXTF_REAL(x) (x).real
+#define COMPLEXTF_IMAGINARY(x) (x).imaginary
+#endif
+
 #endif
 #endif // INT_TYPES_H
diff --git a/compiler-rt/lib/builtins/multc3.c b/compiler-rt/lib/builtins/multc3.c
index bb7f6aabfe2c8ec..f20e53ccbf233bb 100644
--- a/compiler-rt/lib/builtins/multc3.c
+++ b/compiler-rt/lib/builtins/multc3.c
@@ -10,56 +10,61 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define QUAD_PRECISION
+#include "fp_lib.h"
 #include "int_lib.h"
 #include "int_math.h"
 
+#if defined(CRT_HAS_TF_MODE)
+
 // Returns: the product of a + ib and c + id
 
-COMPILER_RT_ABI long double _Complex __multc3(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;
-  long double _Complex z;
-  __real__ z = ac - bd;
-  __imag__ z = ad + bc;
-  if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) {
+COMPILER_RT_ABI Qcomplex __multc3(fp_t a, fp_t b, fp_t c, fp_t d) {
+  fp_t ac = a * c;
+  fp_t bd = b * d;
+  fp_t ad = a * d;
+  fp_t bc = b * c;
+  Qcomplex z;
+  COMPLEXTF_REAL(z) = ac - bd;
+  COMPLEXTF_IMAGINARY(z) = ad + bc;
+  if (crt_isnan(COMPLEXTF_REAL(z)) && crt_isnan(COMPLEXTF_IMAGINARY(z))) {
     int recalc = 0;
     if (crt_isinf(a) || crt_isinf(b)) {
-      a = crt_copysignl(crt_isinf(a) ? 1 : 0, a);
-      b = crt_copysignl(crt_isinf(b) ? 1 : 0, b);
+      a = crt_copysigntf(crt_isinf(a) ? 1 : 0, a);
+      b = crt_copysigntf(crt_isinf(b) ? 1 : 0, b);
       if (crt_isnan(c))
-        c = crt_copysignl(0, c);
+        c = crt_copysigntf(0, c);
       if (crt_isnan(d))
-        d = crt_copysignl(0, d);
+        d = crt_copysigntf(0, d);
       recalc = 1;
     }
     if (crt_isinf(c) || crt_isinf(d)) {
-      c = crt_copysignl(crt_isinf(c) ? 1 : 0, c);
-      d = crt_copysignl(crt_isinf(d) ? 1 : 0, d);
+      c = crt_copysigntf(crt_isinf(c) ? 1 : 0, c);
+      d = crt_copysigntf(crt_isinf(d) ? 1 : 0, d);
       if (crt_isnan(a))
-        a = crt_copysignl(0, a);
+        a = crt_copysigntf(0, a);
       if (crt_isnan(b))
-        b = crt_copysignl(0, b);
+        b = crt_copysigntf(0, b);
       recalc = 1;
     }
     if (!recalc &&
         (crt_isinf(ac) || crt_isinf(bd) || crt_isinf(ad) || crt_isinf(bc))) {
       if (crt_isnan(a))
-        a = crt_copysignl(0, a);
+        a = crt_copysigntf(0, a);
       if (crt_isnan(b))
-        b = crt_copysignl(0, b);
+        b = crt_copysigntf(0, b);
       if (crt_isnan(c))
-        c = crt_copysignl(0, c);
+        c = crt_copysigntf(0, c);
       if (crt_isnan(d))
-        d = crt_copysignl(0, d);
+        d = crt_copysigntf(0, d);
       recalc = 1;
     }
     if (recalc) {
-      __real__ z = CRT_INFINITY * (a * c - b * d);
-      __imag__ z = CRT_INFINITY * (a * d + b * c);
+      COMPLEXTF_REAL(z) = CRT_INFINITY * (a * c - b * d);
+      COMPLEXTF_IMAGINARY(z) = CRT_INFINITY * (a * d + b * c);
     }
   }
   return z;
 }
+
+#endif
diff --git a/compiler-rt/lib/builtins/powitf2.c b/compiler-rt/lib/builtins/powitf2.c
index 74fe707a4e8c40e..e02db40767ac03d 100644
--- a/compiler-rt/lib/builtins/powitf2.c
+++ b/compiler-rt/lib/builtins/powitf2.c
@@ -17,9 +17,9 @@
 
 // Returns: a ^ b
 
-COMPILER_RT_ABI long double __powitf2(long double a, int b) {
+COMPILER_RT_ABI fp_t __powitf2(fp_t a, int b) {
   const int recip = b < 0;
-  long double r = 1;
+  fp_t r = 1;
   while (1) {
     if (b & 1)
       r *= a;
diff --git a/compiler-rt/lib/builtins/trunctfdf2.c b/compiler-rt/lib/builtins/trunctfdf2.c
index f0d2e4141f3b04d..a5bdded53751fdb 100644
--- a/compiler-rt/lib/builtins/trunctfdf2.c
+++ b/compiler-rt/lib/builtins/trunctfdf2.c
@@ -14,6 +14,6 @@
 #define DST_DOUBLE
 #include "fp_trunc_impl.inc"
 
-COMPILER_RT_ABI double __trunctfdf2(long double a) { return __truncXfYf2__(a); }
+COMPILER_RT_ABI dst_t __trunctfdf2(src_t a) { return __truncXfYf2__(a); }
 
 #endif
diff --git a/compiler-rt/lib/builtins/trunctfhf2.c b/compiler-rt/lib/builtins/trunctfhf2.c
index f7776327251c79f..3f031e0f844510c 100644
--- a/compiler-rt/lib/builtins/trunctfhf2.c
+++ b/compiler-rt/lib/builtins/trunctfhf2.c
@@ -15,8 +15,6 @@
 #define DST_HALF
 #include "fp_trunc_impl.inc"
 
-COMPILER_RT_ABI _Float16 __trunctfhf2(long double a) {
-  return __truncXfYf2__(a);
-}
+COMPILER_RT_ABI dst_t __trunctfhf2(src_t a) { return __truncXfYf2__(a); }
 
 #endif
diff --git a/compiler-rt/lib/builtins/trunctfsf2.c b/compiler-rt/lib/builtins/trunctfsf2.c
index 242735f738c1373..b65b5af2fc00178 100644
--- a/compiler-rt/lib/builtins/trunctfsf2.c
+++ b/compiler-rt/lib/builtins/trunctfsf2.c
@@ -14,6 +14,6 @@
 #define DST_SINGLE
 #include "fp_trunc_impl.inc"
 
-COMPILER_RT_ABI float __trunctfsf2(long double a) { return __truncXfYf2__(a); }
+COMPILER_RT_ABI dst_t __trunctfsf2(src_t a) { return __truncXfYf2__(a); }
 
 #endif
diff --git a/compiler-rt/lib/builtins/trunctfxf2.c b/compiler-rt/lib/builtins/trunctfxf2.c
index 4a22a602b38173f..4bb287f630f6896 100644
--- a/compiler-rt/lib/builtins/trunctfxf2.c
+++ b/compiler-rt/lib/builtins/trunctfxf2.c
@@ -17,7 +17,7 @@
 #define DST_80
 #include "fp_trunc_impl.inc"
 
-COMPILER_RT_ABI long double __trunctfxf2(__float128 a) {
+COMPILER_RT_ABI long double __trunctfxf2(tf_float a) {
   return __truncXfYf2__(a);
 }
 
diff --git a/compiler-rt/test/builtins/Unit/addtf3_test.c b/compiler-rt/test/builtins/Unit/addtf3_test.c
index e6986c236a64f5e..cd5872e7dedf403 100644
--- a/compiler-rt/test/builtins/Unit/addtf3_test.c
+++ b/compiler-rt/test/builtins/Unit/addtf3_test.c
@@ -4,102 +4,90 @@
 #include <fenv.h>
 #include <stdio.h>
 
-#if __LDBL_MANT_DIG__ == 113
+// The testcase currently assumes IEEE TF format, once that has been
+// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
+// IBM 128 floats as well.
+#if defined(CRT_HAS_IEEE_TF)
 
-#include "int_lib.h"
-#include "fp_test.h"
+#  include "fp_test.h"
+#  include "int_lib.h"
 
 // Returns: a + b
-COMPILER_RT_ABI long double __addtf3(long double a, long double b);
+COMPILER_RT_ABI tf_float __addtf3(tf_float a, tf_float b);
 
-int test__addtf3(long double a, long double b,
-                 uint64_t expectedHi, uint64_t expectedLo)
-{
-    long double x = __addtf3(a, b);
-    int ret = compareResultF128(x, expectedHi, expectedLo);
+int test__addtf3(tf_float a, tf_float b, uint64_t expectedHi,
+                 uint64_t expectedLo) {
+  tf_float x = __addtf3(a, b);
+  int ret = compareResultF128(x, expectedHi, expectedLo);
 
-    if (ret){
-        printf("error in test__addtf3(%.20Lf, %.20Lf) = %.20Lf, "
-               "expected %.20Lf\n", a, b, x,
-               fromRep128(expectedHi, expectedLo));
-    }
+  if (ret) {
+    printf("error in test__addtf3(%.20Lf, %.20Lf) = %.20Lf, "
+           "expected %.20Lf\n",
+           a, b, x, fromRep128(expectedHi, expectedLo));
+  }
 
-    return ret;
+  return ret;
 }
 
-char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
+char assumption_1[sizeof(tf_float) * CHAR_BIT == 128] = {0};
 
 #endif
 
-int main()
-{
-#if __LDBL_MANT_DIG__ == 113
-    // qNaN + any = qNaN
-    if (test__addtf3(makeQNaN128(),
-                     0x1.23456789abcdefp+5L,
-                     UINT64_C(0x7fff800000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // NaN + any = NaN
-    if (test__addtf3(makeNaN128(UINT64_C(0x800030000000)),
-                     0x1.23456789abcdefp+5L,
-                     UINT64_C(0x7fff800000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // inf + inf = inf
-    if (test__addtf3(makeInf128(),
-                     makeInf128(),
-                     UINT64_C(0x7fff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // inf + any = inf
-    if (test__addtf3(makeInf128(),
-                     0x1.2335653452436234723489432abcdefp+5L,
-                     UINT64_C(0x7fff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // any + any
-    if (test__addtf3(0x1.23456734245345543849abcdefp+5L,
-                     0x1.edcba52449872455634654321fp-1L,
-                     UINT64_C(0x40042afc95c8b579),
-                     UINT64_C(0x61e58dd6c51eb77c)))
-        return 1;
-
-#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \
-    defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && \
-    __loongarch_frlen != 0)
-    // Rounding mode tests on supported architectures
-    const long double m = 1234.0L, n = 0.01L;
-
-    fesetround(FE_UPWARD);
-    if (test__addtf3(m, n,
-                     UINT64_C(0x40093480a3d70a3d),
-                     UINT64_C(0x70a3d70a3d70a3d8)))
-        return 1;
-
-    fesetround(FE_DOWNWARD);
-    if (test__addtf3(m, n,
-                     UINT64_C(0x40093480a3d70a3d),
-                     UINT64_C(0x70a3d70a3d70a3d7)))
-        return 1;
-
-
-    fesetround(FE_TOWARDZERO);
-    if (test__addtf3(m, n,
-                     UINT64_C(0x40093480a3d70a3d),
-                     UINT64_C(0x70a3d70a3d70a3d7)))
-        return 1;
-
-    fesetround(FE_TONEAREST);
-    if (test__addtf3(m, n,
-                     UINT64_C(0x40093480a3d70a3d),
-                     UINT64_C(0x70a3d70a3d70a3d7)))
-        return 1;
-#endif
+int main() {
+#if defined(CRT_HAS_IEEE_TF)
+  // qNaN + any = qNaN
+  if (test__addtf3(makeQNaN128(), 0x1.23456789abcdefp+5L,
+                   UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
+    return 1;
+  // NaN + any = NaN
+  if (test__addtf3(makeNaN128(UINT64_C(0x800030000000)),
+                   TF_C(0x1.23456789abcdefp+5), UINT64_C(0x7fff800000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // inf + inf = inf
+  if (test__addtf3(makeInf128(), makeInf128(), UINT64_C(0x7fff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // inf + any = inf
+  if (test__addtf3(makeInf128(), TF_C(0x1.2335653452436234723489432abcdefp+5),
+                   UINT64_C(0x7fff000000000000), UINT64_C(0x0)))
+    return 1;
+  // any + any
+  if (test__addtf3(TF_C(0x1.23456734245345543849abcdefp+5),
+                   TF_C(0x1.edcba52449872455634654321fp-1),
+                   UINT64_C(0x40042afc95c8b579), UINT64_C(0x61e58dd6c51eb77c)))
+    return 1;
+
+#  if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) ||       \
+      defined(i386) || defined(__x86_64__) ||                                  \
+      (defined(__loongarch__) && __loongarch_frlen != 0)
+  // Rounding mode tests on supported architectures
+  const tf_float m = 1234.0L, n = 0.01L;
+
+  fesetround(FE_UPWARD);
+  if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d),
+                   UINT64_C(0x70a3d70a3d70a3d8)))
+    return 1;
+
+  fesetround(FE_DOWNWARD);
+  if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d),
+                   UINT64_C(0x70a3d70a3d70a3d7)))
+    return 1;
+
+  fesetround(FE_TOWARDZERO);
+  if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d),
+                   UINT64_C(0x70a3d70a3d70a3d7)))
+    return 1;
+
+  fesetround(FE_TONEAREST);
+  if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d),
+                   UINT64_C(0x70a3d70a3d70a3d7)))
+    return 1;
+#  endif
 
 #else
-    printf("skipped\n");
+  printf("skipped\n");
 
 #endif
-    return 0;
+  return 0;
 }
diff --git a/compiler-rt/test/builtins/Unit/compiler_rt_fmaxl_test.c b/compiler-rt/test/builtins/Unit/compiler_rt_fmaxl_test.c
index 7b99514aad4e30a..44f75cf0c3c2a83 100644
--- a/compiler-rt/test/builtins/Unit/compiler_rt_fmaxl_test.c
+++ b/compiler-rt/test/builtins/Unit/compiler_rt_fmaxl_test.c
@@ -6,7 +6,10 @@
 #include <stdio.h>
 #include "fp_lib.h"
 
-#if defined(CRT_HAS_TF_MODE)
+// Since we are comparing the compiler-rt IEEE implementation against libc's
+// long double implementation, this test can only succeed if long double
+// is an IEEE 128-bit floating point number.
+#if defined(CRT_HAS_TF_MODE) && defined(CRT_LDBL_IEEE_F128)
 
 int test__compiler_rt_fmaxl(fp_t x, fp_t y) {
   fp_t crt_value = __compiler_rt_fmaxl(x, y);
@@ -40,10 +43,7 @@ fp_t cases[] = {
   -1.001, 1.001, -1.002, 1.002,
 };
 
-#endif
-
 int main() {
-#if defined(CRT_HAS_TF_MODE)
   const unsigned N = sizeof(cases) / sizeof(cases[0]);
   unsigned i, j;
   for (i = 0; i < N; ++i) {
@@ -51,8 +51,11 @@ int main() {
       if (test__compiler_rt_fmaxl(cases[i], cases[j])) return 1;
     }
   }
+  return 0;
+}
 #else
+int main() {
   printf("skipped\n");
-#endif
   return 0;
 }
+#endif
diff --git a/compiler-rt/test/builtins/Unit/compiler_rt_logbl_test.c b/compiler-rt/test/builtins/Unit/compiler_rt_logbl_test.c
index f48e67e7887cdc7..2bbcd540c8c827c 100644
--- a/compiler-rt/test/builtins/Unit/compiler_rt_logbl_test.c
+++ b/compiler-rt/test/builtins/Unit/compiler_rt_logbl_test.c
@@ -6,7 +6,10 @@
 #include "fp_lib.h"
 #include "int_lib.h"
 
-#if defined(CRT_HAS_TF_MODE)
+// Since we are comparing the compiler-rt IEEE implementation against libc's
+// long double implementation, this test can only succeed if long double
+// is an IEEE 128-bit floating point number.
+#if defined(CRT_HAS_TF_MODE) && defined(CRT_LDBL_IEEE_F128)
 
 int test__compiler_rt_logbl(fp_t x) {
 #if defined(__ve__)
@@ -34,15 +37,12 @@ int test__compiler_rt_logbl(fp_t x) {
   return 0;
 }
 
-double cases[] = {
+fp_t cases[] = {
     1.e-6, -1.e-6, NAN, -NAN, INFINITY, -INFINITY, -1,
     -0.0,  0.0,    1,   -2,   2,        -0.5,      0.5,
 };
 
-#endif
-
 int main() {
-#if defined(CRT_HAS_TF_MODE)
   const unsigned N = sizeof(cases) / sizeof(cases[0]);
   unsigned i;
   for (i = 0; i < N; ++i) {
@@ -64,9 +64,12 @@ int main() {
     if (test__compiler_rt_logbl(fromRep(signBit ^ x))) return 1;
     x >>= 1;
   }
+
+  return 0;
+}
 #else
+int main() {
   printf("skipped\n");
-#endif
-
   return 0;
 }
+#endif
diff --git a/compiler-rt/test/builtins/Unit/compiler_rt_scalbnl_test.c b/compiler-rt/test/builtins/Unit/compiler_rt_scalbnl_test.c
index 79193334c65d9f9..28407e274af8dc1 100644
--- a/compiler-rt/test/builtins/Unit/compiler_rt_scalbnl_test.c
+++ b/compiler-rt/test/builtins/Unit/compiler_rt_scalbnl_test.c
@@ -8,7 +8,10 @@
 #include <stdio.h>
 #include "fp_lib.h"
 
-#if defined(CRT_HAS_TF_MODE)
+// Since we are comparing the compiler-rt IEEE implementation against libc's
+// long double implementation, this test can only succeed if long double
+// is an IEEE 128-bit floating point number.
+#if defined(CRT_HAS_TF_MODE) && defined(CRT_LDBL_IEEE_F128)
 
 int test__compiler_rt_scalbnl(const char *mode, fp_t x, int y) {
 #if defined(__ve__)
@@ -64,18 +67,18 @@ int iterate_cases(const char *mode) {
   return 0;
 }
 
-#endif
-
 int main() {
-#if defined(CRT_HAS_TF_MODE)
   if (iterate_cases("default")) return 1;
 
   // Skip rounding mode tests (fesetround) because compiler-rt's quad-precision
   // multiply also ignores the current rounding mode.
 
+  return 0;
+}
+
 #else
+int main() {
   printf("skipped\n");
-#endif
-
   return 0;
 }
+#endif
diff --git a/compiler-rt/test/builtins/Unit/divtc3_test.c b/compiler-rt/test/builtins/Unit/divtc3_test.c
index 18042031ccf0ba1..9ba4880f4a11027 100644
--- a/compiler-rt/test/builtins/Unit/divtc3_test.c
+++ b/compiler-rt/test/builtins/Unit/divtc3_test.c
@@ -9,362 +9,357 @@
 #include <stdio.h>
 
 #include "int_lib.h"
-#include <math.h>
+#include "int_math.h"
 #include <complex.h>
-
+#include <math.h>
 
 // Returns: the quotient of (a + ib) / (c + id)
 
-COMPILER_RT_ABI long double _Complex
-__divtc3(long double __a, long double __b, long double __c, long double __d);
+COMPILER_RT_ABI Qcomplex __divtc3(tf_float __a, tf_float __b, tf_float __c,
+                                  tf_float __d);
 
 enum {zero, non_zero, inf, NaN, non_zero_nan};
 
-int
-classify(long double _Complex x)
-{
-    if (x == 0)
-        return zero;
-    if (isinf(creall(x)) || isinf(cimagl(x)))
-        return inf;
-    if (isnan(creall(x)) && isnan(cimagl(x)))
-        return NaN;
-    if (isnan(creall(x)))
-    {
-        if (cimagl(x) == 0)
-            return NaN;
-        return non_zero_nan;
-    }
-    if (isnan(cimagl(x)))
-    {
-        if (creall(x) == 0)
-            return NaN;
-        return non_zero_nan;
-    }
-    return non_zero;
+static int classify(Qcomplex x) {
+  tf_float real = COMPLEXTF_REAL(x);
+  tf_float imag = COMPLEXTF_IMAGINARY(x);
+  if (real == 0.0 && imag == 0.0)
+    return zero;
+  if (crt_isinf(real) || crt_isinf(imag))
+    return inf;
+  if (crt_isnan(real) && crt_isnan(imag))
+    return NaN;
+  if (crt_isnan(real)) {
+    if (imag == 0.0)
+      return NaN;
+    return non_zero_nan;
+  }
+  if (crt_isnan(imag)) {
+    if (real == 0.0)
+      return NaN;
+    return non_zero_nan;
+  }
+  return non_zero;
 }
 
-int test__divtc3(long double a, long double b, long double c, long double d)
-{
-    long double _Complex r = __divtc3(a, b, c, d);
-//      printf("test__divtc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n",
-//              a, b, c, d, creall(r), cimagl(r));
-	
-	long double _Complex dividend;
-	long double _Complex divisor;
-	
-	__real__ dividend = a;
-	__imag__ dividend = b;
-	__real__ divisor = c;
-	__imag__ divisor = d;
-	
-    switch (classify(dividend))
-    {
+static int test__divtc3(tf_float a, tf_float b, tf_float c, tf_float d) {
+  Qcomplex r = __divtc3(a, b, c, d);
+  Qcomplex dividend;
+  Qcomplex divisor;
+
+  COMPLEXTF_REAL(dividend) = a;
+  COMPLEXTF_IMAGINARY(dividend) = b;
+  COMPLEXTF_REAL(divisor) = c;
+  COMPLEXTF_IMAGINARY(divisor) = d;
+
+  switch (classify(dividend)) {
+  case zero:
+    switch (classify(divisor)) {
+    case zero:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    case non_zero:
+      if (classify(r) != zero)
+        return 1;
+      break;
+    case inf:
+      if (classify(r) != zero)
+        return 1;
+      break;
+    case NaN:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    case non_zero_nan:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    }
+    break;
+  case non_zero:
+    switch (classify(divisor)) {
+    case zero:
+      if (classify(r) != inf)
+        return 1;
+      break;
+    case non_zero:
+      if (classify(r) != non_zero)
+        return 1;
+      {
+        tf_float zReal = (a * c + b * d) / (c * c + d * d);
+        tf_float zImag = (b * c - a * d) / (c * c + d * d);
+        Qcomplex diff =
+            __divtc3(COMPLEXTF_REAL(r) - zReal, COMPLEXTF_IMAGINARY(r) - zImag,
+                     COMPLEXTF_REAL(r), COMPLEXTF_IMAGINARY(r));
+        // cabsl(z) == hypotl(creall(z), cimagl(z))
+#ifdef CRT_LDBL_128BIT
+        if (hypotl(COMPLEXTF_REAL(diff), COMPLEXTF_IMAGINARY(diff)) > 1.e-6)
+#else
+        // Avoid dependency on __trunctfxf2 for ld80 platforms and use double instead.
+        if (hypot(COMPLEXTF_REAL(diff), COMPLEXTF_IMAGINARY(diff)) > 1.e-6)
+#endif
+          return 1;
+      }
+      break;
+    case inf:
+      if (classify(r) != zero)
+        return 1;
+      break;
+    case NaN:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    case non_zero_nan:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    }
+    break;
+  case inf:
+    switch (classify(divisor)) {
+    case zero:
+      if (classify(r) != inf)
+        return 1;
+      break;
+    case non_zero:
+      if (classify(r) != inf)
+        return 1;
+      break;
+    case inf:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    case NaN:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    case non_zero_nan:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    }
+    break;
+  case NaN:
+    switch (classify(divisor)) {
+    case zero:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    case non_zero:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    case inf:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    case NaN:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    case non_zero_nan:
+      if (classify(r) != NaN)
+        return 1;
+      break;
+    }
+    break;
+  case non_zero_nan:
+    switch (classify(divisor)) {
     case zero:
-        switch (classify(divisor))
-        {
-        case zero:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case non_zero:
-            if (classify(r) != zero)
-                return 1;
-            break;
-        case inf:
-            if (classify(r) != zero)
-                return 1;
-            break;
-        case NaN:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case non_zero_nan:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        }
-        break;
+      if (classify(r) != inf)
+        return 1;
+      break;
     case non_zero:
-        switch (classify(divisor))
-        {
-        case zero:
-            if (classify(r) != inf)
-                return 1;
-            break;
-        case non_zero:
-            if (classify(r) != non_zero)
-                return 1;
-            {
-            long double _Complex z = (a * c + b * d) / (c * c + d * d)
-                                   + (b * c - a * d) / (c * c + d * d) * _Complex_I;
-            if (cabsl((r - z)/r) > 1.e-6)
-                return 1;
-            }
-            break;
-        case inf:
-            if (classify(r) != zero)
-                return 1;
-            break;
-        case NaN:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case non_zero_nan:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        }
-        break;
+      if (classify(r) != NaN)
+        return 1;
+      break;
     case inf:
-        switch (classify(divisor))
-        {
-        case zero:
-            if (classify(r) != inf)
-                return 1;
-            break;
-        case non_zero:
-            if (classify(r) != inf)
-                return 1;
-            break;
-        case inf:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case NaN:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case non_zero_nan:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        }
-        break;
+      if (classify(r) != NaN)
+        return 1;
+      break;
     case NaN:
-        switch (classify(divisor))
-        {
-        case zero:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case non_zero:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case inf:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case NaN:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case non_zero_nan:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        }
-        break;
+      if (classify(r) != NaN)
+        return 1;
+      break;
     case non_zero_nan:
-        switch (classify(divisor))
-        {
-        case zero:
-            if (classify(r) != inf)
-                return 1;
-            break;
-        case non_zero:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case inf:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case NaN:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        case non_zero_nan:
-            if (classify(r) != NaN)
-                return 1;
-            break;
-        }
-        break;
+      if (classify(r) != NaN)
+        return 1;
+      break;
     }
-    
-    return 0;
+    break;
+  }
+
+  return 0;
 }
 
-long double x[][2] =
-{
-    { 1.e-6,  1.e-6},
-    {-1.e-6,  1.e-6},
-    {-1.e-6, -1.e-6},
-    { 1.e-6, -1.e-6},
+tf_float x[][2] = {{1.e-6, 1.e-6},
+                   {-1.e-6, 1.e-6},
+                   {-1.e-6, -1.e-6},
+                   {1.e-6, -1.e-6},
 
-    { 1.e+6,  1.e-6},
-    {-1.e+6,  1.e-6},
-    {-1.e+6, -1.e-6},
-    { 1.e+6, -1.e-6},
+                   {1.e+6, 1.e-6},
+                   {-1.e+6, 1.e-6},
+                   {-1.e+6, -1.e-6},
+                   {1.e+6, -1.e-6},
 
-    { 1.e-6,  1.e+6},
-    {-1.e-6,  1.e+6},
-    {-1.e-6, -1.e+6},
-    { 1.e-6, -1.e+6},
+                   {1.e-6, 1.e+6},
+                   {-1.e-6, 1.e+6},
+                   {-1.e-6, -1.e+6},
+                   {1.e-6, -1.e+6},
 
-    { 1.e+6,  1.e+6},
-    {-1.e+6,  1.e+6},
-    {-1.e+6, -1.e+6},
-    { 1.e+6, -1.e+6},
+                   {1.e+6, 1.e+6},
+                   {-1.e+6, 1.e+6},
+                   {-1.e+6, -1.e+6},
+                   {1.e+6, -1.e+6},
 
-    {NAN, NAN},
-    {-INFINITY, NAN},
-    {-2, NAN},
-    {-1, NAN},
-    {-0.5, NAN},
-    {-0., NAN},
-    {+0., NAN},
-    {0.5, NAN},
-    {1, NAN},
-    {2, NAN},
-    {INFINITY, NAN},
+                   {NAN, NAN},
+                   {-INFINITY, NAN},
+                   {-2, NAN},
+                   {-1, NAN},
+                   {-0.5, NAN},
+                   {-0., NAN},
+                   {+0., NAN},
+                   {0.5, NAN},
+                   {1, NAN},
+                   {2, NAN},
+                   {INFINITY, NAN},
 
-    {NAN, -INFINITY},
-    {-INFINITY, -INFINITY},
-    {-2, -INFINITY},
-    {-1, -INFINITY},
-    {-0.5, -INFINITY},
-    {-0., -INFINITY},
-    {+0., -INFINITY},
-    {0.5, -INFINITY},
-    {1, -INFINITY},
-    {2, -INFINITY},
-    {INFINITY, -INFINITY},
+                   {NAN, -INFINITY},
+                   {-INFINITY, -INFINITY},
+                   {-2, -INFINITY},
+                   {-1, -INFINITY},
+                   {-0.5, -INFINITY},
+                   {-0., -INFINITY},
+                   {+0., -INFINITY},
+                   {0.5, -INFINITY},
+                   {1, -INFINITY},
+                   {2, -INFINITY},
+                   {INFINITY, -INFINITY},
 
-    {NAN, -2},
-    {-INFINITY, -2},
-    {-2, -2},
-    {-1, -2},
-    {-0.5, -2},
-    {-0., -2},
-    {+0., -2},
-    {0.5, -2},
-    {1, -2},
-    {2, -2},
-    {INFINITY, -2},
+                   {NAN, -2},
+                   {-INFINITY, -2},
+                   {-2, -2},
+                   {-1, -2},
+                   {-0.5, -2},
+                   {-0., -2},
+                   {+0., -2},
+                   {0.5, -2},
+                   {1, -2},
+                   {2, -2},
+                   {INFINITY, -2},
 
-    {NAN, -1},
-    {-INFINITY, -1},
-    {-2, -1},
-    {-1, -1},
-    {-0.5, -1},
-    {-0., -1},
-    {+0., -1},
-    {0.5, -1},
-    {1, -1},
-    {2, -1},
-    {INFINITY, -1},
+                   {NAN, -1},
+                   {-INFINITY, -1},
+                   {-2, -1},
+                   {-1, -1},
+                   {-0.5, -1},
+                   {-0., -1},
+                   {+0., -1},
+                   {0.5, -1},
+                   {1, -1},
+                   {2, -1},
+                   {INFINITY, -1},
 
-    {NAN, -0.5},
-    {-INFINITY, -0.5},
-    {-2, -0.5},
-    {-1, -0.5},
-    {-0.5, -0.5},
-    {-0., -0.5},
-    {+0., -0.5},
-    {0.5, -0.5},
-    {1, -0.5},
-    {2, -0.5},
-    {INFINITY, -0.5},
+                   {NAN, -0.5},
+                   {-INFINITY, -0.5},
+                   {-2, -0.5},
+                   {-1, -0.5},
+                   {-0.5, -0.5},
+                   {-0., -0.5},
+                   {+0., -0.5},
+                   {0.5, -0.5},
+                   {1, -0.5},
+                   {2, -0.5},
+                   {INFINITY, -0.5},
 
-    {NAN, -0.},
-    {-INFINITY, -0.},
-    {-2, -0.},
-    {-1, -0.},
-    {-0.5, -0.},
-    {-0., -0.},
-    {+0., -0.},
-    {0.5, -0.},
-    {1, -0.},
-    {2, -0.},
-    {INFINITY, -0.},
+                   {NAN, -0.},
+                   {-INFINITY, -0.},
+                   {-2, -0.},
+                   {-1, -0.},
+                   {-0.5, -0.},
+                   {-0., -0.},
+                   {+0., -0.},
+                   {0.5, -0.},
+                   {1, -0.},
+                   {2, -0.},
+                   {INFINITY, -0.},
 
-    {NAN, 0.},
-    {-INFINITY, 0.},
-    {-2, 0.},
-    {-1, 0.},
-    {-0.5, 0.},
-    {-0., 0.},
-    {+0., 0.},
-    {0.5, 0.},
-    {1, 0.},
-    {2, 0.},
-    {INFINITY, 0.},
+                   {NAN, 0.},
+                   {-INFINITY, 0.},
+                   {-2, 0.},
+                   {-1, 0.},
+                   {-0.5, 0.},
+                   {-0., 0.},
+                   {+0., 0.},
+                   {0.5, 0.},
+                   {1, 0.},
+                   {2, 0.},
+                   {INFINITY, 0.},
 
-    {NAN, 0.5},
-    {-INFINITY, 0.5},
-    {-2, 0.5},
-    {-1, 0.5},
-    {-0.5, 0.5},
-    {-0., 0.5},
-    {+0., 0.5},
-    {0.5, 0.5},
-    {1, 0.5},
-    {2, 0.5},
-    {INFINITY, 0.5},
+                   {NAN, 0.5},
+                   {-INFINITY, 0.5},
+                   {-2, 0.5},
+                   {-1, 0.5},
+                   {-0.5, 0.5},
+                   {-0., 0.5},
+                   {+0., 0.5},
+                   {0.5, 0.5},
+                   {1, 0.5},
+                   {2, 0.5},
+                   {INFINITY, 0.5},
 
-    {NAN, 1},
-    {-INFINITY, 1},
-    {-2, 1},
-    {-1, 1},
-    {-0.5, 1},
-    {-0., 1},
-    {+0., 1},
-    {0.5, 1},
-    {1, 1},
-    {2, 1},
-    {INFINITY, 1},
+                   {NAN, 1},
+                   {-INFINITY, 1},
+                   {-2, 1},
+                   {-1, 1},
+                   {-0.5, 1},
+                   {-0., 1},
+                   {+0., 1},
+                   {0.5, 1},
+                   {1, 1},
+                   {2, 1},
+                   {INFINITY, 1},
 
-    {NAN, 2},
-    {-INFINITY, 2},
-    {-2, 2},
-    {-1, 2},
-    {-0.5, 2},
-    {-0., 2},
-    {+0., 2},
-    {0.5, 2},
-    {1, 2},
-    {2, 2},
-    {INFINITY, 2},
+                   {NAN, 2},
+                   {-INFINITY, 2},
+                   {-2, 2},
+                   {-1, 2},
+                   {-0.5, 2},
+                   {-0., 2},
+                   {+0., 2},
+                   {0.5, 2},
+                   {1, 2},
+                   {2, 2},
+                   {INFINITY, 2},
 
-    {NAN, INFINITY},
-    {-INFINITY, INFINITY},
-    {-2, INFINITY},
-    {-1, INFINITY},
-    {-0.5, INFINITY},
-    {-0., INFINITY},
-    {+0., INFINITY},
-    {0.5, INFINITY},
-    {1, INFINITY},
-    {2, INFINITY},
-    {INFINITY, INFINITY}
+                   {NAN, INFINITY},
+                   {-INFINITY, INFINITY},
+                   {-2, INFINITY},
+                   {-1, INFINITY},
+                   {-0.5, INFINITY},
+                   {-0., INFINITY},
+                   {+0., INFINITY},
+                   {0.5, INFINITY},
+                   {1, INFINITY},
+                   {2, INFINITY},
+                   {INFINITY, INFINITY}
 
 };
 
-int main()
-{
-    const unsigned N = sizeof(x) / sizeof(x[0]);
-    unsigned i, j;
-    for (i = 0; i < N; ++i)
-    {
-        for (j = 0; j < N; ++j)
-        {
-            if (test__divtc3(x[i][0], x[i][1], x[j][0], x[j][1]))
-                return 1;
-        }
+int main() {
+  const unsigned N = sizeof(x) / sizeof(x[0]);
+  unsigned i, j;
+  for (i = 0; i < N; ++i) {
+    for (j = 0; j < N; ++j) {
+      if (test__divtc3(x[i][0], x[i][1], x[j][0], x[j][1])) {
+        fprintf(stderr, "Failed for %g, %g, %g, %g\n", (double)x[i][0],
+                (double)x[i][1], (double)x[j][0], (double)x[j][1]);
+        return 1;
+      }
     }
+  }
 
-//	printf("No errors found.\n");
-    return 0;
+  fprintf(stderr, "No errors found.\n");
+  return 0;
 }
diff --git a/compiler-rt/test/builtins/Unit/divtf3_test.c b/compiler-rt/test/builtins/Unit/divtf3_test.c
index da6465636e92326..d46fcc047769381 100644
--- a/compiler-rt/test/builtins/Unit/divtf3_test.c
+++ b/compiler-rt/test/builtins/Unit/divtf3_test.c
@@ -4,190 +4,161 @@
 #include "int_lib.h"
 #include <stdio.h>
 
-#if __LDBL_MANT_DIG__ == 113
+// The testcase currently assumes IEEE TF format, once that has been
+// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
+// IBM 128 floats as well.
+#if defined(CRT_HAS_IEEE_TF)
 
-#include "fp_test.h"
+#  include "fp_test.h"
 
 // Returns: a / b
-COMPILER_RT_ABI long double __divtf3(long double a, long double b);
-
-int test__divtf3(long double a, long double b,
-                 uint64_t expectedHi, uint64_t expectedLo)
-{
-    long double x = __divtf3(a, b);
-    int ret = compareResultF128(x, expectedHi, expectedLo);
-
-    if (ret){
-        printf("error in test__divtf3(%.20Le, %.20Le) = %.20Le, "
-               "expected %.20Le\n", a, b, x,
-               fromRep128(expectedHi, expectedLo));
-    }
-    return ret;
+COMPILER_RT_ABI tf_float __divtf3(tf_float a, tf_float b);
+
+int test__divtf3(tf_float a, tf_float b, uint64_t expectedHi,
+                 uint64_t expectedLo) {
+  tf_float x = __divtf3(a, b);
+  int ret = compareResultF128(x, expectedHi, expectedLo);
+
+  if (ret) {
+    printf("error in test__divtf3(%.20Le, %.20Le) = %.20Le, "
+           "expected %.20Le\n",
+           a, b, x, fromRep128(expectedHi, expectedLo));
+  }
+  return ret;
 }
 
-char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
+char assumption_1[sizeof(tf_float) * CHAR_BIT == 128] = {0};
 
 #endif
 
-int main()
-{
-#if __LDBL_MANT_DIG__ == 113
-    // Returned NaNs are assumed to be qNaN by default
-
-    // qNaN / any = qNaN
-    if (test__divtf3(makeQNaN128(),
-                     0x1.23456789abcdefp+5L,
-                     UINT64_C(0x7fff800000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // NaN / any = NaN
-    if (test__divtf3(makeNaN128(UINT64_C(0x30000000)),
-                     0x1.23456789abcdefp+5L,
-                     UINT64_C(0x7fff800000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // any / qNaN = qNaN
-    if (test__divtf3(0x1.23456789abcdefp+5L,
-                     makeQNaN128(),
-                     UINT64_C(0x7fff800000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // any / NaN = NaN
-    if (test__divtf3(0x1.23456789abcdefp+5L,
-                     makeNaN128(UINT64_C(0x30000000)),
-                     UINT64_C(0x7fff800000000000),
-                     UINT64_C(0x0)))
-        return 1;
-
-    // +Inf / positive = +Inf
-    if (test__divtf3(makeInf128(), 3.L,
-                     UINT64_C(0x7fff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // +Inf / negative = -Inf
-    if (test__divtf3(makeInf128(), -3.L,
-                     UINT64_C(0xffff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // -Inf / positive = -Inf
-    if (test__divtf3(makeNegativeInf128(), 3.L,
-                     UINT64_C(0xffff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // -Inf / negative = +Inf
-    if (test__divtf3(makeNegativeInf128(), -3.L,
-                     UINT64_C(0x7fff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-
-    // Inf / Inf = NaN
-    if (test__divtf3(makeInf128(), makeInf128(),
-                     UINT64_C(0x7fff800000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // 0.0 / 0.0 = NaN
-    if (test__divtf3(+0x0.0p+0L, +0x0.0p+0L,
-                     UINT64_C(0x7fff800000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // +0.0 / +Inf = +0.0
-    if (test__divtf3(+0x0.0p+0L, makeInf128(),
-                     UINT64_C(0x0),
-                     UINT64_C(0x0)))
-        return 1;
-    // +Inf / +0.0 = +Inf
-    if (test__divtf3(makeInf128(), +0x0.0p+0L,
-                     UINT64_C(0x7fff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-
-    // positive / +0.0 = +Inf
-    if (test__divtf3(+1.0L, +0x0.0p+0L,
-                     UINT64_C(0x7fff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // positive / -0.0 = -Inf
-    if (test__divtf3(+1.0L, -0x0.0p+0L,
-                     UINT64_C(0xffff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // negative / +0.0 = -Inf
-    if (test__divtf3(-1.0L, +0x0.0p+0L,
-                     UINT64_C(0xffff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // negative / -0.0 = +Inf
-    if (test__divtf3(-1.0L, -0x0.0p+0L,
-                     UINT64_C(0x7fff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-
-    // 1/3
-    if (test__divtf3(1.L, 3.L,
-                     UINT64_C(0x3ffd555555555555),
-                     UINT64_C(0x5555555555555555)))
-        return 1;
-    // smallest normal result
-    if (test__divtf3(0x1.0p-16381L, 2.L,
-                     UINT64_C(0x0001000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-
-    // divisor is exactly 1.0
-    if (test__divtf3(0x1.0p+0L,
-                     0x1.0p+0L,
-                     UINT64_C(0x3fff000000000000),
-                     UINT64_C(0x0)))
-        return 1;
-    // divisor is truncated to exactly 1.0 in UQ1.63
-    if (test__divtf3(0x1.0p+0L,
-                     0x1.0000000000000001p+0L,
-                     UINT64_C(0x3ffeffffffffffff),
-                     UINT64_C(0xfffe000000000000)))
-        return 1;
-
-    // smallest normal value divided by 2.0
-    if (test__divtf3(0x1.0p-16382L, 2.L, UINT64_C(0x0000800000000000), UINT64_C(0x0)))
-      return 1;
-    // smallest subnormal result
-    if (test__divtf3(0x1.0p-16382L, 0x1p+112L, UINT64_C(0x0), UINT64_C(0x1)))
-      return 1;
-
-    // any / any
-    if (test__divtf3(0x1.a23b45362464523375893ab4cdefp+5L,
-                     0x1.eedcbaba3a94546558237654321fp-1L,
-                     UINT64_C(0x4004b0b72924d407),
-                     UINT64_C(0x0717e84356c6eba2)))
-        return 1;
-    if (test__divtf3(0x1.a2b34c56d745382f9abf2c3dfeffp-50L,
-                     0x1.ed2c3ba15935332532287654321fp-9L,
-                     UINT64_C(0x3fd5b2af3f828c9b),
-                     UINT64_C(0x40e51f64cde8b1f2)))
-        return 15;
-    if (test__divtf3(0x1.2345f6aaaa786555f42432abcdefp+456L,
-                     0x1.edacbba9874f765463544dd3621fp+6400L,
-                     UINT64_C(0x28c62e15dc464466),
-                     UINT64_C(0xb5a07586348557ac)))
-        return 1;
-    if (test__divtf3(0x1.2d3456f789ba6322bc665544edefp-234L,
-                     0x1.eddcdba39f3c8b7a36564354321fp-4455L,
-                     UINT64_C(0x507b38442b539266),
-                     UINT64_C(0x22ce0f1d024e1252)))
-        return 1;
-    if (test__divtf3(0x1.2345f6b77b7a8953365433abcdefp+234L,
-                     0x1.edcba987d6bb3aa467754354321fp-4055L,
-                     UINT64_C(0x50bf2e02f0798d36),
-                     UINT64_C(0x5e6fcb6b60044078)))
-        return 1;
-    if (test__divtf3(6.72420628622418701252535563464350521E-4932L,
-                     2.L,
-                     UINT64_C(0x0001000000000000),
-                     UINT64_C(0)))
-        return 1;
+int main() {
+#if defined(CRT_HAS_IEEE_TF)
+  // Returned NaNs are assumed to be qNaN by default
+
+  // qNaN / any = qNaN
+  if (test__divtf3(makeQNaN128(), TF_C(0x1.23456789abcdefp+5),
+                   UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
+    return 1;
+  // NaN / any = NaN
+  if (test__divtf3(makeNaN128(UINT64_C(0x30000000)),
+                   TF_C(0x1.23456789abcdefp+5), UINT64_C(0x7fff800000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // any / qNaN = qNaN
+  if (test__divtf3(TF_C(0x1.23456789abcdefp+5), makeQNaN128(),
+                   UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
+    return 1;
+  // any / NaN = NaN
+  if (test__divtf3(TF_C(0x1.23456789abcdefp+5),
+                   makeNaN128(UINT64_C(0x30000000)),
+                   UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
+    return 1;
+
+  // +Inf / positive = +Inf
+  if (test__divtf3(makeInf128(), TF_C(3.), UINT64_C(0x7fff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // +Inf / negative = -Inf
+  if (test__divtf3(makeInf128(), -TF_C(3.), UINT64_C(0xffff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // -Inf / positive = -Inf
+  if (test__divtf3(makeNegativeInf128(), TF_C(3.), UINT64_C(0xffff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // -Inf / negative = +Inf
+  if (test__divtf3(makeNegativeInf128(), -TF_C(3.),
+                   UINT64_C(0x7fff000000000000), UINT64_C(0x0)))
+    return 1;
+
+  // Inf / Inf = NaN
+  if (test__divtf3(makeInf128(), makeInf128(), UINT64_C(0x7fff800000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // 0.0 / 0.0 = NaN
+  if (test__divtf3(+TF_C(0x0.0p+0), +TF_C(0x0.0p+0),
+                   UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
+    return 1;
+  // +0.0 / +Inf = +0.0
+  if (test__divtf3(+TF_C(0x0.0p+0), makeInf128(), UINT64_C(0x0), UINT64_C(0x0)))
+    return 1;
+  // +Inf / +0.0 = +Inf
+  if (test__divtf3(makeInf128(), +TF_C(0x0.0p+0), UINT64_C(0x7fff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+
+  // positive / +0.0 = +Inf
+  if (test__divtf3(+TF_C(1.0), +TF_C(0x0.0p+0), UINT64_C(0x7fff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // positive / -0.0 = -Inf
+  if (test__divtf3(+1.0L, -TF_C(0x0.0p+0), UINT64_C(0xffff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // negative / +0.0 = -Inf
+  if (test__divtf3(-1.0L, +TF_C(0x0.0p+0), UINT64_C(0xffff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // negative / -0.0 = +Inf
+  if (test__divtf3(TF_C(-1.0), -TF_C(0x0.0p+0), UINT64_C(0x7fff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+
+  // 1/3
+  if (test__divtf3(TF_C(1.), TF_C(3.), UINT64_C(0x3ffd555555555555),
+                   UINT64_C(0x5555555555555555)))
+    return 1;
+  // smallest normal result
+  if (test__divtf3(TF_C(0x1.0p-16381), TF_C(2.), UINT64_C(0x0001000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+
+  // divisor is exactly 1.0
+  if (test__divtf3(TF_C(0x1.0p+0), TF_C(0x1.0p+0), UINT64_C(0x3fff000000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // divisor is truncated to exactly 1.0 in UQ1.63
+  if (test__divtf3(TF_C(0x1.0p+0), TF_C(0x1.0000000000000001p+0),
+                   UINT64_C(0x3ffeffffffffffff), UINT64_C(0xfffe000000000000)))
+    return 1;
+
+  // smallest normal value divided by 2.0
+  if (test__divtf3(TF_C(0x1.0p-16382), 2.L, UINT64_C(0x0000800000000000),
+                   UINT64_C(0x0)))
+    return 1;
+  // smallest subnormal result
+  if (test__divtf3(TF_C(0x1.0p-16382), TF_C(0x1p+112), UINT64_C(0x0),
+                   UINT64_C(0x1)))
+    return 1;
+
+  // any / any
+  if (test__divtf3(TF_C(0x1.a23b45362464523375893ab4cdefp+5),
+                   TF_C(0x1.eedcbaba3a94546558237654321fp-1),
+                   UINT64_C(0x4004b0b72924d407), UINT64_C(0x0717e84356c6eba2)))
+    return 1;
+  if (test__divtf3(TF_C(0x1.a2b34c56d745382f9abf2c3dfeffp-50),
+                   TF_C(0x1.ed2c3ba15935332532287654321fp-9),
+                   UINT64_C(0x3fd5b2af3f828c9b), UINT64_C(0x40e51f64cde8b1f2)))
+    return 15;
+  if (test__divtf3(TF_C(0x1.2345f6aaaa786555f42432abcdefp+456),
+                   TF_C(0x1.edacbba9874f765463544dd3621fp+6400),
+                   UINT64_C(0x28c62e15dc464466), UINT64_C(0xb5a07586348557ac)))
+    return 1;
+  if (test__divtf3(TF_C(0x1.2d3456f789ba6322bc665544edefp-234),
+                   TF_C(0x1.eddcdba39f3c8b7a36564354321fp-4455),
+                   UINT64_C(0x507b38442b539266), UINT64_C(0x22ce0f1d024e1252)))
+    return 1;
+  if (test__divtf3(TF_C(0x1.2345f6b77b7a8953365433abcdefp+234),
+                   TF_C(0x1.edcba987d6bb3aa467754354321fp-4055),
+                   UINT64_C(0x50bf2e02f0798d36), UINT64_C(0x5e6fcb6b60044078)))
+    return 1;
+  if (test__divtf3(TF_C(6.72420628622418701252535563464350521E-4932), TF_C(2.),
+                   UINT64_C(0x0001000000000000), UINT64_C(0)))
+    return 1;
 
 #else
-    printf("skipped\n");
+  printf("skipped\n");
 
 #endif
-    return 0;
+  return 0;
 }
diff --git a/compiler-rt/test/builtins/Unit/extendxftf2_test.c b/compiler-rt/test/builtins/Unit/extendxftf2_test.c
index f5211875438c732..7c3b0abdc392467 100644
--- a/compiler-rt/test/builtins/Unit/extendxftf2_test.c
+++ b/compiler-rt/test/builtins/Unit/extendxftf2_test.c
@@ -9,10 +9,10 @@
 
 #include "fp_test.h"
 
-COMPILER_RT_ABI __float128 __extendxftf2(long double a);
+COMPILER_RT_ABI tf_float __extendxftf2(long double a);
 
 int test__extendxftf2(long double a, uint64_t expectedHi, uint64_t expectedLo) {
-  __float128 x = __extendxftf2(a);
+  tf_float x = __extendxftf2(a);
   int ret = compareResultF128(x, expectedHi, expectedLo);
 
   if (ret) {
diff --git a/compiler-rt/test/builtins/Unit/floatditf_test.c b/compiler-rt/test/builtins/Unit/floatditf_test.c
index fe7a5fd86ae8423..29761d7c8eabc15 100644
--- a/compiler-rt/test/builtins/Unit/floatditf_test.c
+++ b/compiler-rt/test/builtins/Unit/floatditf_test.c
@@ -2,58 +2,66 @@
 // REQUIRES: librt_has_floatditf
 
 #include "int_lib.h"
-#include <math.h>
 #include <complex.h>
+#include <math.h>
 #include <stdio.h>
 
-#if __LDBL_MANT_DIG__ == 113
+// The testcase currently assumes IEEE TF format, once that has been
+// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
+// IBM 128 floats as well.
+#if defined(CRT_HAS_IEEE_TF)
 
-#include "fp_test.h"
+#  include "fp_test.h"
 
-// Returns: long integer converted to long double
+// Returns: long integer converted to tf_float
 
-COMPILER_RT_ABI long double __floatditf(di_int a);
+COMPILER_RT_ABI tf_float __floatditf(di_int a);
 
-int test__floatditf(di_int a, uint64_t expectedHi, uint64_t expectedLo)
-{
-    long double x = __floatditf(a);
-    int ret = compareResultF128(x, expectedHi, expectedLo);
+int test__floatditf(di_int a, uint64_t expectedHi, uint64_t expectedLo) {
+  tf_float x = __floatditf(a);
+  int ret = compareResultF128(x, expectedHi, expectedLo);
 
-    if (ret)
-        printf("error in __floatditf(%Ld) = %.20Lf, "
-               "expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
-    return ret;
+  if (ret)
+    printf("error in __floatditf(%Ld) = %.20Lf, "
+           "expected %.20Lf\n",
+           a, x, fromRep128(expectedHi, expectedLo));
+  return ret;
 }
 
 char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
 
 #endif
 
-int main()
-{
-#if __LDBL_MANT_DIG__ == 113
-    if (test__floatditf(0x7fffffffffffffff, UINT64_C(0x403dffffffffffff), UINT64_C(0xfffc000000000000)))
-        return 1;
-    if (test__floatditf(0x123456789abcdef1, UINT64_C(0x403b23456789abcd), UINT64_C(0xef10000000000000)))
-        return 1;
-    if (test__floatditf(0x2, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
-        return 1;
-    if (test__floatditf(0x1, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
-        return 1;
-    if (test__floatditf(0x0, UINT64_C(0x0), UINT64_C(0x0)))
-        return 1;
-    if (test__floatditf(0xffffffffffffffff, UINT64_C(0xbfff000000000000), UINT64_C(0x0)))
-        return 1;
-    if (test__floatditf(0xfffffffffffffffe, UINT64_C(0xc000000000000000), UINT64_C(0x0)))
-        return 1;
-    if (test__floatditf(-0x123456789abcdef1, UINT64_C(0xc03b23456789abcd), UINT64_C(0xef10000000000000)))
-        return 1;
-    if (test__floatditf(0x8000000000000000, UINT64_C(0xc03e000000000000), UINT64_C(0x0)))
-        return 1;
+int main() {
+#if defined(CRT_HAS_IEEE_TF)
+  if (test__floatditf(0x7fffffffffffffff, UINT64_C(0x403dffffffffffff),
+                      UINT64_C(0xfffc000000000000)))
+    return 1;
+  if (test__floatditf(0x123456789abcdef1, UINT64_C(0x403b23456789abcd),
+                      UINT64_C(0xef10000000000000)))
+    return 1;
+  if (test__floatditf(0x2, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
+    return 1;
+  if (test__floatditf(0x1, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
+    return 1;
+  if (test__floatditf(0x0, UINT64_C(0x0), UINT64_C(0x0)))
+    return 1;
+  if (test__floatditf(0xffffffffffffffff, UINT64_C(0xbfff000000000000),
+                      UINT64_C(0x0)))
+    return 1;
+  if (test__floatditf(0xfffffffffffffffe, UINT64_C(0xc000000000000000),
+                      UINT64_C(0x0)))
+    return 1;
+  if (test__floatditf(-0x123456789abcdef1, UINT64_C(0xc03b23456789abcd),
+                      UINT64_C(0xef10000000000000)))
+    return 1;
+  if (test__floatditf(0x8000000000000000, UINT64_C(0xc03e000000000000),
+                      UINT64_C(0x0)))
+    return 1;
 
 #else
-    printf("skipped\n");
+  printf("skipped\n");
 
 #endif
-    return 0;
+  return 0;
 }
diff --git a/compiler-rt/test/builtins/Unit/floattitf_test.c b/compiler-rt/test/builtins/Unit/floattitf_test.c
index abd3006135b38f7..33b434169f0614f 100644
--- a/compiler-rt/test/builtins/Unit/floattitf_test.c
+++ b/compiler-rt/test/builtins/Unit/floattitf_test.c
@@ -7,7 +7,10 @@
 #include <float.h>
 #include <stdio.h>
 
-#if defined(CRT_HAS_TF_MODE)
+// The testcase currently assumes IEEE TF format, once that has been
+// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
+// IBM 128 floats as well.
+#if defined(CRT_HAS_IEEE_TF)
 
 /* Returns: convert a ti_int to a fp_t, rounding toward even. */
 
@@ -36,10 +39,7 @@ char assumption_1[sizeof(ti_int) == 2 * sizeof(di_int)] = {0};
 char assumption_2[sizeof(ti_int) * CHAR_BIT == 128] = {0};
 char assumption_3[sizeof(fp_t) * CHAR_BIT == 128] = {0};
 
-#endif
-
 int main() {
-#if defined(CRT_HAS_TF_MODE)
   if (test__floattitf(0, 0.0))
     return 1;
 
@@ -215,8 +215,12 @@ int main() {
   if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC57FFLL),
                       TF_C(0x1.23456789ABCDEF0123456789ABC5p+124)))
     return 1;
+  return 0;
+}
+
 #else
+int main() {
   printf("skipped\n");
-#endif
   return 0;
 }
+#endif
diff --git a/compiler-rt/test/builtins/Unit/floatunditf_test.c b/compiler-rt/test/builtins/Unit/floatunditf_test.c
index 8da78da9760293a..98c2262546f204c 100644
--- a/compiler-rt/test/builtins/Unit/floatunditf_test.c
+++ b/compiler-rt/test/builtins/Unit/floatunditf_test.c
@@ -2,56 +2,63 @@
 // REQUIRES: librt_has_floatunditf
 
 #include "int_lib.h"
-#include <math.h>
 #include <complex.h>
+#include <math.h>
 #include <stdio.h>
 
-#if __LDBL_MANT_DIG__ == 113
+// The testcase currently assumes IEEE TF format, once that has been
+// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
+// IBM 128 floats as well.
+#if defined(CRT_HAS_IEEE_TF)
 
-#include "fp_test.h"
+#  include "fp_test.h"
 
 // Returns: long integer converted to long double
 
-COMPILER_RT_ABI long double __floatunditf(du_int a);
+COMPILER_RT_ABI tf_float __floatunditf(du_int a);
 
-int test__floatunditf(du_int a, uint64_t expectedHi, uint64_t expectedLo)
-{
-    long double x = __floatunditf(a);
-    int ret = compareResultF128(x, expectedHi, expectedLo);
+int test__floatunditf(du_int a, uint64_t expectedHi, uint64_t expectedLo) {
+  tf_float x = __floatunditf(a);
+  int ret = compareResultF128(x, expectedHi, expectedLo);
 
-    if (ret)
-        printf("error in __floatunditf(%Lu) = %.20Lf, "
-               "expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
-    return ret;
+  if (ret)
+    printf("error in __floatunditf(%Lu) = %.20Lf, "
+           "expected %.20Lf\n",
+           a, x, fromRep128(expectedHi, expectedLo));
+  return ret;
 }
 
 char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
 
 #endif
 
-int main()
-{
-#if __LDBL_MANT_DIG__ == 113
-    if (test__floatunditf(0xffffffffffffffffULL, UINT64_C(0x403effffffffffff), UINT64_C(0xfffe000000000000)))
-        return 1;
-    if (test__floatunditf(0xfffffffffffffffeULL, UINT64_C(0x403effffffffffff), UINT64_C(0xfffc000000000000)))
-        return 1;
-    if (test__floatunditf(0x8000000000000000ULL, UINT64_C(0x403e000000000000), UINT64_C(0x0)))
-        return 1;
-    if (test__floatunditf(0x7fffffffffffffffULL, UINT64_C(0x403dffffffffffff), UINT64_C(0xfffc000000000000)))
-        return 1;
-    if (test__floatunditf(0x123456789abcdef1ULL, UINT64_C(0x403b23456789abcd), UINT64_C(0xef10000000000000)))
-        return 1;
-    if (test__floatunditf(0x2ULL, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
-        return 1;
-    if (test__floatunditf(0x1ULL, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
-        return 1;
-    if (test__floatunditf(0x0ULL, UINT64_C(0x0), UINT64_C(0x0)))
-        return 1;
+int main() {
+#if defined(CRT_HAS_IEEE_TF)
+  if (test__floatunditf(0xffffffffffffffffULL, UINT64_C(0x403effffffffffff),
+                        UINT64_C(0xfffe000000000000)))
+    return 1;
+  if (test__floatunditf(0xfffffffffffffffeULL, UINT64_C(0x403effffffffffff),
+                        UINT64_C(0xfffc000000000000)))
+    return 1;
+  if (test__floatunditf(0x8000000000000000ULL, UINT64_C(0x403e000000000000),
+                        UINT64_C(0x0)))
+    return 1;
+  if (test__floatunditf(0x7fffffffffffffffULL, UINT64_C(0x403dffffffffffff),
+                        UINT64_C(0xfffc000000000000)))
+    return 1;
+  if (test__floatunditf(0x123456789abcdef1ULL, UINT64_C(0x403b23456789abcd),
+                        UINT64_C(0xef10000000000000)))
+    return 1;
+  if (test__floatunditf(0x2ULL, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
+    return 1;
+  if (test__floatunditf(0x1ULL, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
+    return 1;
+  if (test__floatunditf(0x0ULL, UINT64_C(0x0), UINT64_C(0x0)))
+    return 1;
 
 #else
-    printf("skipped\n");
+  printf("skipped\n");
 
 #endif
-    return 0;
+  return 0;
 }
diff --git a/compiler-rt/test/builtins/Unit/floatunsitf_test.c b/compiler-rt/test/builtins/Unit/floatunsitf_test.c
index b6b1ba045739900..44337cc81e7360e 100644
--- a/compiler-rt/test/builtins/Unit/floatunsitf_test.c
+++ b/compiler-rt/test/builtins/Unit/floatunsitf_test.c
@@ -4,43 +4,48 @@
 #include "int_lib.h"
 #include <stdio.h>
 
-#if __LDBL_MANT_DIG__ == 113
+// The testcase currently assumes IEEE TF format, once that has been
+// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
+// IBM 128 floats as well.
+#if defined(CRT_HAS_IEEE_TF)
 
-#include "fp_test.h"
+#  include "fp_test.h"
 
-COMPILER_RT_ABI long double __floatunsitf(su_int a);
+COMPILER_RT_ABI tf_float __floatunsitf(su_int a);
 
-int test__floatunsitf(su_int a, uint64_t expectedHi, uint64_t expectedLo)
-{
-    long double x = __floatunsitf(a);
-    int ret = compareResultF128(x, expectedHi, expectedLo);
+int test__floatunsitf(su_int a, uint64_t expectedHi, uint64_t expectedLo) {
+  tf_float x = __floatunsitf(a);
+  int ret = compareResultF128(x, expectedHi, expectedLo);
 
-    if (ret){
-        printf("error in test__floatunsitf(%u) = %.20Lf, "
-               "expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
-    }
-    return ret;
+  if (ret) {
+    printf("error in test__floatunsitf(%u) = %.20Lf, "
+           "expected %.20Lf\n",
+           a, x, fromRep128(expectedHi, expectedLo));
+  }
+  return ret;
 }
 
-char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
+char assumption_1[sizeof(tf_float) * CHAR_BIT == 128] = {0};
 
 #endif
 
-int main()
-{
-#if __LDBL_MANT_DIG__ == 113
-    if (test__floatunsitf(0x7fffffff, UINT64_C(0x401dfffffffc0000), UINT64_C(0x0)))
-        return 1;
-    if (test__floatunsitf(0, UINT64_C(0x0), UINT64_C(0x0)))
-        return 1;
-    if (test__floatunsitf(0xffffffff, UINT64_C(0x401efffffffe0000), UINT64_C(0x0)))
-        return 1;
-    if (test__floatunsitf(0x12345678, UINT64_C(0x401b234567800000), UINT64_C(0x0)))
-        return 1;
+int main() {
+#if defined(CRT_HAS_IEEE_TF)
+  if (test__floatunsitf(0x7fffffff, UINT64_C(0x401dfffffffc0000),
+                        UINT64_C(0x0)))
+    return 1;
+  if (test__floatunsitf(0, UINT64_C(0x0), UINT64_C(0x0)))
+    return 1;
+  if (test__floatunsitf(0xffffffff, UINT64_C(0x401efffffffe0000),
+                        UINT64_C(0x0)))
+    return 1;
+  if (test__floatunsitf(0x12345678, UINT64_C(0x401b234567800000),
+                        UINT64_C(0x0)))
+    return 1;
 
 #else
-    printf("skipped\n");
+  printf("skipped\n");
 
 #endif
-    return 0;
+  return 0;
 }
diff --git a/compiler-rt/test/builtins/Unit/floatuntitf_test.c b/compiler-rt/test/builtins/Unit/floatuntitf_test.c
index db25f2b0230cd14..bf152ce47a21036 100644
--- a/compiler-rt/test/builtins/Unit/floatuntitf_test.c
+++ b/compiler-rt/test/builtins/Unit/floatuntitf_test.c
@@ -7,11 +7,14 @@
 #include <float.h>
 #include <stdio.h>
 
-#if defined(CRT_HAS_TF_MODE)
+// The testcase currently assumes IEEE TF format, once that has been
+// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
+// IBM 128 floats as well.
+#if defined(CRT_HAS_IEEE_TF)
 
-/* Returns: convert a tu_int to a fp_t, rounding toward even. */
+/* Returns: convert a tu_int to a tf_float, rounding toward even. */
 
-/* Assumption: fp_t is a IEEE 128 bit floating point type
+/* Assumption: tf_float is a IEEE 128 bit floating point type
  *             tu_int is a 128 bit integral type
  */
 
@@ -19,10 +22,10 @@
  * mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
  */
 
-COMPILER_RT_ABI fp_t __floatuntitf(tu_int a);
+COMPILER_RT_ABI tf_float __floatuntitf(tu_int a);
 
-int test__floatuntitf(tu_int a, fp_t expected) {
-  fp_t x = __floatuntitf(a);
+int test__floatuntitf(tu_int a, tf_float expected) {
+  tf_float x = __floatuntitf(a);
   if (x != expected) {
     utwords at;
     at.all = a;
@@ -34,12 +37,12 @@ int test__floatuntitf(tu_int a, fp_t expected) {
 
 char assumption_1[sizeof(tu_int) == 2 * sizeof(du_int)] = {0};
 char assumption_2[sizeof(tu_int) * CHAR_BIT == 128] = {0};
-char assumption_3[sizeof(fp_t) * CHAR_BIT == 128] = {0};
+char assumption_3[sizeof(tf_float) * CHAR_BIT == 128] = {0};
 
 #endif
 
 int main() {
-#if defined(CRT_HAS_TF_MODE)
+#if defined(CRT_HAS_IEEE_TF)
   if (test__floatuntitf(0, 0.0))
     return 1;
 
diff --git a/compiler-rt/test/builtins/Unit/fp_test.h b/compiler-rt/test/builtins/Unit/fp_test.h
index f095ae0701d77e6..3577c79e300ffbd 100644
--- a/compiler-rt/test/builtins/Unit/fp_test.h
+++ b/compiler-rt/test/builtins/Unit/fp_test.h
@@ -9,18 +9,6 @@
 #define TYPE_FP16 uint16_t
 #endif
 
-// TODO: Switch to using fp_lib.h once QUAD_PRECISION is available on x86_64.
-#if __LDBL_MANT_DIG__ == 113 ||                                                \
-    ((__LDBL_MANT_DIG__ == 64) && defined(__x86_64__) &&                       \
-     (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)))
-#if __LDBL_MANT_DIG__ == 113
-#define TYPE_FP128 long double
-#else
-#define TYPE_FP128 __float128
-#endif
-#define TEST_COMPILER_RT_HAS_FLOAT128
-#endif
-
 enum EXPECTED_RESULT {
     LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0
 };
@@ -50,10 +38,10 @@ static inline double fromRep64(uint64_t x)
     return ret;
 }
 
-#ifdef TEST_COMPILER_RT_HAS_FLOAT128
-static inline TYPE_FP128 fromRep128(uint64_t hi, uint64_t lo) {
+#if defined(CRT_HAS_TF_MODE)
+static inline tf_float fromRep128(uint64_t hi, uint64_t lo) {
     __uint128_t x = ((__uint128_t)hi << 64) + lo;
-    TYPE_FP128 ret;
+    tf_float ret;
     memcpy(&ret, &x, 16);
     return ret;
 }
@@ -84,8 +72,8 @@ static inline uint64_t toRep64(double x)
     return ret;
 }
 
-#ifdef TEST_COMPILER_RT_HAS_FLOAT128
-static inline __uint128_t toRep128(TYPE_FP128 x) {
+#if defined(CRT_HAS_TF_MODE)
+static inline __uint128_t toRep128(tf_float x) {
     __uint128_t ret;
     memcpy(&ret, &x, 16);
     return ret;
@@ -146,11 +134,11 @@ static inline int compareResultD(double result,
     return 1;
 }
 
-#ifdef TEST_COMPILER_RT_HAS_FLOAT128
+#if defined(CRT_HAS_TF_MODE)
 // return 0 if equal
 // use two 64-bit integers instead of one 128-bit integer
 // because 128-bit integer constant can't be assigned directly
-static inline int compareResultF128(TYPE_FP128 result, uint64_t expectedHi,
+static inline int compareResultF128(tf_float result, uint64_t expectedHi,
                                     uint64_t expectedLo) {
     __uint128_t rep = toRep128(result);
     uint64_t hi = rep >> 64;
@@ -277,8 +265,8 @@ static inline long double makeInf80(void) {
 }
 #endif
 
-#ifdef TEST_COMPILER_RT_HAS_FLOAT128
-static inline TYPE_FP128 makeQNaN128(void) {
+#if defined(CRT_HAS_TF_MODE)
+static inline tf_float makeQNaN128(void) {
     return fromRep128(0x7fff800000000000UL, 0x0UL);
 }
 #endif
@@ -298,8 +286,8 @@ static inline double makeNaN64(uint64_t rand)
     return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
 }
 
-#ifdef TEST_COMPILER_RT_HAS_FLOAT128
-static inline TYPE_FP128 makeNaN128(uint64_t rand) {
+#if defined(CRT_HAS_TF_MODE)
+static inline tf_float makeNaN128(uint64_t rand) {
     return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
 }
 #endif
@@ -329,12 +317,12 @@ static inline double makeNegativeInf64(void)
     return fromRep64(0xfff0000000000000UL);
 }
 
-#ifdef TEST_COMPILER_RT_HAS_FLOAT128
-static inline TYPE_FP128 makeInf128(void) {
+#if defined(CRT_HAS_TF_MODE)
+static inline tf_float makeInf128(void) {
     return fromRep128(0x7fff000000000000UL, 0x0UL);
 }
 
-static inline TYPE_FP128 makeNegativeInf128(void) {
+static inline tf_float makeNegativeInf128(void) {
     return fromRep128(0xffff000000000000UL, 0x0UL);
 }
 #endif
diff --git a/compiler-rt/test/builtins/Unit/trunctfxf2_test.c b/compiler-rt/test/builtins/Unit/trunctfxf2_test.c
index 53024ef139624aa..76885e255e4c494 100644
--- a/compiler-rt/test/builtins/Unit/trunctfxf2_test.c
+++ b/compiler-rt/test/builtins/Unit/trunctfxf2_test.c
@@ -9,9 +9,9 @@
 
 #include "fp_test.h"
 
-COMPILER_RT_ABI long double __trunctfxf2(__float128 a);
+COMPILER_RT_ABI long double __trunctfxf2(tf_float a);
 
-int test__trunctfxf2(__float128 a, uint64_t expectedHi, uint64_t expectedLo) {
+int test__trunctfxf2(tf_float a, uint64_t expectedHi, uint64_t expectedLo) {
   long double x = __trunctfxf2(a);
   int ret = compareResultF80(x, expectedHi, expectedLo);
   ;
@@ -59,24 +59,24 @@ int main() {
     return 1;
 
   // Test rounding near halfway.
-  __float128 halfwayPlus =
+  tf_float halfwayPlus =
       fromRep128(UINT64_C(0x7ffa000000000000),
                  ((UINT64_C(1) << (112 - 63 - 1)) + UINT64_C(1)));
   if (test__trunctfxf2(halfwayPlus, UINT64_C(0x7ffa),
                        UINT64_C(0x8000000000000001)))
     return 1;
-  __float128 halfwayExactOdd = fromRep128(
+  tf_float halfwayExactOdd = fromRep128(
       UINT64_C(0x7ffa000000000000),
       ((UINT64_C(1) << (112 - 63)) + (UINT64_C(1) << (112 - 63 - 1))));
   if (test__trunctfxf2(halfwayExactOdd, UINT64_C(0x7ffa),
                        UINT64_C(0x8000000000000002)))
     return 1;
-  __float128 halfwayExactEven =
+  tf_float halfwayExactEven =
       fromRep128(UINT64_C(0x7ffa000000000000), (UINT64_C(1) << (112 - 63 - 1)));
   if (test__trunctfxf2(halfwayExactEven, UINT64_C(0x7ffa),
                        UINT64_C(0x8000000000000000)))
     return 1;
-  __float128 halfwayRoundingWillChangeExponent =
+  tf_float halfwayRoundingWillChangeExponent =
       fromRep128(UINT64_C(0x7ffaffffffffffff), UINT64_C(0xffff000000000001));
   if (test__trunctfxf2(halfwayRoundingWillChangeExponent, UINT64_C(0x7ffb),
                        UINT64_C(0x8000000000000000)))



More information about the llvm-commits mailing list