[libc-commits] [libc] 988e509 - [libc] Fix FreeBSD build for 53-bit-rounded fp80s (#216332)
via libc-commits
libc-commits at lists.llvm.org
Mon Aug 17 02:22:04 PDT 2026
Author: Lewis Crawford
Date: 2026-08-17T10:21:59+01:00
New Revision: 988e509161d498930869e639698d948827aeadbd
URL: https://github.com/llvm/llvm-project/commit/988e509161d498930869e639698d948827aeadbd
DIFF: https://github.com/llvm/llvm-project/commit/988e509161d498930869e639698d948827aeadbd.diff
LOG: [libc] Fix FreeBSD build for 53-bit-rounded fp80s (#216332)
Fix build issues on FreeBSD, which reports `LDBL_MANT_DIG == 53` for
`long double` on some targets despite using fp80 as the underlying type.
This is because it stores the value as an fp80, but configures the FPU
to round the mantissa to 53-bits. However, this causes some parts of
libc to misidentify the fp80 as an fp64 since both use a 53-bit
mantissa. This led to build issues on FreeBSD when trying to bitcast the
12-byte `FPBits<long double>` to an 8-byte fp64 value.
This is fixed by checking both the mantissa size and the exponent range
when determining the correct format for `long double`. Also, move the
check for this to a single place in `types.h`, rather than re-checking
the `LDBL_MANT_DIG` and `LDBL_MAX_EXP` values in `FPBits.h`.
Added:
Modified:
libc/src/__support/FPUtil/FPBits.h
libc/src/__support/macros/properties/types.h
Removed:
################################################################################
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 58222f1a7ae15..0a7aee7ae232e 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -794,14 +794,15 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
else if constexpr (cpp::is_same_v<UnqualT, double> && DBL_MANT_DIG == 53)
return FPType::IEEE754_Binary64;
else if constexpr (cpp::is_same_v<UnqualT, long double>) {
- if constexpr (LDBL_MANT_DIG == 53)
- return FPType::IEEE754_Binary64;
- else if constexpr (LDBL_MANT_DIG == 64)
- return FPType::X86_Binary80;
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+ return FPType::IEEE754_Binary64;
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ return FPType::X86_Binary80;
+#else
// TODO: properly treat double-double type.
- // else if constexpr (LDBL_MANT_DIG == 113)
- else
- return FPType::IEEE754_Binary128;
+ // #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
+ return FPType::IEEE754_Binary128;
+#endif
}
#if defined(LIBC_TYPES_HAS_FLOAT16)
else if constexpr (cpp::is_same_v<UnqualT, float16>)
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 083b05164ae64..7126cb018167c 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -10,7 +10,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
-#include "hdr/float_macros.h" // LDBL_MANT_DIG
+#include "hdr/float_macros.h" // LDBL_MANT_DIG, LDBL_MAX_EXP
#include "hdr/stdint_proxy.h" // UINT64_MAX, __SIZEOF_INT128__
#include "include/llvm-libc-macros/float16-macros.h" // LIBC_TYPES_HAS_FLOAT16
#include "include/llvm-libc-types/float128.h" // float128
@@ -21,9 +21,16 @@
#include "src/__support/macros/properties/os.h"
// 'long double' properties.
-#if (LDBL_MANT_DIG == 53)
+//
+// Note: we cannot distinguish between f64 and f80 by just checking for a 53-bit
+// mantissa. On FreeBSD, `long double` is an fp80, but the FPU rounds the
+// mantissa to 53 bits. On GCC this is TARGET_96_ROUND_53_LONG_DOUBLE, which
+// reports LDBL_MANT_DIG == 53. As such, we must also check the exponent's range
+// to distinguish between f64 and 53-bit rounded f80 for `long double`.
+#if (LDBL_MANT_DIG == 53) && (LDBL_MAX_EXP == 1024)
#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
-#elif (LDBL_MANT_DIG == 64)
+#elif (LDBL_MANT_DIG == 64) || \
+ ((LDBL_MANT_DIG == 53) && (LDBL_MAX_EXP == 16384))
#define LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#elif (LDBL_MANT_DIG == 113)
#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128
More information about the libc-commits
mailing list