[compiler-rt] [builtins] Avoid using long double in generic sources (PR #69754)
Alexander Richardson via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 20 12:13:28 PDT 2023
https://github.com/arichardson created https://github.com/llvm/llvm-project/pull/69754
Use of long double can be error-prone since it could be one of 80-bit
extended precision float, IEEE 128-bit float, or IBM 128-bit float.
Instead use an explicit xf_float typedef for the remaining cases where
long double is being used in the implementation. This patch does not touch
the PPC specializations which still use long double.
Depends on #68132 (to be committed after that PR).
>From 3518654bd8df736eee931de59d0914ab56232cab Mon Sep 17 00:00:00 2001
From: Alex Richardson <alexrichardson at google.com>
Date: Thu, 19 Oct 2023 16:16:53 -0700
Subject: [PATCH 1/2] [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/extendxftf2.c | 9 +-
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_to_fp.h | 2 +-
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 | 9 +-
compiler-rt/test/builtins/Unit/addtf3_test.c | 154 ++---
.../builtins/Unit/compiler_rt_fmaxl_test.c | 13 +-
.../builtins/Unit/compiler_rt_logbl_test.c | 57 +-
.../builtins/Unit/compiler_rt_scalbnl_test.c | 68 +-
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 | 87 ++-
.../test/builtins/Unit/floatunditf_test.c | 73 +-
.../test/builtins/Unit/floatunsitf_test.c | 57 +-
.../test/builtins/Unit/floatuntitf_test.c | 89 +--
compiler-rt/test/builtins/Unit/fp_test.h | 42 +-
.../test/builtins/Unit/trunctfxf2_test.c | 12 +-
33 files changed, 1060 insertions(+), 954 deletions(-)
diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index cf2648233b0cf8f..a705486e2d3c842 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/extendxftf2.c b/compiler-rt/lib/builtins/extendxftf2.c
index 20911fe7cf2a000..6cb8a63122f2262 100644
--- a/compiler-rt/lib/builtins/extendxftf2.c
+++ b/compiler-rt/lib/builtins/extendxftf2.c
@@ -9,14 +9,15 @@
// Assumption: long double is a IEEE 80 bit floating point type padded to 128
// bits.
-// TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
-#if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__) && \
- (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_TF_MODE) && __LDBL_MANT_DIG__ == 64 && defined(__x86_64__)
#define SRC_80
#define DST_QUAD
#include "fp_extend_impl.inc"
-COMPILER_RT_ABI __float128 __extendxftf2(long double a) {
+COMPILER_RT_ABI tf_float __extendxftf2(long double a) {
return __extendXfYf2__(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_to_fp.h b/compiler-rt/lib/builtins/int_to_fp.h
index 1adce097d7a8568..6c87f7bdd792a5e 100644
--- a/compiler-rt/lib/builtins/int_to_fp.h
+++ b/compiler-rt/lib/builtins/int_to_fp.h
@@ -53,7 +53,7 @@ typedef uint64_t dst_rep_t;
static const int dstSigBits = 52;
#elif defined DST_QUAD
-typedef long double dst_t;
+typedef tf_float dst_t;
typedef __uint128_t dst_rep_t;
#define DST_REP_C (__uint128_t)
static const int dstSigBits = 112;
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..6a84477879f0f7c 100644
--- a/compiler-rt/lib/builtins/trunctfxf2.c
+++ b/compiler-rt/lib/builtins/trunctfxf2.c
@@ -9,15 +9,16 @@
// Assumption: long double is a IEEE 80 bit floating point type padded to 128
// bits.
-// TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
-#if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__) && \
- (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_TF_MODE) && __LDBL_MANT_DIG__ == 64 && defined(__x86_64__)
#define SRC_QUAD
#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..f49ce710b04432f 100644
--- a/compiler-rt/test/builtins/Unit/compiler_rt_logbl_test.c
+++ b/compiler-rt/test/builtins/Unit/compiler_rt_logbl_test.c
@@ -1,18 +1,18 @@
// RUN: %clang_builtins %s %librt -o %t && %run %t
#define QUAD_PRECISION
-#include <math.h>
-#include <stdio.h>
#include "fp_lib.h"
#include "int_lib.h"
+#include <math.h>
+#include <stdio.h>
#if defined(CRT_HAS_TF_MODE)
int test__compiler_rt_logbl(fp_t x) {
-#if defined(__ve__)
+# if defined(__ve__)
if (fpclassify(x) == FP_SUBNORMAL)
return 0;
-#endif
+# endif
fp_t crt_value = __compiler_rt_logbl(x);
fp_t libm_value = logbl(x);
// Compare the values, considering all NaNs equivalent, as the spec doesn't
@@ -24,49 +24,62 @@ int test__compiler_rt_logbl(fp_t x) {
x_t.all = toRep(x);
crt_value_t.all = toRep(crt_value);
libm_value_t.all = toRep(libm_value);
- printf(
- "error: in __compiler_rt_logbl([%llX %llX]) = [%llX %llX] != "
- "[%llX %llX]\n",
- x_t.s.high, x_t.s.low, crt_value_t.s.high, crt_value_t.s.low,
- libm_value_t.s.high, libm_value_t.s.low);
+ printf("error: in __compiler_rt_logbl([%llX %llX]) = [%llX %llX] != "
+ "[%llX %llX]\n",
+ x_t.s.high, x_t.s.low, crt_value_t.s.high, crt_value_t.s.low,
+ libm_value_t.s.high, libm_value_t.s.low);
return 1;
}
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) {
- if (test__compiler_rt_logbl(cases[i])) return 1;
+ for (unsigned i = 0; i < N; ++i) {
+ if (test__compiler_rt_logbl(cases[i]))
+ return 1;
}
// Test a moving 1 bit, especially to handle denormal values.
// Test the negation as well.
+ // 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 (otherwise we will see mismatches
+ // once we reach numbers that cannot be precisely represented in long double
+ // format).
+# if defined(CRT_LDBL_IEEE_F128)
rep_t x = signBit;
+ int i = 0;
while (x) {
- if (test__compiler_rt_logbl(fromRep(x))) return 1;
- if (test__compiler_rt_logbl(fromRep(signBit ^ x))) return 1;
+ if (test__compiler_rt_logbl(fromRep(x)))
+ return 1;
+ if (test__compiler_rt_logbl(fromRep(signBit ^ x)))
+ return 1;
x >>= 1;
+ printf("l1: %d\n", i++);
}
// Also try a couple moving ones
x = signBit | (signBit >> 1) | (signBit >> 2);
while (x) {
- if (test__compiler_rt_logbl(fromRep(x))) return 1;
- if (test__compiler_rt_logbl(fromRep(signBit ^ x))) return 1;
+ if (test__compiler_rt_logbl(fromRep(x)))
+ return 1;
+ if (test__compiler_rt_logbl(fromRep(signBit ^ x)))
+ return 1;
x >>= 1;
+ printf("l1: %d\n", i++);
}
-#else
- printf("skipped\n");
#endif
return 0;
}
+#else
+int main() {
+ printf("skipped\n");
+ 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..0d9bbdfd68e4a84 100644
--- a/compiler-rt/test/builtins/Unit/compiler_rt_scalbnl_test.c
+++ b/compiler-rt/test/builtins/Unit/compiler_rt_scalbnl_test.c
@@ -1,12 +1,12 @@
// RUN: %clang_builtins %s %librt -o %t && %run %t
#define QUAD_PRECISION
+#include "fp_lib.h"
#include <fenv.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
-#include "fp_lib.h"
#if defined(CRT_HAS_TF_MODE)
@@ -14,7 +14,7 @@ int test__compiler_rt_scalbnl(const char *mode, fp_t x, int y) {
#if defined(__ve__)
if (fpclassify(x) == FP_SUBNORMAL)
return 0;
-#endif
+# endif
fp_t crt_value = __compiler_rt_scalbnl(x, y);
fp_t libm_value = scalbnl(x, y);
// Consider +/-0 unequal, but disregard the sign/payload of NaN.
@@ -39,13 +39,34 @@ int test__compiler_rt_scalbnl(const char *mode, fp_t x, int y) {
}
fp_t cases[] = {
- -NAN, NAN, -INFINITY, INFINITY, -0.0, 0.0, -1, 1, -2, 2,
- LDBL_TRUE_MIN, LDBL_MIN, LDBL_MAX,
- -1.001, 1.001, -1.002, 1.002, 1.e-6, -1.e-6,
- 0x1.0p-16381L,
- 0x1.0p-16382L,
- 0x1.0p-16383L, // subnormal
- 0x1.0p-16384L, // subnormal
+ -NAN,
+ NAN,
+ -INFINITY,
+ INFINITY,
+ -0.0,
+ 0.0,
+ -1,
+ 1,
+ -2,
+ 2,
+// 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_LDBL_IEEE_F128)
+ LDBL_TRUE_MIN,
+# endif
+ LDBL_MIN,
+ LDBL_MAX,
+ -1.001,
+ 1.001,
+ -1.002,
+ 1.002,
+ 1.e-6,
+ -1.e-6,
+ TF_C(0x1.0p-16381),
+ TF_C(0x1.0p-16382),
+ TF_C(0x1.0p-16383), // subnormal
+ TF_C(0x1.0p-16384), // subnormal
};
int iterate_cases(const char *mode) {
@@ -54,28 +75,35 @@ int iterate_cases(const char *mode) {
for (i = 0; i < N; ++i) {
int j;
for (j = -5; j <= 5; ++j) {
- if (test__compiler_rt_scalbnl(mode, cases[i], j)) return 1;
+ printf("%d, %d\n", i, j);
+ if (test__compiler_rt_scalbnl(mode, cases[i], j))
+ return 1;
}
- if (test__compiler_rt_scalbnl(mode, cases[i], -100000)) return 1;
- if (test__compiler_rt_scalbnl(mode, cases[i], 100000)) return 1;
- if (test__compiler_rt_scalbnl(mode, cases[i], INT_MIN)) return 1;
- if (test__compiler_rt_scalbnl(mode, cases[i], INT_MAX)) return 1;
+ if (test__compiler_rt_scalbnl(mode, cases[i], -100000))
+ return 1;
+ if (test__compiler_rt_scalbnl(mode, cases[i], 100000))
+ return 1;
+ if (test__compiler_rt_scalbnl(mode, cases[i], INT_MIN))
+ return 1;
+ if (test__compiler_rt_scalbnl(mode, cases[i], INT_MAX))
+ return 1;
}
return 0;
}
-#endif
-
int main() {
-#if defined(CRT_HAS_TF_MODE)
- if (iterate_cases("default")) return 1;
+ 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..28cf3f4ff58d740 100644
--- a/compiler-rt/test/builtins/Unit/floattitf_test.c
+++ b/compiler-rt/test/builtins/Unit/floattitf_test.c
@@ -7,7 +7,12 @@
#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)
+
+# include "fp_test.h"
/* Returns: convert a ti_int to a fp_t, rounding toward even. */
@@ -21,93 +26,97 @@
COMPILER_RT_ABI fp_t __floattitf(ti_int a);
-int test__floattitf(ti_int a, fp_t expected) {
+int _test__floattitf(int line, ti_int a, fp_t expected) {
fp_t x = __floattitf(a);
if (x != expected) {
twords at;
at.all = a;
- printf("error in __floattitf(0x%.16llX%.16llX) = %LA, expected %LA\n",
- at.s.high, at.s.low, x, expected);
+ __uint128_t expected_rep = toRep128(expected);
+ __uint128_t res_rep = toRep128(x);
+ printf("%s:%d: error in __floattitf(0x%.16llX%.16llX) = "
+ "0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
+ __FILE__, line, at.s.high, at.s.low, (uint64_t)(res_rep >> 64),
+ (uint64_t)res_rep, (uint64_t)(expected_rep >> 64),
+ (uint64_t)expected_rep);
}
return x != expected;
}
+# define test__floattitf(a, e) _test__floattitf(__LINE__, a, e)
+
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))
+ if (test__floattitf(0, TF_C(0.0)))
return 1;
- if (test__floattitf(1, 1.0))
+ if (test__floattitf(1, TF_C(1.0)))
return 1;
- if (test__floattitf(2, 2.0))
+ if (test__floattitf(2, TF_C(2.0)))
return 1;
- if (test__floattitf(20, 20.0))
+ if (test__floattitf(20, TF_C(20.0)))
return 1;
- if (test__floattitf(-1, -1.0))
+ if (test__floattitf(-1, -TF_C(1.0)))
return 1;
- if (test__floattitf(-2, -2.0))
+ if (test__floattitf(-2, -TF_C(2.0)))
return 1;
- if (test__floattitf(-20, -20.0))
+ if (test__floattitf(-20, -TF_C(20.0)))
return 1;
- if (test__floattitf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62))
+ if (test__floattitf(0x7FFFFF8000000000LL, TF_C(0x1.FFFFFEp+62)))
return 1;
- if (test__floattitf(0x7FFFFFFFFFFFF800LL, 0x1.FFFFFFFFFFFFEp+62))
+ if (test__floattitf(0x7FFFFFFFFFFFF800LL, TF_C(0x1.FFFFFFFFFFFFEp+62)))
return 1;
- if (test__floattitf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62))
+ if (test__floattitf(0x7FFFFF0000000000LL, TF_C(0x1.FFFFFCp+62)))
return 1;
- if (test__floattitf(0x7FFFFFFFFFFFF000LL, 0x1.FFFFFFFFFFFFCp+62))
+ if (test__floattitf(0x7FFFFFFFFFFFF000LL, TF_C(0x1.FFFFFFFFFFFFCp+62)))
return 1;
- if (test__floattitf(make_ti(0x8000008000000000LL, 0), -0x1.FFFFFEp+126))
+ if (test__floattitf(make_ti(0x8000008000000000LL, 0), -TF_C(0x1.FFFFFEp+126)))
return 1;
if (test__floattitf(make_ti(0x8000000000000800LL, 0),
- -0x1.FFFFFFFFFFFFEp+126))
+ -TF_C(0x1.FFFFFFFFFFFFEp+126)))
return 1;
- if (test__floattitf(make_ti(0x8000010000000000LL, 0), -0x1.FFFFFCp+126))
+ if (test__floattitf(make_ti(0x8000010000000000LL, 0), -TF_C(0x1.FFFFFCp+126)))
return 1;
if (test__floattitf(make_ti(0x8000000000001000LL, 0),
- -0x1.FFFFFFFFFFFFCp+126))
+ -TF_C(0x1.FFFFFFFFFFFFCp+126)))
return 1;
- if (test__floattitf(make_ti(0x8000000000000000LL, 0), -0x1.000000p+127))
+ if (test__floattitf(make_ti(0x8000000000000000LL, 0), -TF_C(0x1.000000p+127)))
return 1;
if (test__floattitf(make_ti(0x8000000000000001LL, 0),
-TF_C(0x1.FFFFFFFFFFFFFFFCp+126)))
return 1;
- if (test__floattitf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50))
+ if (test__floattitf(0x0007FB72E8000000LL, TF_C(0x1.FEDCBAp+50)))
return 1;
- if (test__floattitf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50))
+ if (test__floattitf(0x0007FB72EA000000LL, TF_C(0x1.FEDCBA8p+50)))
return 1;
- if (test__floattitf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50))
+ if (test__floattitf(0x0007FB72EB000000LL, TF_C(0x1.FEDCBACp+50)))
return 1;
- if (test__floattitf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50))
+ if (test__floattitf(0x0007FB72EBFFFFFFLL, TF_C(0x1.FEDCBAFFFFFFCp+50)))
return 1;
- if (test__floattitf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50))
+ if (test__floattitf(0x0007FB72EC000000LL, TF_C(0x1.FEDCBBp+50)))
return 1;
- if (test__floattitf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50))
+ if (test__floattitf(0x0007FB72E8000001LL, TF_C(0x1.FEDCBA0000004p+50)))
return 1;
- if (test__floattitf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50))
+ if (test__floattitf(0x0007FB72E6000000LL, TF_C(0x1.FEDCB98p+50)))
return 1;
- if (test__floattitf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50))
+ if (test__floattitf(0x0007FB72E7000000LL, TF_C(0x1.FEDCB9Cp+50)))
return 1;
- if (test__floattitf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50))
+ if (test__floattitf(0x0007FB72E7FFFFFFLL, TF_C(0x1.FEDCB9FFFFFFCp+50)))
return 1;
- if (test__floattitf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50))
+ if (test__floattitf(0x0007FB72E4000001LL, TF_C(0x1.FEDCB90000004p+50)))
return 1;
- if (test__floattitf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50))
+ if (test__floattitf(0x0007FB72E4000000LL, TF_C(0x1.FEDCB9p+50)))
return 1;
- if (test__floattitf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57))
+ if (test__floattitf(0x023479FD0E092DC0LL, TF_C(0x1.1A3CFE870496Ep+57)))
return 1;
if (test__floattitf(0x023479FD0E092DA1LL, TF_C(0x1.1A3CFE870496D08p+57)))
return 1;
@@ -135,7 +144,7 @@ int main() {
return 1;
if (test__floattitf(0x023479FD0E092DDFLL, TF_C(0x1.1A3CFE870496EF8p+57)))
return 1;
- if (test__floattitf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57))
+ if (test__floattitf(0x023479FD0E092DE0LL, TF_C(0x1.1A3CFE870496Fp+57)))
return 1;
if (test__floattitf(make_ti(0x023479FD0E092DC0LL, 0),
@@ -215,8 +224,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..727d6477bba1e45 100644
--- a/compiler-rt/test/builtins/Unit/floatuntitf_test.c
+++ b/compiler-rt/test/builtins/Unit/floatuntitf_test.c
@@ -7,11 +7,16 @@
#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. */
+# include "fp_test.h"
-/* Assumption: fp_t is a IEEE 128 bit floating point type
+/* Returns: convert a tu_int to a tf_float, rounding toward even. */
+
+/* Assumption: tf_float is a IEEE 128 bit floating point type
* tu_int is a 128 bit integral type
*/
@@ -19,92 +24,98 @@
* 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(int line, tu_int a, tf_float expected) {
+ tf_float x = __floatuntitf(a);
if (x != expected) {
utwords at;
at.all = a;
- printf("error in __floatuntitf(0x%.16llX%.16llX) = %LA, expected %LA\n",
- at.s.high, at.s.low, x, expected);
+ __uint128_t expected_rep = toRep128(expected);
+ __uint128_t res_rep = toRep128(x);
+ printf("%s:%d: error in __floatuntitf(0x%.16llX%.16llX) = "
+ "0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
+ __FILE__, line, at.s.high, at.s.low, (uint64_t)(res_rep >> 64),
+ (uint64_t)res_rep, (uint64_t)(expected_rep >> 64),
+ (uint64_t)expected_rep);
}
return x != expected;
}
+# define test__floatuntitf(a, e) _test__floatuntitf(__LINE__, a, e)
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 (test__floatuntitf(0, 0.0))
+#if defined(CRT_HAS_IEEE_TF)
+ if (test__floatuntitf(0, TF_C(0.0)))
return 1;
- if (test__floatuntitf(1, 1.0))
+ if (test__floatuntitf(1, TF_C(1.0)))
return 1;
- if (test__floatuntitf(2, 2.0))
+ if (test__floatuntitf(2, TF_C(2.0)))
return 1;
- if (test__floatuntitf(20, 20.0))
+ if (test__floatuntitf(20, TF_C(20.0)))
return 1;
- if (test__floatuntitf(0x7FFFFF8000000000ULL, 0x1.FFFFFEp+62))
+ if (test__floatuntitf(0x7FFFFF8000000000ULL, TF_C(0x1.FFFFFEp+62)))
return 1;
- if (test__floatuntitf(0x7FFFFFFFFFFFF800ULL, 0x1.FFFFFFFFFFFFEp+62))
+ if (test__floatuntitf(0x7FFFFFFFFFFFF800ULL, TF_C(0x1.FFFFFFFFFFFFEp+62)))
return 1;
- if (test__floatuntitf(0x7FFFFF0000000000ULL, 0x1.FFFFFCp+62))
+ if (test__floatuntitf(0x7FFFFF0000000000ULL, TF_C(0x1.FFFFFCp+62)))
return 1;
- if (test__floatuntitf(0x7FFFFFFFFFFFF000ULL, 0x1.FFFFFFFFFFFFCp+62))
+ if (test__floatuntitf(0x7FFFFFFFFFFFF000ULL, TF_C(0x1.FFFFFFFFFFFFCp+62)))
return 1;
- if (test__floatuntitf(0x7FFFFFFFFFFFFFFFULL, 0xF.FFFFFFFFFFFFFFEp+59L))
+ if (test__floatuntitf(0x7FFFFFFFFFFFFFFFULL, TF_C(0xF.FFFFFFFFFFFFFFEp+59)))
return 1;
- if (test__floatuntitf(0xFFFFFFFFFFFFFFFEULL, 0xF.FFFFFFFFFFFFFFEp+60L))
+ if (test__floatuntitf(0xFFFFFFFFFFFFFFFEULL, TF_C(0xF.FFFFFFFFFFFFFFEp+60)))
return 1;
- if (test__floatuntitf(0xFFFFFFFFFFFFFFFFULL, 0xF.FFFFFFFFFFFFFFFp+60L))
+ if (test__floatuntitf(0xFFFFFFFFFFFFFFFFULL, TF_C(0xF.FFFFFFFFFFFFFFFp+60)))
return 1;
- if (test__floatuntitf(0x8000008000000000ULL, 0x8.000008p+60))
+ if (test__floatuntitf(0x8000008000000000ULL, TF_C(0x8.000008p+60)))
return 1;
- if (test__floatuntitf(0x8000000000000800ULL, 0x8.0000000000008p+60))
+ if (test__floatuntitf(0x8000000000000800ULL, TF_C(0x8.0000000000008p+60)))
return 1;
- if (test__floatuntitf(0x8000010000000000ULL, 0x8.00001p+60))
+ if (test__floatuntitf(0x8000010000000000ULL, TF_C(0x8.00001p+60)))
return 1;
- if (test__floatuntitf(0x8000000000001000ULL, 0x8.000000000001p+60))
+ if (test__floatuntitf(0x8000000000001000ULL, TF_C(0x8.000000000001p+60)))
return 1;
- if (test__floatuntitf(0x8000000000000000ULL, 0x8p+60))
+ if (test__floatuntitf(0x8000000000000000ULL, TF_C(0x8p+60)))
return 1;
if (test__floatuntitf(0x8000000000000001ULL, TF_C(0x8.000000000000001p+60)))
return 1;
- if (test__floatuntitf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50))
+ if (test__floatuntitf(0x0007FB72E8000000LL, TF_C(0x1.FEDCBAp+50)))
return 1;
- if (test__floatuntitf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50))
+ if (test__floatuntitf(0x0007FB72EA000000LL, TF_C(0x1.FEDCBA8p+50)))
return 1;
- if (test__floatuntitf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50))
+ if (test__floatuntitf(0x0007FB72EB000000LL, TF_C(0x1.FEDCBACp+50)))
return 1;
- if (test__floatuntitf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50))
+ if (test__floatuntitf(0x0007FB72EBFFFFFFLL, TF_C(0x1.FEDCBAFFFFFFCp+50)))
return 1;
- if (test__floatuntitf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50))
+ if (test__floatuntitf(0x0007FB72EC000000LL, TF_C(0x1.FEDCBBp+50)))
return 1;
- if (test__floatuntitf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50))
+ if (test__floatuntitf(0x0007FB72E8000001LL, TF_C(0x1.FEDCBA0000004p+50)))
return 1;
- if (test__floatuntitf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50))
+ if (test__floatuntitf(0x0007FB72E6000000LL, TF_C(0x1.FEDCB98p+50)))
return 1;
- if (test__floatuntitf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50))
+ if (test__floatuntitf(0x0007FB72E7000000LL, TF_C(0x1.FEDCB9Cp+50)))
return 1;
- if (test__floatuntitf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50))
+ if (test__floatuntitf(0x0007FB72E7FFFFFFLL, TF_C(0x1.FEDCB9FFFFFFCp+50)))
return 1;
- if (test__floatuntitf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50))
+ if (test__floatuntitf(0x0007FB72E4000001LL, TF_C(0x1.FEDCB90000004p+50)))
return 1;
- if (test__floatuntitf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50))
+ if (test__floatuntitf(0x0007FB72E4000000LL, TF_C(0x1.FEDCB9p+50)))
return 1;
- if (test__floatuntitf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57))
+ if (test__floatuntitf(0x023479FD0E092DC0LL, TF_C(0x1.1A3CFE870496Ep+57)))
return 1;
if (test__floatuntitf(0x023479FD0E092DA1LL, TF_C(0x1.1A3CFE870496D08p+57)))
return 1;
@@ -132,7 +143,7 @@ int main() {
return 1;
if (test__floatuntitf(0x023479FD0E092DDFLL, TF_C(0x1.1A3CFE870496EF8p+57)))
return 1;
- if (test__floatuntitf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57))
+ if (test__floatuntitf(0x023479FD0E092DE0LL, TF_C(0x1.1A3CFE870496Fp+57)))
return 1;
if (test__floatuntitf(make_ti(0x023479FD0E092DC0LL, 0),
diff --git a/compiler-rt/test/builtins/Unit/fp_test.h b/compiler-rt/test/builtins/Unit/fp_test.h
index f095ae0701d77e6..4eb54b7425c107b 100644
--- a/compiler-rt/test/builtins/Unit/fp_test.h
+++ b/compiler-rt/test/builtins/Unit/fp_test.h
@@ -3,24 +3,14 @@
#include <string.h>
#include <stdint.h>
+#include "int_types.h"
+
#ifdef COMPILER_RT_HAS_FLOAT16
#define TYPE_FP16 _Float16
#else
#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 +40,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 +74,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 +136,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 +267,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 +288,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 +319,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)))
>From 6298a09fbd99ed69ad53e0d766cbe4d971a9642d 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 2/2] [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