[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