[libc-commits] [libc] [libc][math][C23] add software float16 support (PR #184283)

via libc-commits libc-commits at lists.llvm.org
Sat Aug 1 09:22:19 PDT 2026


https://github.com/AnonMiraj updated https://github.com/llvm/llvm-project/pull/184283

>From 353115fbd88922ee2623da5033ffc9779f4fca59 Mon Sep 17 00:00:00 2001
From: Anonmiraj <ezzibrahimx at gmail.com>
Date: Tue, 3 Mar 2026 02:42:07 +0200
Subject: [PATCH] [libc][math][C23] add software float16 support

---
 libc/config/linux/arm/entrypoints.txt         |   5 +
 .../include/llvm-libc-macros/float16-macros.h |  13 +-
 libc/src/__support/FPUtil/BasicOperations.h   |   4 +
 libc/src/__support/FPUtil/CMakeLists.txt      |  18 +++
 libc/src/__support/FPUtil/Float16.h           | 127 ++++++++++++++++++
 libc/src/__support/macros/properties/types.h  |  12 ++
 libc/src/__support/math/CMakeLists.txt        |   1 +
 libc/src/__support/math/fabsf16.h             |   4 +-
 libc/src/math/generic/fabsf16.cpp             |   1 -
 libc/test/src/math/exhaustive/CMakeLists.txt  |  17 +++
 .../src/math/exhaustive/exhaustive_test.h     |   1 +
 .../test/src/math/exhaustive/float16_test.cpp |  67 +++++++++
 libc/test/src/math/smoke/CMakeLists.txt       |   1 +
 libc/test/src/math/smoke/fabsf16_test.cpp     |   2 +-
 libc/utils/MPFRWrapper/CMakeLists.txt         |   2 +
 libc/utils/MPFRWrapper/MPCommon.cpp           |   7 +-
 libc/utils/MPFRWrapper/MPFRUtils.cpp          |   1 +
 17 files changed, 276 insertions(+), 7 deletions(-)
 create mode 100644 libc/src/__support/FPUtil/Float16.h
 create mode 100644 libc/test/src/math/exhaustive/float16_test.cpp

diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 1986d6a5347dc..608b50843b94a 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -506,6 +506,11 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.ufromfpxl
 )
 
+list(APPEND TARGET_LIBM_ENTRYPOINTS
+  # float16 entrypoints
+  libc.src.math.fabsf16
+)
+
 list(APPEND TARGET_LIBM_ENTRYPOINTS
   # bfloat16 entrypoints
   libc.src.math.atanbf16
diff --git a/libc/include/llvm-libc-macros/float16-macros.h b/libc/include/llvm-libc-macros/float16-macros.h
index 528c7f016f873..0b40a1b85636c 100644
--- a/libc/include/llvm-libc-macros/float16-macros.h
+++ b/libc/include/llvm-libc-macros/float16-macros.h
@@ -11,11 +11,18 @@
 
 #include "../llvm-libc-types/float128.h"
 
-#if defined(__FLT16_MANT_DIG__) &&                                             \
+#if defined(__arm__) && defined(_M_ARM)
+#define LIBC_USE_SOFT_FLOAT16
+#endif
+
+#ifdef LIBC_USE_SOFT_FLOAT16
+#define LIBC_TYPES_HAS_FLOAT16
+#endif
+
+#if !defined(LIBC_TYPES_HAS_FLOAT16) && defined(__FLT16_MANT_DIG__) &&         \
     (!defined(__GNUC__) || __GNUC__ >= 13 ||                                   \
      (defined(__clang__) && __clang_major__ >= 12)) &&                         \
-    !defined(__arm__) && !defined(_M_ARM) && !defined(__riscv) &&              \
-    !defined(_WIN32)
+    !defined(__riscv) && !defined(_WIN32)
 #define LIBC_TYPES_HAS_FLOAT16
 
 // TODO: This would no longer be required if HdrGen let us guard function
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 5b81b921296a0..747d089f3da73 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -53,6 +53,7 @@ max(T x, T y) {
 }
 
 #ifdef LIBC_TYPES_HAS_FLOAT16
+#if !defined(LIBC_USE_SOFT_FLOAT16)
 #if defined(__LIBC_USE_BUILTIN_FMAXF16_FMINF16)
 template <> LIBC_INLINE constexpr float16 max(float16 x, float16 y) {
   if (cpp::is_constant_evaluated())
@@ -69,6 +70,7 @@ template <> LIBC_INLINE constexpr float16 max(float16 x, float16 y) {
   return ((xi > yi) != (xi < 0 && yi < 0)) ? x : y;
 }
 #endif
+#endif // !LIBC_USE_SOFT_FLOAT16
 #endif // LIBC_TYPES_HAS_FLOAT16
 
 #if defined(__LIBC_USE_BUILTIN_FMAX_FMIN) && !defined(LIBC_TARGET_ARCH_IS_X86)
@@ -106,6 +108,7 @@ min(T x, T y) {
 }
 
 #ifdef LIBC_TYPES_HAS_FLOAT16
+#if !defined(LIBC_USE_SOFT_FLOAT16)
 #if defined(__LIBC_USE_BUILTIN_FMAXF16_FMINF16)
 template <> LIBC_INLINE constexpr float16 min(float16 x, float16 y) {
   if (cpp::is_constant_evaluated())
@@ -122,6 +125,7 @@ template <> LIBC_INLINE constexpr float16 min(float16 x, float16 y) {
   return ((xi < yi) != (xi < 0 && yi < 0)) ? x : y;
 }
 #endif
+#endif // !LIBC_USE_SOFT_FLOAT16
 #endif // LIBC_TYPES_HAS_FLOAT16
 
 #if defined(__LIBC_USE_BUILTIN_FMAX_FMIN) && !defined(LIBC_TARGET_ARCH_IS_X86)
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 4673ef794c80b..2f86adc9b745e 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -43,6 +43,24 @@ add_header_library(
     libc.src.__support.uint128
 )
 
+add_header_library(
+  Float16
+  HDRS
+    Float16.h
+  DEPENDS
+    .cast
+    .comparison_operations
+    .dyadic_float
+    libc.hdr.stdint_proxy
+    libc.src.__support.CPP.bit
+    libc.src.__support.CPP.type_traits
+    libc.src.__support.FPUtil.generic.add_sub
+    libc.src.__support.FPUtil.generic.div
+    libc.src.__support.FPUtil.generic.mul
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
 add_header_library(
   fpbits_str
   HDRS
diff --git a/libc/src/__support/FPUtil/Float16.h b/libc/src/__support/FPUtil/Float16.h
new file mode 100644
index 0000000000000..5387e6a7c1c7a
--- /dev/null
+++ b/libc/src/__support/FPUtil/Float16.h
@@ -0,0 +1,127 @@
+//===-- Definition of float16 data type. ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT16_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT16_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_USE_SOFT_FLOAT16
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/comparison_operations.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/FPUtil/generic/div.h"
+#include "src/__support/FPUtil/generic/mul.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+
+struct Float16 {
+  uint16_t bits;
+
+  LIBC_INLINE Float16() = default;
+
+  template <typename T>
+  LIBC_INLINE constexpr explicit Float16(T value)
+      : bits(static_cast<uint16_t>(0U)) {
+    if constexpr (cpp::is_floating_point_v<T>) {
+      bits = fputil::cast<Float16>(value).bits;
+    } else if constexpr (cpp::is_integral_v<T>) {
+      Sign sign = Sign::POS;
+
+      if constexpr (cpp::is_signed_v<T>) {
+        if (value < 0) {
+          sign = Sign::NEG;
+          value = -value;
+        }
+      }
+
+      fputil::DyadicFloat<cpp::numeric_limits<cpp::make_unsigned_t<T>>::digits>
+          xd(sign, 0, value);
+      bits = xd.template as<Float16, /*ShouldSignalExceptions=*/true>().bits;
+
+    } else if constexpr (cpp::is_convertible_v<T, Float16>) {
+      bits = value.operator Float16().bits;
+    }
+  }
+
+  template <cpp::enable_if_t<fputil::get_fp_type<float>() ==
+                                 fputil::FPType::IEEE754_Binary32,
+                             int> = 0>
+  LIBC_INLINE constexpr operator float() const {
+    return fputil::cast<float>(*this);
+  }
+
+  template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
+  LIBC_INLINE constexpr explicit operator T() const {
+    return static_cast<T>(static_cast<float>(*this));
+  }
+
+  LIBC_INLINE bool operator==(Float16 other) const {
+    return fputil::equals(*this, other);
+  }
+
+  LIBC_INLINE bool operator!=(Float16 other) const {
+    return !fputil::equals(*this, other);
+  }
+
+  LIBC_INLINE bool operator<(Float16 other) const {
+    return fputil::less_than(*this, other);
+  }
+
+  LIBC_INLINE bool operator<=(Float16 other) const {
+    return fputil::less_than_or_equals(*this, other);
+  }
+
+  LIBC_INLINE bool operator>(Float16 other) const {
+    return fputil::greater_than(*this, other);
+  }
+
+  LIBC_INLINE bool operator>=(Float16 other) const {
+    return fputil::greater_than_or_equals(*this, other);
+  }
+
+  LIBC_INLINE constexpr Float16 operator-() const {
+    fputil::FPBits<float16> result(*this);
+    result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS);
+    return result.get_val();
+  }
+
+  LIBC_INLINE Float16 operator+(Float16 other) const {
+    return fputil::generic::add<Float16>(*this, other);
+  }
+
+  LIBC_INLINE Float16 operator-(Float16 other) const {
+    return fputil::generic::sub<Float16>(*this, other);
+  }
+
+  LIBC_INLINE Float16 operator*(Float16 other) const {
+    return fputil::generic::mul<float16>(*this, other);
+  }
+
+  LIBC_INLINE Float16 operator/(Float16 other) const {
+    return fputil::generic::div<float16>(*this, other);
+  }
+
+  LIBC_INLINE Float16 &operator*=(const Float16 &other) {
+    *this = *this * other;
+    return *this;
+  }
+}; // struct Float16
+
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_USE_SOFT_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT16_H
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 505fa6d7957f8..68907507b9ffc 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -50,8 +50,20 @@
 // LIBC_TYPES_HAS_FLOAT16 is provided by
 // "include/llvm-libc-macros/float16-macros.h"
 #ifdef LIBC_TYPES_HAS_FLOAT16
+
+#ifdef LIBC_USE_SOFT_FLOAT16
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+struct Float16;
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+using float16 = LIBC_NAMESPACE::fputil::Float16;
+#else
 // Type alias for internal use.
 using float16 = _Float16;
+#endif
+
 #endif // LIBC_TYPES_HAS_FLOAT16
 
 // -- float128 support --------------------------------------------------------
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 9f4624682eafe..baed5ad3ffea9 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -3236,6 +3236,7 @@ add_header_library(
     fabsf16.h
   DEPENDS
     libc.include.llvm-libc-macros.float16_macros
+    libc.src.__support.FPUtil.Float16
     libc.src.__support.FPUtil.basic_operations
     libc.src.__support.macros.config
   FLAGS
diff --git a/libc/src/__support/math/fabsf16.h b/libc/src/__support/math/fabsf16.h
index 26634361adc73..ca568c680b7c2 100644
--- a/libc/src/__support/math/fabsf16.h
+++ b/libc/src/__support/math/fabsf16.h
@@ -14,6 +14,7 @@
 #ifdef LIBC_TYPES_HAS_FLOAT16
 
 #include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/Float16.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/properties/architectures.h"
 #include "src/__support/macros/properties/compiler.h"
@@ -27,7 +28,8 @@ LIBC_INLINE constexpr float16 fabsf16(float16 x) {
   // For x86, GCC generates better code from the generic implementation.
   // https://godbolt.org/z/K9orM4hTa
 #if defined(__LIBC_MISC_MATH_BASIC_OPS_OPT) &&                                 \
-    !(defined(LIBC_TARGET_ARCH_IS_X86) && defined(LIBC_COMPILER_IS_GCC))
+    !(defined(LIBC_TARGET_ARCH_IS_X86) && defined(LIBC_COMPILER_IS_GCC)) &&    \
+    !defined(LIBC_USE_SOFT_FLOAT16)
   return __builtin_fabsf16(x);
 #else
   return fputil::abs(x);
diff --git a/libc/src/math/generic/fabsf16.cpp b/libc/src/math/generic/fabsf16.cpp
index 8e84f78ed564e..9138d54dd5f62 100644
--- a/libc/src/math/generic/fabsf16.cpp
+++ b/libc/src/math/generic/fabsf16.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/math/fabsf16.h"
 #include "src/__support/math/fabsf16.h"
 
 namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt
index 2d1301d3a1e66..97355fbbf0278 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -713,6 +713,23 @@ add_fp_unittest(
     -lpthread
 )
 
+add_fp_unittest(
+  float16_test
+  NO_RUN_POSTBUILD
+  NEED_MPFR
+  SUITE
+    libc_math_exhaustive_tests
+  SRCS
+    float16_test.cpp
+  DEPENDS
+    .exhaustive_test
+    libc.src.__support.FPUtil.Float16
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.FPUtil.fp_bits
+  LINK_LIBRARIES
+    -lpthread
+)
+
 add_fp_unittest(
   bfloat16_test
   NO_RUN_POSTBUILD
diff --git a/libc/test/src/math/exhaustive/exhaustive_test.h b/libc/test/src/math/exhaustive/exhaustive_test.h
index 322d774d46a68..04d43214e00a2 100644
--- a/libc/test/src/math/exhaustive/exhaustive_test.h
+++ b/libc/test/src/math/exhaustive/exhaustive_test.h
@@ -8,6 +8,7 @@
 
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/Float16.h"
 #include "src/__support/macros/properties/types.h"
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
diff --git a/libc/test/src/math/exhaustive/float16_test.cpp b/libc/test/src/math/exhaustive/float16_test.cpp
new file mode 100644
index 0000000000000..3d1ba1ab805a6
--- /dev/null
+++ b/libc/test/src/math/exhaustive/float16_test.cpp
@@ -0,0 +1,67 @@
+//===-- Exhaustive tests for float -> float16 conversion ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "exhaustive_test.h"
+#include "src/__support/FPUtil/cast.h"
+#include "utils/MPFRWrapper/MPCommon.h"
+
+using namespace LIBC_NAMESPACE::fputil;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+template <typename InType>
+struct Float16ConversionChecker : public virtual LIBC_NAMESPACE::testing::Test {
+  using FloatType = InType;
+  using FPBits = LIBC_NAMESPACE::fputil::FPBits<FloatType>;
+  using StorageType = typename FPBits::StorageType;
+
+  // Check in a range, return the number of failures.
+  uint64_t check(StorageType start, StorageType stop,
+                 mpfr::RoundingMode rounding) {
+    mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return (stop > start);
+    StorageType bits = start;
+    uint64_t failed = 0;
+    do {
+      FPBits x_bits(bits);
+      FloatType x = x_bits.get_val();
+
+      const float16 libc_result = cast<float16>(x);
+      const float16 mpfr_result = mpfr::MPFRNumber(x).as<float16>();
+
+      const bool correct =
+          LIBC_NAMESPACE::testing::getMatcher<
+              LIBC_NAMESPACE::testing::TestCond::EQ>(mpfr_result)
+              .match(libc_result);
+
+      failed += (!correct);
+    } while (bits++ < stop);
+    return failed;
+  }
+};
+
+template <typename FloatType>
+using LlvmLibcFloat16ExhaustiveTest =
+    LlvmLibcExhaustiveMathTest<Float16ConversionChecker<FloatType>>;
+using LlvmLibcFloat16FromFloatTest = LlvmLibcFloat16ExhaustiveTest<float>;
+
+// Positive Range: [0, Inf];
+constexpr uint32_t POS_START = 0x0000'0000U;
+constexpr uint32_t POS_STOP = 0x7f80'0000U;
+
+// Negative Range: [-Inf, 0];
+constexpr uint32_t NEG_START = 0xb000'0000U;
+constexpr uint32_t NEG_STOP = 0xff80'0000U;
+
+TEST_F(LlvmLibcFloat16FromFloatTest, PostiveRange) {
+  test_full_range_all_roundings(POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcFloat16FromFloatTest, NegativeRange) {
+  test_full_range_all_roundings(NEG_START, NEG_STOP);
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 81f76fa7681fd..8e670ad2a2851 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -229,6 +229,7 @@ add_fp_unittest(
     FAbsTest.h
   DEPENDS
     libc.src.math.fabsf16
+    libc.src.__support.FPUtil.Float16
 )
 
 add_fp_unittest(
diff --git a/libc/test/src/math/smoke/fabsf16_test.cpp b/libc/test/src/math/smoke/fabsf16_test.cpp
index c43bd5090f90b..d4d6dd1d2593a 100644
--- a/libc/test/src/math/smoke/fabsf16_test.cpp
+++ b/libc/test/src/math/smoke/fabsf16_test.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "FAbsTest.h"
-
+#include "src/__support/FPUtil/Float16.h"
 #include "src/math/fabsf16.h"
 
 LIST_FABS_TESTS(float16, LIBC_NAMESPACE::fabsf16)
diff --git a/libc/utils/MPFRWrapper/CMakeLists.txt b/libc/utils/MPFRWrapper/CMakeLists.txt
index 73151c61a7fcc..a1546992ce21c 100644
--- a/libc/utils/MPFRWrapper/CMakeLists.txt
+++ b/libc/utils/MPFRWrapper/CMakeLists.txt
@@ -14,6 +14,7 @@ if(LIBC_TESTS_CAN_USE_MPFR OR LIBC_TESTS_CAN_USE_MPC)
     libc.src.__support.CPP.string
     libc.src.__support.CPP.string_view
     libc.src.__support.CPP.type_traits
+    libc.src.__support.FPUtil.Float16
     libc.src.__support.FPUtil.bfloat16
     libc.src.__support.FPUtil.cast
     libc.src.__support.FPUtil.fp_bits
@@ -43,6 +44,7 @@ if(LIBC_TESTS_CAN_USE_MPFR)
     libc.hdr.stdint_proxy
     libc.src.__support.CPP.array
     libc.src.__support.CPP.stringstream
+    libc.src.__support.FPUtil.Float16
     libc.src.__support.FPUtil.bfloat16
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.fpbits_str
diff --git a/libc/utils/MPFRWrapper/MPCommon.cpp b/libc/utils/MPFRWrapper/MPCommon.cpp
index 2422bcf45222f..4847f03d1cbfa 100644
--- a/libc/utils/MPFRWrapper/MPCommon.cpp
+++ b/libc/utils/MPFRWrapper/MPCommon.cpp
@@ -10,6 +10,11 @@
 
 #include "src/__support/CPP/string_view.h"
 #include "src/__support/FPUtil/bfloat16.h"
+
+#ifdef LIBC_USE_SOFT_FLOAT16
+#include "src/__support/FPUtil/Float16.h"
+#endif
+
 #include "src/__support/FPUtil/cast.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/properties/types.h"
@@ -632,7 +637,7 @@ template <> long double MPFRNumber::as<long double>() const {
   return mpfr_get_ld(value, mpfr_rounding);
 }
 
-#ifdef LIBC_TYPES_HAS_FLOAT16
+#if defined(LIBC_TYPES_HAS_FLOAT16) || defined(LIBC_USE_SOFT_FLOAT16)
 template <> float16 MPFRNumber::as<float16>() const {
   // TODO: Either prove that this cast won't cause double-rounding errors, or
   // find a better way to get a float16.
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index d585baa2e0d2c..b928edeebba4b 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -11,6 +11,7 @@
 
 #include "src/__support/CPP/array.h"
 #include "src/__support/CPP/stringstream.h"
+#include "src/__support/FPUtil/Float16.h"
 #include "src/__support/FPUtil/bfloat16.h"
 #include "src/__support/FPUtil/fpbits_str.h"
 #include "src/__support/macros/config.h"



More information about the libc-commits mailing list