[libc-commits] [compiler-rt] [libc] [compiler-rt][builtins] libc-backed float16 extend/truncate builtins (PR #211882)

via libc-commits libc-commits at lists.llvm.org
Sat Aug 8 13:57:51 PDT 2026


https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/211882

>From b669b3c1f7c86bb4f91d30449643a45085d3d068 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Thu, 16 Jul 2026 09:43:25 +0300
Subject: [PATCH 1/7] [compiler-rt][builtins] libc-backed floating-point
 extend/truncate builtins

---
 libc/test/shared/shared_builtins_test.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/libc/test/shared/shared_builtins_test.cpp b/libc/test/shared/shared_builtins_test.cpp
index eb1c566d6b179..1046dd6a0e1d8 100644
--- a/libc/test/shared/shared_builtins_test.cpp
+++ b/libc/test/shared/shared_builtins_test.cpp
@@ -19,6 +19,10 @@ TEST(LlvmLibcSharedBuiltinsTest, SinglePrecisionArithmtic) {
   EXPECT_FP_EQ(6.0f, shared::mulsf3(2.0f, 3.0f));
   EXPECT_FP_EQ(-5.0, shared::negsf2(5.0));
   EXPECT_FP_EQ(2.0f, shared::subsf3(5.0f, 3.0f));
+namespace shared = LIBC_NAMESPACE::shared;
+
+TEST(LlvmLibcSharedBuiltinsTest, AllFloat) {
+  // TODO: assertions for shared::*sf3 builtins.
 }
 
 TEST(LlvmLibcSharedBuiltinsTest, DoublePrecisionArithmtic) {
@@ -46,6 +50,7 @@ TEST(LlvmLibcSharedBuiltinsTest, ExtendConversion) {
   EXPECT_FP_EQ(float128(1.5), shared::extenddftf2(1.5));
   EXPECT_FP_EQ(float128(1.5), shared::extendsftf2(1.5f));
 #ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+#if LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
   EXPECT_FP_EQ(float128(1.5), shared::extendxftf2(1.5L));
 #endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
 #endif // LIBC_TYPES_HAS_FLOAT128
@@ -57,6 +62,7 @@ TEST(LlvmLibcSharedBuiltinsTest, TruncateConversion) {
   EXPECT_FP_EQ(1.5, shared::trunctfdf2(float128(1.5)));
   EXPECT_FP_EQ(1.5f, shared::trunctfsf2(float128(1.5)));
 #ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+#if LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
   EXPECT_FP_EQ(1.5L, shared::trunctfxf2(float128(1.5)));
 #endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
 #endif // LIBC_TYPES_HAS_FLOAT128

>From df2209e1cd94ac6ef20f1eedf9a262b42ac946f6 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Fri, 24 Jul 2026 20:33:18 +0300
Subject: [PATCH 2/7] [compiler-rt][builtins] libc-backed bfloat16
 extend/truncate builtins

---
 compiler-rt/lib/builtins/CMakeLists.txt    |  4 +++
 compiler-rt/lib/builtins/extendbfsf2.cpp   | 24 +++++++++++++
 compiler-rt/lib/builtins/truncdfbf2.cpp    | 24 +++++++++++++
 compiler-rt/lib/builtins/truncsfbf2.cpp    | 24 +++++++++++++
 compiler-rt/lib/builtins/trunctfbf2.cpp    | 29 ++++++++++++++++
 libc/shared/builtins.h                     |  4 +++
 libc/shared/builtins/extendbfsf2.h         | 29 ++++++++++++++++
 libc/shared/builtins/truncdfbf2.h          | 29 ++++++++++++++++
 libc/shared/builtins/truncsfbf2.h          | 29 ++++++++++++++++
 libc/shared/builtins/trunctfbf2.h          | 35 +++++++++++++++++++
 libc/src/__support/builtins/CMakeLists.txt | 28 ++++++++++++++++
 libc/src/__support/builtins/extendbfsf2.h  | 35 +++++++++++++++++++
 libc/src/__support/builtins/truncdfbf2.h   | 33 ++++++++++++++++++
 libc/src/__support/builtins/truncsfbf2.h   | 33 ++++++++++++++++++
 libc/src/__support/builtins/trunctfbf2.h   | 39 ++++++++++++++++++++++
 libc/test/shared/CMakeLists.txt            |  4 +++
 libc/test/shared/shared_builtins_test.cpp  |  6 ++++
 17 files changed, 409 insertions(+)
 create mode 100644 compiler-rt/lib/builtins/extendbfsf2.cpp
 create mode 100644 compiler-rt/lib/builtins/truncdfbf2.cpp
 create mode 100644 compiler-rt/lib/builtins/truncsfbf2.cpp
 create mode 100644 compiler-rt/lib/builtins/trunctfbf2.cpp
 create mode 100644 libc/shared/builtins/extendbfsf2.h
 create mode 100644 libc/shared/builtins/truncdfbf2.h
 create mode 100644 libc/shared/builtins/truncsfbf2.h
 create mode 100644 libc/shared/builtins/trunctfbf2.h
 create mode 100644 libc/src/__support/builtins/extendbfsf2.h
 create mode 100644 libc/src/__support/builtins/truncdfbf2.h
 create mode 100644 libc/src/__support/builtins/truncsfbf2.h
 create mode 100644 libc/src/__support/builtins/trunctfbf2.h

diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index 1134115934df5..abd581a206647 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -291,6 +291,7 @@ if(COMPILER_RT_USE_LIBC_MATH)
   use_libc_builtin(GENERIC_SOURCES    divdf3)
   use_libc_builtin(GENERIC_SOURCES    divsf3)
   use_libc_builtin(GENERIC_TF_SOURCES divtf3)
+  use_libc_builtin(BF16_SOURCES       extendbfsf2)
   use_libc_builtin(GENERIC_TF_SOURCES extenddftf2)
   use_libc_builtin(GENERIC_SOURCES    extendsfdf2)
   use_libc_builtin(GENERIC_TF_SOURCES extendsftf2)
@@ -316,6 +317,9 @@ if(COMPILER_RT_USE_LIBC_MATH)
   use_libc_builtin(GENERIC_SOURCES    subsf3)
   use_libc_builtin(GENERIC_TF_SOURCES subtf3)
   use_libc_builtin(GENERIC_SOURCES    truncdfsf2)  
+  use_libc_builtin(BF16_SOURCES       truncdfbf2)
+  use_libc_builtin(BF16_SOURCES       truncsfbf2)
+  use_libc_builtin(BF16_SOURCES       trunctfbf2)
   use_libc_builtin(GENERIC_TF_SOURCES trunctfdf2)
   use_libc_builtin(GENERIC_TF_SOURCES trunctfsf2)
   use_libc_builtin(x86_80_BIT_SOURCES trunctfxf2)
diff --git a/compiler-rt/lib/builtins/extendbfsf2.cpp b/compiler-rt/lib/builtins/extendbfsf2.cpp
new file mode 100644
index 0000000000000..74c56803d5c65
--- /dev/null
+++ b/compiler-rt/lib/builtins/extendbfsf2.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __extendbfsf2, extend bfloat16 to float,
+/// on top of LLVM-libc's shared::extendbfsf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define SRC_BFLOAT16
+#define DST_SINGLE
+#include "fp_extend.h"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/extendbfsf2.h"
+
+extern "C" COMPILER_RT_ABI dst_t __extendbfsf2(src_t a) {
+  return LIBC_NAMESPACE::shared::extendbfsf2(__builtin_bit_cast(uint16_t, a));
+}
diff --git a/compiler-rt/lib/builtins/truncdfbf2.cpp b/compiler-rt/lib/builtins/truncdfbf2.cpp
new file mode 100644
index 0000000000000..a5ae505b03553
--- /dev/null
+++ b/compiler-rt/lib/builtins/truncdfbf2.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __truncdfbf2, truncate double to
+/// bfloat16, on top of LLVM-libc's shared::truncdfbf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define SRC_DOUBLE
+#define DST_BFLOAT
+#include "fp_trunc.h"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/truncdfbf2.h"
+
+extern "C" COMPILER_RT_ABI dst_t __truncdfbf2(src_t a) {
+  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncdfbf2(a));
+}
diff --git a/compiler-rt/lib/builtins/truncsfbf2.cpp b/compiler-rt/lib/builtins/truncsfbf2.cpp
new file mode 100644
index 0000000000000..91011f086ad85
--- /dev/null
+++ b/compiler-rt/lib/builtins/truncsfbf2.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __truncsfbf2, truncate float to bfloat16,
+/// on top of LLVM-libc's shared::truncsfbf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define SRC_SINGLE
+#define DST_BFLOAT
+#include "fp_trunc.h"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/truncsfbf2.h"
+
+extern "C" COMPILER_RT_ABI dst_t __truncsfbf2(src_t a) {
+  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncsfbf2(a));
+}
diff --git a/compiler-rt/lib/builtins/trunctfbf2.cpp b/compiler-rt/lib/builtins/trunctfbf2.cpp
new file mode 100644
index 0000000000000..d789111907fd3
--- /dev/null
+++ b/compiler-rt/lib/builtins/trunctfbf2.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __trunctfbf2, truncate float128 to
+/// bfloat16, on top of LLVM-libc's shared::trunctfbf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/trunctfbf2.h"
+
+#if defined(CRT_HAS_TF_MODE) && defined(__x86_64__)
+#define SRC_QUAD
+#define DST_BFLOAT
+#include "fp_trunc.h"
+
+extern "C" COMPILER_RT_ABI dst_t __trunctfbf2(src_t a) {
+  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::trunctfbf2(a));
+}
+#endif
diff --git a/libc/shared/builtins.h b/libc/shared/builtins.h
index e13ef6b84a6de..3833bb8142179 100644
--- a/libc/shared/builtins.h
+++ b/libc/shared/builtins.h
@@ -23,6 +23,7 @@
 #include "builtins/divdf3.h"
 #include "builtins/divsf3.h"
 #include "builtins/divtf3.h"
+#include "builtins/extendbfsf2.h"
 #include "builtins/extenddftf2.h"
 #include "builtins/extendsfdf2.h"
 #include "builtins/extendsftf2.h"
@@ -47,7 +48,10 @@
 #include "builtins/subdf3.h"
 #include "builtins/subsf3.h"
 #include "builtins/subtf3.h"
+#include "builtins/truncdfbf2.h"
 #include "builtins/truncdfsf2.h"
+#include "builtins/truncsfbf2.h"
+#include "builtins/trunctfbf2.h"
 #include "builtins/trunctfdf2.h"
 #include "builtins/trunctfsf2.h"
 #include "builtins/trunctfxf2.h"
diff --git a/libc/shared/builtins/extendbfsf2.h b/libc/shared/builtins/extendbfsf2.h
new file mode 100644
index 0000000000000..f660301a5e31c
--- /dev/null
+++ b/libc/shared/builtins/extendbfsf2.h
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __extendbfsf2 implementation as
+/// shared::extendbfsf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDBFSF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_EXTENDBFSF2_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/extendbfsf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::extendbfsf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDBFSF2_H
diff --git a/libc/shared/builtins/truncdfbf2.h b/libc/shared/builtins/truncdfbf2.h
new file mode 100644
index 0000000000000..2846c484fa813
--- /dev/null
+++ b/libc/shared/builtins/truncdfbf2.h
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __truncdfbf2 implementation as
+/// shared::truncdfbf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCDFBF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCDFBF2_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/truncdfbf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::truncdfbf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCDFBF2_H
diff --git a/libc/shared/builtins/truncsfbf2.h b/libc/shared/builtins/truncsfbf2.h
new file mode 100644
index 0000000000000..93f4bfb256f84
--- /dev/null
+++ b/libc/shared/builtins/truncsfbf2.h
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __truncsfbf2 implementation as
+/// shared::truncsfbf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCSFBF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCSFBF2_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/truncsfbf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::truncsfbf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCSFBF2_H
diff --git a/libc/shared/builtins/trunctfbf2.h b/libc/shared/builtins/trunctfbf2.h
new file mode 100644
index 0000000000000..76aca0aa13565
--- /dev/null
+++ b/libc/shared/builtins/trunctfbf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __trunctfbf2 implementation as
+/// shared::trunctfbf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCTFBF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCTFBF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/trunctfbf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::trunctfbf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCTFBF2_H
diff --git a/libc/src/__support/builtins/CMakeLists.txt b/libc/src/__support/builtins/CMakeLists.txt
index 51212c4bff34c..477c121d6d4cb 100644
--- a/libc/src/__support/builtins/CMakeLists.txt
+++ b/libc/src/__support/builtins/CMakeLists.txt
@@ -230,6 +230,12 @@ add_header_library(
   DEPENDS
     libc.hdr.stdint_proxy
     libc.src.__support.builtins.fixint_helper
+  extendbfsf2
+  HDRS
+    extendbfsf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.src.__support.FPUtil.bfloat16
     libc.src.__support.macros.config
 )
 
@@ -252,6 +258,12 @@ add_header_library(
   DEPENDS
     libc.hdr.stdint_proxy
     libc.src.__support.builtins.fixint_helper
+  truncsfbf2
+  HDRS
+    truncsfbf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.src.__support.FPUtil.bfloat16
     libc.src.__support.macros.config
 )
 
@@ -262,6 +274,12 @@ add_header_library(
   DEPENDS
     libc.hdr.stdint_proxy
     libc.src.__support.builtins.fixint_helper
+  truncdfbf2
+  HDRS
+    truncdfbf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.src.__support.FPUtil.bfloat16
     libc.src.__support.macros.config
 )
 
@@ -350,3 +368,13 @@ add_header_library(
     libc.src.__support.macros.properties.types
     libc.src.__support.uint128
 )
+  trunctfbf2
+  HDRS
+    trunctfbf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.include.llvm-libc-types.float128
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.macros.config
+)
+
diff --git a/libc/src/__support/builtins/extendbfsf2.h b/libc/src/__support/builtins/extendbfsf2.h
new file mode 100644
index 0000000000000..1ce0009a71055
--- /dev/null
+++ b/libc/src/__support/builtins/extendbfsf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __extendbfsf2 implementation as
+/// builtins::extendbfsf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDBFSF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDBFSF2_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Extend bfloat16 to float; mirrors compiler-rt's __extendbfsf2.
+LIBC_INLINE float extendbfsf2(uint16_t bits) {
+  bfloat16 x;
+  x.bits = bits;
+  return fputil::cast<float>(x);
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDBFSF2_H
diff --git a/libc/src/__support/builtins/truncdfbf2.h b/libc/src/__support/builtins/truncdfbf2.h
new file mode 100644
index 0000000000000..4bccb2db9de6d
--- /dev/null
+++ b/libc/src/__support/builtins/truncdfbf2.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __truncdfbf2 implementation as
+/// builtins::truncdfbf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFBF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFBF2_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate double to bfloat16; mirrors compiler-rt's __truncdfbf2.
+LIBC_INLINE uint16_t truncdfbf2(double x) {
+  return fputil::cast<bfloat16>(x).bits;
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFBF2_H
diff --git a/libc/src/__support/builtins/truncsfbf2.h b/libc/src/__support/builtins/truncsfbf2.h
new file mode 100644
index 0000000000000..08611f20fb2a2
--- /dev/null
+++ b/libc/src/__support/builtins/truncsfbf2.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __truncsfbf2 implementation as
+/// builtins::truncsfbf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCSFBF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCSFBF2_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate float to bfloat16; mirrors compiler-rt's __truncsfbf2.
+LIBC_INLINE uint16_t truncsfbf2(float x) {
+  return fputil::cast<bfloat16>(x).bits;
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCSFBF2_H
diff --git a/libc/src/__support/builtins/trunctfbf2.h b/libc/src/__support/builtins/trunctfbf2.h
new file mode 100644
index 0000000000000..99e2833c39058
--- /dev/null
+++ b/libc/src/__support/builtins/trunctfbf2.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __trunctfbf2 implementation as
+/// builtins::trunctfbf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFBF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFBF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT128
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate float128 to bfloat16; mirrors compiler-rt's __trunctfbf2.
+LIBC_INLINE uint16_t trunctfbf2(float128 x) {
+  return fputil::cast<bfloat16>(x).bits;
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFBF2_H
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 04b6a6e3aed91..22a6d09eb6369 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -834,6 +834,7 @@ add_fp_unittest(
     libc.src.__support.builtins.divdf3
     libc.src.__support.builtins.divsf3
     libc.src.__support.builtins.divtf3
+    libc.src.__support.builtins.extendbfsf2
     libc.src.__support.builtins.extenddftf2
     libc.src.__support.builtins.extendsfdf2
     libc.src.__support.builtins.extendsftf2
@@ -858,7 +859,10 @@ add_fp_unittest(
     libc.src.__support.builtins.subdf3
     libc.src.__support.builtins.subsf3
     libc.src.__support.builtins.subtf3
+    libc.src.__support.builtins.truncdfbf2
     libc.src.__support.builtins.truncdfsf2
+    libc.src.__support.builtins.truncsfbf2
+    libc.src.__support.builtins.trunctfbf2
     libc.src.__support.builtins.trunctfdf2
     libc.src.__support.builtins.trunctfsf2
     libc.src.__support.builtins.trunctfxf2
diff --git a/libc/test/shared/shared_builtins_test.cpp b/libc/test/shared/shared_builtins_test.cpp
index 1046dd6a0e1d8..dc7847dbb01a0 100644
--- a/libc/test/shared/shared_builtins_test.cpp
+++ b/libc/test/shared/shared_builtins_test.cpp
@@ -46,6 +46,7 @@ TEST(LlvmLibcSharedBuiltinsTest, QuadPrecisionArithmtic) {
 
 TEST(LlvmLibcSharedBuiltinsTest, ExtendConversion) {
   EXPECT_FP_EQ(1.5, shared::extendsfdf2(1.5f));
+  EXPECT_FP_EQ(1.5f, shared::extendbfsf2(static_cast<uint16_t>(0x3FC0)));
 #ifdef LIBC_TYPES_HAS_FLOAT128
   EXPECT_FP_EQ(float128(1.5), shared::extenddftf2(1.5));
   EXPECT_FP_EQ(float128(1.5), shared::extendsftf2(1.5f));
@@ -57,7 +58,12 @@ TEST(LlvmLibcSharedBuiltinsTest, ExtendConversion) {
 }
 
 TEST(LlvmLibcSharedBuiltinsTest, TruncateConversion) {
+  EXPECT_EQ(static_cast<uint16_t>(0x3FC0), shared::truncdfbf2(1.5));
   EXPECT_FP_EQ(1.5f, shared::truncdfsf2(1.5));
+  EXPECT_EQ(static_cast<uint16_t>(0x3FC0), shared::truncsfbf2(1.5f));
+#ifdef LIBC_TYPES_HAS_FLOAT128
+  EXPECT_EQ(static_cast<uint16_t>(0x3FC0), shared::trunctfbf2(float128(1.5)));
+#endif // LIBC_TYPES_HAS_FLOAT128
 #ifdef LIBC_TYPES_HAS_FLOAT128
   EXPECT_FP_EQ(1.5, shared::trunctfdf2(float128(1.5)));
   EXPECT_FP_EQ(1.5f, shared::trunctfsf2(float128(1.5)));

>From d08d9ca1a8f68a6a7d4c65c6ee54b804944000ed Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Fri, 24 Jul 2026 20:53:10 +0300
Subject: [PATCH 3/7] [compiler-rt][builtins] libc-backed float16
 extend/truncate builtins

---
 compiler-rt/lib/builtins/CMakeLists.txt       |  6 ++
 compiler-rt/lib/builtins/extendhfdf2.cpp      | 30 ++++++++
 compiler-rt/lib/builtins/extendhfsf2.cpp      | 44 ++++++++++++
 compiler-rt/lib/builtins/extendhftf2.cpp      | 35 ++++++++++
 compiler-rt/lib/builtins/truncdfhf2.cpp       | 30 ++++++++
 compiler-rt/lib/builtins/truncsfhf2.cpp       | 44 ++++++++++++
 compiler-rt/lib/builtins/trunctfhf2.cpp       | 35 ++++++++++
 libc/shared/builtins.h                        |  6 ++
 libc/shared/builtins/extendhfdf2.h            | 35 ++++++++++
 libc/shared/builtins/extendhfsf2.h            | 35 ++++++++++
 libc/shared/builtins/extendhftf2.h            | 36 ++++++++++
 libc/shared/builtins/truncdfhf2.h             | 35 ++++++++++
 libc/shared/builtins/truncsfhf2.h             | 35 ++++++++++
 libc/shared/builtins/trunctfhf2.h             | 36 ++++++++++
 libc/src/__support/builtins/CMakeLists.txt    | 70 +++++++++++++++++++
 libc/src/__support/builtins/extendhfdf2.h     | 39 +++++++++++
 libc/src/__support/builtins/extendhfsf2.h     | 39 +++++++++++
 libc/src/__support/builtins/extendhftf2.h     | 40 +++++++++++
 .../src/__support/builtins/fpconvert_helper.h | 33 +++++++--
 libc/src/__support/builtins/truncdfhf2.h      | 40 +++++++++++
 libc/src/__support/builtins/truncsfhf2.h      | 40 +++++++++++
 libc/src/__support/builtins/trunctfhf2.h      | 41 +++++++++++
 libc/test/shared/CMakeLists.txt               |  6 ++
 23 files changed, 785 insertions(+), 5 deletions(-)
 create mode 100644 compiler-rt/lib/builtins/extendhfdf2.cpp
 create mode 100644 compiler-rt/lib/builtins/extendhfsf2.cpp
 create mode 100644 compiler-rt/lib/builtins/extendhftf2.cpp
 create mode 100644 compiler-rt/lib/builtins/truncdfhf2.cpp
 create mode 100644 compiler-rt/lib/builtins/truncsfhf2.cpp
 create mode 100644 compiler-rt/lib/builtins/trunctfhf2.cpp
 create mode 100644 libc/shared/builtins/extendhfdf2.h
 create mode 100644 libc/shared/builtins/extendhfsf2.h
 create mode 100644 libc/shared/builtins/extendhftf2.h
 create mode 100644 libc/shared/builtins/truncdfhf2.h
 create mode 100644 libc/shared/builtins/truncsfhf2.h
 create mode 100644 libc/shared/builtins/trunctfhf2.h
 create mode 100644 libc/src/__support/builtins/extendhfdf2.h
 create mode 100644 libc/src/__support/builtins/extendhfsf2.h
 create mode 100644 libc/src/__support/builtins/extendhftf2.h
 create mode 100644 libc/src/__support/builtins/truncdfhf2.h
 create mode 100644 libc/src/__support/builtins/truncsfhf2.h
 create mode 100644 libc/src/__support/builtins/trunctfhf2.h

diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index abd581a206647..8a35fe3cdac23 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -293,6 +293,9 @@ if(COMPILER_RT_USE_LIBC_MATH)
   use_libc_builtin(GENERIC_TF_SOURCES divtf3)
   use_libc_builtin(BF16_SOURCES       extendbfsf2)
   use_libc_builtin(GENERIC_TF_SOURCES extenddftf2)
+  use_libc_builtin(GENERIC_SOURCES    extendhfsf2)
+  use_libc_builtin(GENERIC_SOURCES    extendhfdf2)
+  use_libc_builtin(GENERIC_TF_SOURCES extendhftf2)
   use_libc_builtin(GENERIC_SOURCES    extendsfdf2)
   use_libc_builtin(GENERIC_TF_SOURCES extendsftf2)
   use_libc_builtin(x86_80_BIT_SOURCES extendxftf2)
@@ -321,6 +324,9 @@ if(COMPILER_RT_USE_LIBC_MATH)
   use_libc_builtin(BF16_SOURCES       truncsfbf2)
   use_libc_builtin(BF16_SOURCES       trunctfbf2)
   use_libc_builtin(GENERIC_TF_SOURCES trunctfdf2)
+  use_libc_builtin(GENERIC_SOURCES    truncsfhf2)
+  use_libc_builtin(GENERIC_SOURCES    truncdfhf2)
+  use_libc_builtin(GENERIC_TF_SOURCES trunctfhf2)
   use_libc_builtin(GENERIC_TF_SOURCES trunctfsf2)
   use_libc_builtin(x86_80_BIT_SOURCES trunctfxf2)
 endif()
diff --git a/compiler-rt/lib/builtins/extendhfdf2.cpp b/compiler-rt/lib/builtins/extendhfdf2.cpp
new file mode 100644
index 0000000000000..f1d40971b7f45
--- /dev/null
+++ b/compiler-rt/lib/builtins/extendhfdf2.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __extendhfdf2, extend float16 to double,
+/// on top of LLVM-libc's shared::extendhfdf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define SRC_HALF
+#define DST_DOUBLE
+#include "fp_extend_impl.inc"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/extendhfdf2.h"
+
+#if defined(LIBC_TYPES_HAS_FLOAT16)
+extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfdf2(src_t a) {
+  return LIBC_NAMESPACE::shared::extendhfdf2(__builtin_bit_cast(uint16_t, a));
+}
+#else
+extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfdf2(src_t a) {
+  return __extendXfYf2__(a);
+}
+#endif
diff --git a/compiler-rt/lib/builtins/extendhfsf2.cpp b/compiler-rt/lib/builtins/extendhfsf2.cpp
new file mode 100644
index 0000000000000..6dc3ef17c22d5
--- /dev/null
+++ b/compiler-rt/lib/builtins/extendhfsf2.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __extendhfsf2, extend float16 to float,
+/// on top of LLVM-libc's shared::extendhfsf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define SRC_HALF
+#define DST_SINGLE
+#include "fp_extend_impl.inc"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/extendhfsf2.h"
+
+#if defined(LIBC_TYPES_HAS_FLOAT16)
+extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfsf2(src_t a) {
+  return LIBC_NAMESPACE::shared::extendhfsf2(__builtin_bit_cast(uint16_t, a));
+}
+#else
+extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfsf2(src_t a) {
+  return __extendXfYf2__(a);
+}
+#endif
+
+extern "C" {
+#if defined(__ARM_EABI__)
+#if defined(COMPILER_RT_ARMHF_TARGET)
+AEABI_RTABI dst_t __gnu_h2f_ieee(src_t a) { return __extendhfsf2(a); }
+AEABI_RTABI dst_t __aeabi_h2f(src_t a) { return __extendhfsf2(a); }
+#else
+COMPILER_RT_ALIAS(__extendhfsf2, __gnu_h2f_ieee)
+COMPILER_RT_ALIAS(__extendhfsf2, __aeabi_h2f)
+#endif
+#else
+COMPILER_RT_ABI dst_t __gnu_h2f_ieee(src_t a) { return __extendhfsf2(a); }
+#endif
+}
diff --git a/compiler-rt/lib/builtins/extendhftf2.cpp b/compiler-rt/lib/builtins/extendhftf2.cpp
new file mode 100644
index 0000000000000..2b035ee639b22
--- /dev/null
+++ b/compiler-rt/lib/builtins/extendhftf2.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __extendhftf2, extend float16 to
+/// float128, on top of LLVM-libc's shared::extendhftf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/extendhftf2.h"
+
+#if defined(CRT_HAS_TF_MODE) && defined(COMPILER_RT_HAS_FLOAT16)
+#define SRC_HALF
+#define DST_QUAD
+#include "fp_extend_impl.inc"
+
+#if defined(LIBC_TYPES_HAS_FLOAT16)
+extern "C" COMPILER_RT_ABI dst_t __extendhftf2(src_t a) {
+  return LIBC_NAMESPACE::shared::extendhftf2(__builtin_bit_cast(uint16_t, a));
+}
+#else
+extern "C" COMPILER_RT_ABI dst_t __extendhftf2(src_t a) {
+  return __extendXfYf2__(a);
+}
+#endif
+#endif
diff --git a/compiler-rt/lib/builtins/truncdfhf2.cpp b/compiler-rt/lib/builtins/truncdfhf2.cpp
new file mode 100644
index 0000000000000..ab08483cdabfa
--- /dev/null
+++ b/compiler-rt/lib/builtins/truncdfhf2.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __truncdfhf2, truncate double to float16,
+/// on top of LLVM-libc's shared::truncdfhf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define SRC_DOUBLE
+#define DST_HALF
+#include "fp_trunc_impl.inc"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/truncdfhf2.h"
+
+#if defined(LIBC_TYPES_HAS_FLOAT16)
+extern "C" COMPILER_RT_ABI dst_t __truncdfhf2(src_t a) {
+  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncdfhf2(a));
+}
+#else
+extern "C" COMPILER_RT_ABI dst_t __truncdfhf2(src_t a) {
+  return __truncXfYf2__(a);
+}
+#endif
diff --git a/compiler-rt/lib/builtins/truncsfhf2.cpp b/compiler-rt/lib/builtins/truncsfhf2.cpp
new file mode 100644
index 0000000000000..3fa614d2970fe
--- /dev/null
+++ b/compiler-rt/lib/builtins/truncsfhf2.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __truncsfhf2, truncate float to float16,
+/// on top of LLVM-libc's shared::truncsfhf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define SRC_SINGLE
+#define DST_HALF
+#include "fp_trunc_impl.inc"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/truncsfhf2.h"
+
+#if defined(LIBC_TYPES_HAS_FLOAT16)
+extern "C" COMPILER_RT_ABI NOINLINE dst_t __truncsfhf2(src_t a) {
+  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncsfhf2(a));
+}
+#else
+extern "C" COMPILER_RT_ABI NOINLINE dst_t __truncsfhf2(src_t a) {
+  return __truncXfYf2__(a);
+}
+#endif
+
+extern "C" {
+#if defined(__ARM_EABI__)
+#if defined(COMPILER_RT_ARMHF_TARGET)
+AEABI_RTABI dst_t __gnu_f2h_ieee(float a) { return __truncsfhf2(a); }
+AEABI_RTABI dst_t __aeabi_f2h(float a) { return __truncsfhf2(a); }
+#else
+COMPILER_RT_ALIAS(__truncsfhf2, __gnu_f2h_ieee)
+COMPILER_RT_ALIAS(__truncsfhf2, __aeabi_f2h)
+#endif
+#else
+COMPILER_RT_ABI dst_t __gnu_f2h_ieee(float a) { return __truncsfhf2(a); }
+#endif
+}
diff --git a/compiler-rt/lib/builtins/trunctfhf2.cpp b/compiler-rt/lib/builtins/trunctfhf2.cpp
new file mode 100644
index 0000000000000..a1c06a9415229
--- /dev/null
+++ b/compiler-rt/lib/builtins/trunctfhf2.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements compiler-rt's __trunctfhf2, truncate float128 to
+/// float16, on top of LLVM-libc's shared::trunctfhf2.
+///
+//===----------------------------------------------------------------------===//
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#include "fp_libc_config.h"
+#include "shared/builtins/trunctfhf2.h"
+
+#if defined(CRT_HAS_TF_MODE) && defined(COMPILER_RT_HAS_FLOAT16)
+#define SRC_QUAD
+#define DST_HALF
+#include "fp_trunc_impl.inc"
+
+#if defined(LIBC_TYPES_HAS_FLOAT16)
+extern "C" COMPILER_RT_ABI dst_t __trunctfhf2(src_t a) {
+  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::trunctfhf2(a));
+}
+#else
+extern "C" COMPILER_RT_ABI dst_t __trunctfhf2(src_t a) {
+  return __truncXfYf2__(a);
+}
+#endif
+#endif
diff --git a/libc/shared/builtins.h b/libc/shared/builtins.h
index 3833bb8142179..dea8058f73dec 100644
--- a/libc/shared/builtins.h
+++ b/libc/shared/builtins.h
@@ -25,6 +25,9 @@
 #include "builtins/divtf3.h"
 #include "builtins/extendbfsf2.h"
 #include "builtins/extenddftf2.h"
+#include "builtins/extendhfdf2.h"
+#include "builtins/extendhfsf2.h"
+#include "builtins/extendhftf2.h"
 #include "builtins/extendsfdf2.h"
 #include "builtins/extendsftf2.h"
 #include "builtins/extendxftf2.h"
@@ -49,10 +52,13 @@
 #include "builtins/subsf3.h"
 #include "builtins/subtf3.h"
 #include "builtins/truncdfbf2.h"
+#include "builtins/truncdfhf2.h"
 #include "builtins/truncdfsf2.h"
 #include "builtins/truncsfbf2.h"
+#include "builtins/truncsfhf2.h"
 #include "builtins/trunctfbf2.h"
 #include "builtins/trunctfdf2.h"
+#include "builtins/trunctfhf2.h"
 #include "builtins/trunctfsf2.h"
 #include "builtins/trunctfxf2.h"
 
diff --git a/libc/shared/builtins/extendhfdf2.h b/libc/shared/builtins/extendhfdf2.h
new file mode 100644
index 0000000000000..ebae43abfbf3b
--- /dev/null
+++ b/libc/shared/builtins/extendhfdf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __extendhfdf2 implementation as
+/// shared::extendhfdf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDHFDF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_EXTENDHFDF2_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/extendhfdf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::extendhfdf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDHFDF2_H
diff --git a/libc/shared/builtins/extendhfsf2.h b/libc/shared/builtins/extendhfsf2.h
new file mode 100644
index 0000000000000..346961746bd52
--- /dev/null
+++ b/libc/shared/builtins/extendhfsf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __extendhfsf2 implementation as
+/// shared::extendhfsf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDHFSF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_EXTENDHFSF2_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/extendhfsf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::extendhfsf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDHFSF2_H
diff --git a/libc/shared/builtins/extendhftf2.h b/libc/shared/builtins/extendhftf2.h
new file mode 100644
index 0000000000000..28a3331fcfc5d
--- /dev/null
+++ b/libc/shared/builtins/extendhftf2.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __extendhftf2 implementation as
+/// shared::extendhftf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDHFTF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_EXTENDHFTF2_H
+
+#include "include/llvm-libc-types/float128.h"
+#include "src/__support/macros/properties/types.h"
+
+#if defined(LIBC_TYPES_HAS_FLOAT128) && defined(LIBC_TYPES_HAS_FLOAT16)
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/extendhftf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::extendhftf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDHFTF2_H
diff --git a/libc/shared/builtins/truncdfhf2.h b/libc/shared/builtins/truncdfhf2.h
new file mode 100644
index 0000000000000..697261cc261e1
--- /dev/null
+++ b/libc/shared/builtins/truncdfhf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __truncdfhf2 implementation as
+/// shared::truncdfhf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCDFHF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCDFHF2_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/truncdfhf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::truncdfhf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCDFHF2_H
diff --git a/libc/shared/builtins/truncsfhf2.h b/libc/shared/builtins/truncsfhf2.h
new file mode 100644
index 0000000000000..de011638e7c12
--- /dev/null
+++ b/libc/shared/builtins/truncsfhf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __truncsfhf2 implementation as
+/// shared::truncsfhf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCSFHF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCSFHF2_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/truncsfhf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::truncsfhf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCSFHF2_H
diff --git a/libc/shared/builtins/trunctfhf2.h b/libc/shared/builtins/trunctfhf2.h
new file mode 100644
index 0000000000000..00134f87c9978
--- /dev/null
+++ b/libc/shared/builtins/trunctfhf2.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __trunctfhf2 implementation as
+/// shared::trunctfhf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCTFHF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCTFHF2_H
+
+#include "include/llvm-libc-types/float128.h"
+#include "src/__support/macros/properties/types.h"
+
+#if defined(LIBC_TYPES_HAS_FLOAT128) && defined(LIBC_TYPES_HAS_FLOAT16)
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/trunctfhf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::trunctfhf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCTFHF2_H
diff --git a/libc/src/__support/builtins/CMakeLists.txt b/libc/src/__support/builtins/CMakeLists.txt
index 477c121d6d4cb..831c920688f14 100644
--- a/libc/src/__support/builtins/CMakeLists.txt
+++ b/libc/src/__support/builtins/CMakeLists.txt
@@ -378,3 +378,73 @@ add_header_library(
     libc.src.__support.macros.config
 )
 
+add_header_library(
+  extendhfsf2
+  HDRS
+    extendhfsf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.src.__support.builtins.fpconvert_helper
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+  extendhfdf2
+  HDRS
+    extendhfdf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.src.__support.builtins.fpconvert_helper
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+  extendhftf2
+  HDRS
+    extendhftf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.include.llvm-libc-types.float128
+    libc.src.__support.builtins.fpconvert_helper
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+  truncsfhf2
+  HDRS
+    truncsfhf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.src.__support.CPP.bit
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+  truncdfhf2
+  HDRS
+    truncdfhf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.src.__support.CPP.bit
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+  trunctfhf2
+  HDRS
+    trunctfhf2.h
+  DEPENDS
+    libc.hdr.stdint_proxy
+    libc.include.llvm-libc-types.float128
+    libc.src.__support.CPP.bit
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
diff --git a/libc/src/__support/builtins/extendhfdf2.h b/libc/src/__support/builtins/extendhfdf2.h
new file mode 100644
index 0000000000000..36e747dc8112c
--- /dev/null
+++ b/libc/src/__support/builtins/extendhfdf2.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __extendhfdf2 implementation as
+/// builtins::extendhfdf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFDF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFDF2_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Extend float16 to double; mirrors compiler-rt's __extendhfdf2.
+LIBC_INLINE double extendhfdf2(uint16_t bits) {
+  return fpconvert_from_bits<double, float16>(bits);
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFDF2_H
diff --git a/libc/src/__support/builtins/extendhfsf2.h b/libc/src/__support/builtins/extendhfsf2.h
new file mode 100644
index 0000000000000..aa24e939c8767
--- /dev/null
+++ b/libc/src/__support/builtins/extendhfsf2.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __extendhfsf2 implementation as
+/// builtins::extendhfsf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFSF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFSF2_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Extend float16 to float; mirrors compiler-rt's __extendhfsf2.
+LIBC_INLINE float extendhfsf2(uint16_t bits) {
+  return fpconvert_from_bits<float, float16>(bits);
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFSF2_H
diff --git a/libc/src/__support/builtins/extendhftf2.h b/libc/src/__support/builtins/extendhftf2.h
new file mode 100644
index 0000000000000..54f34b57d7ba2
--- /dev/null
+++ b/libc/src/__support/builtins/extendhftf2.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __extendhftf2 implementation as
+/// builtins::extendhftf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFTF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFTF2_H
+
+#include "include/llvm-libc-types/float128.h"
+#include "src/__support/macros/properties/types.h"
+
+#if defined(LIBC_TYPES_HAS_FLOAT128) && defined(LIBC_TYPES_HAS_FLOAT16)
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Extend float16 to float128; mirrors compiler-rt's __extendhftf2.
+LIBC_INLINE float128 extendhftf2(uint16_t bits) {
+  return fpconvert_from_bits<float128, float16>(bits);
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFTF2_H
diff --git a/libc/src/__support/builtins/fpconvert_helper.h b/libc/src/__support/builtins/fpconvert_helper.h
index f892bc4d2a1ce..2067f1bf0bebb 100644
--- a/libc/src/__support/builtins/fpconvert_helper.h
+++ b/libc/src/__support/builtins/fpconvert_helper.h
@@ -17,6 +17,7 @@
 #define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FPCONVERT_HELPER_H
 
 #include "hdr/fenv_macros.h"
+#include "hdr/stdint_proxy.h"
 #include "src/__support/CPP/algorithm.h"
 #include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/type_traits.h"
@@ -42,9 +43,14 @@ namespace builtins {
 // Convert the floating-point value x from From to To (extend or truncate).
 // Narrowing rounds to nearest, ties to even; mirrors compiler-rt __extend* /
 // __trunc*.
-template <typename To, typename From>
-LIBC_INLINE constexpr To fpconvert(From x) {
-  using FromBits = fputil::FPBits<From>;
+namespace internal {
+
+// Shared conversion body, taking the source as FPBits.  FPBits is backed by an
+// unsigned integer (uint16_t for the 16-bit floats), so passing it -- rather
+// than a From value -- keeps clang from emitting a circular __extendhfsf2 for a
+// float16 argument (see the TODO above).
+template <typename To, typename FromBits>
+LIBC_INLINE constexpr To fpconvert(FromBits x_bits) {
   using ToBits = fputil::FPBits<To>;
   using ToStorageType = typename ToBits::StorageType;
 
@@ -69,14 +75,31 @@ LIBC_INLINE constexpr To fpconvert(From x) {
   if (x_bits.is_inf())
     return ToBits::inf(x_bits.sign()).get_val();
 
-  // Zero and subnormals fall through: DyadicFloat(x) gives a zero mantissa for
+  // Zero and subnormals fall through: DyadicFloat gives a zero mantissa for
   // zero, which as<To>() maps back to a correctly-signed zero.
   constexpr size_t MAX_FRACTION_LEN =
       cpp::max(ToBits::FRACTION_LEN, FromBits::FRACTION_LEN);
-  fputil::DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x);
+  fputil::DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x_bits.get_val());
   return xd.template as<To, /*ShouldSignalExceptions=*/true>();
 }
 
+} // namespace internal
+
+// Convert a floating-point value from From to To (extend or truncate).
+template <typename To, typename From>
+LIBC_INLINE constexpr To fpconvert(From x) {
+  return internal::fpconvert<To>(fputil::FPBits<From>(x));
+}
+
+// Same, for a float16/bfloat16 source delivered as raw bits.  Reconstructing
+// the value here (instead of taking a From parameter) avoids clang's _Float16
+// ABI lowering, which would emit a circular __extendhfsf2.
+template <typename To, typename From>
+LIBC_INLINE constexpr To fpconvert_from_bits(uint16_t bits) {
+  return internal::fpconvert<To>(
+      fputil::FPBits<From>(cpp::bit_cast<From>(bits)));
+}
+
 } // namespace builtins
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/__support/builtins/truncdfhf2.h b/libc/src/__support/builtins/truncdfhf2.h
new file mode 100644
index 0000000000000..af2506b1a93c8
--- /dev/null
+++ b/libc/src/__support/builtins/truncdfhf2.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __truncdfhf2 implementation as
+/// builtins::truncdfhf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFHF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFHF2_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate double to float16; mirrors compiler-rt's __truncdfhf2.
+LIBC_INLINE uint16_t truncdfhf2(double x) {
+  return cpp::bit_cast<uint16_t>(fputil::cast<float16>(x));
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFHF2_H
diff --git a/libc/src/__support/builtins/truncsfhf2.h b/libc/src/__support/builtins/truncsfhf2.h
new file mode 100644
index 0000000000000..a323e7ee76acf
--- /dev/null
+++ b/libc/src/__support/builtins/truncsfhf2.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __truncsfhf2 implementation as
+/// builtins::truncsfhf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCSFHF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCSFHF2_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate float to float16; mirrors compiler-rt's __truncsfhf2.
+LIBC_INLINE uint16_t truncsfhf2(float x) {
+  return cpp::bit_cast<uint16_t>(fputil::cast<float16>(x));
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCSFHF2_H
diff --git a/libc/src/__support/builtins/trunctfhf2.h b/libc/src/__support/builtins/trunctfhf2.h
new file mode 100644
index 0000000000000..db9790a5f3ea1
--- /dev/null
+++ b/libc/src/__support/builtins/trunctfhf2.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This header exposes LLVM-libc's __trunctfhf2 implementation as
+/// builtins::trunctfhf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFHF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFHF2_H
+
+#include "include/llvm-libc-types/float128.h"
+#include "src/__support/macros/properties/types.h"
+
+#if defined(LIBC_TYPES_HAS_FLOAT128) && defined(LIBC_TYPES_HAS_FLOAT16)
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate float128 to float16; mirrors compiler-rt's __trunctfhf2.
+LIBC_INLINE uint16_t trunctfhf2(float128 x) {
+  return cpp::bit_cast<uint16_t>(fputil::cast<float16>(x));
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFHF2_H
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 22a6d09eb6369..270b203298527 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -836,6 +836,9 @@ add_fp_unittest(
     libc.src.__support.builtins.divtf3
     libc.src.__support.builtins.extendbfsf2
     libc.src.__support.builtins.extenddftf2
+    libc.src.__support.builtins.extendhfdf2
+    libc.src.__support.builtins.extendhfsf2
+    libc.src.__support.builtins.extendhftf2
     libc.src.__support.builtins.extendsfdf2
     libc.src.__support.builtins.extendsftf2
     libc.src.__support.builtins.extendxftf2
@@ -860,10 +863,13 @@ add_fp_unittest(
     libc.src.__support.builtins.subsf3
     libc.src.__support.builtins.subtf3
     libc.src.__support.builtins.truncdfbf2
+    libc.src.__support.builtins.truncdfhf2
     libc.src.__support.builtins.truncdfsf2
     libc.src.__support.builtins.truncsfbf2
+    libc.src.__support.builtins.truncsfhf2
     libc.src.__support.builtins.trunctfbf2
     libc.src.__support.builtins.trunctfdf2
+    libc.src.__support.builtins.trunctfhf2
     libc.src.__support.builtins.trunctfsf2
     libc.src.__support.builtins.trunctfxf2
     libc.src.__support.uint128

>From 44ca797ec7eb93294a4c350376f40df1f7c109be Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Fri, 24 Jul 2026 21:23:48 +0300
Subject: [PATCH 4/7] Revert "[compiler-rt][builtins] libc-backed bfloat16
 extend/truncate builtins"

This reverts commit 60fa6676d3538ed4d6ece4cf3d3e9406fe882e11.
---
 compiler-rt/lib/builtins/CMakeLists.txt   |  4 ---
 compiler-rt/lib/builtins/extendbfsf2.cpp  | 24 --------------
 compiler-rt/lib/builtins/truncdfbf2.cpp   | 24 --------------
 compiler-rt/lib/builtins/truncsfbf2.cpp   | 24 --------------
 compiler-rt/lib/builtins/trunctfbf2.cpp   | 29 -----------------
 libc/shared/builtins.h                    |  6 ----
 libc/shared/builtins/extendbfsf2.h        | 29 -----------------
 libc/shared/builtins/truncdfbf2.h         | 29 -----------------
 libc/shared/builtins/truncsfbf2.h         | 29 -----------------
 libc/shared/builtins/trunctfbf2.h         | 35 --------------------
 libc/src/__support/builtins/extendbfsf2.h | 35 --------------------
 libc/src/__support/builtins/truncdfbf2.h  | 33 -------------------
 libc/src/__support/builtins/truncsfbf2.h  | 33 -------------------
 libc/src/__support/builtins/trunctfbf2.h  | 39 -----------------------
 libc/test/shared/CMakeLists.txt           |  2 +-
 libc/test/shared/shared_builtins_test.cpp |  6 ----
 16 files changed, 1 insertion(+), 380 deletions(-)
 delete mode 100644 compiler-rt/lib/builtins/extendbfsf2.cpp
 delete mode 100644 compiler-rt/lib/builtins/truncdfbf2.cpp
 delete mode 100644 compiler-rt/lib/builtins/truncsfbf2.cpp
 delete mode 100644 compiler-rt/lib/builtins/trunctfbf2.cpp
 delete mode 100644 libc/shared/builtins/extendbfsf2.h
 delete mode 100644 libc/shared/builtins/truncdfbf2.h
 delete mode 100644 libc/shared/builtins/truncsfbf2.h
 delete mode 100644 libc/shared/builtins/trunctfbf2.h
 delete mode 100644 libc/src/__support/builtins/extendbfsf2.h
 delete mode 100644 libc/src/__support/builtins/truncdfbf2.h
 delete mode 100644 libc/src/__support/builtins/truncsfbf2.h
 delete mode 100644 libc/src/__support/builtins/trunctfbf2.h

diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index 8a35fe3cdac23..71fc2de77a75e 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -291,7 +291,6 @@ if(COMPILER_RT_USE_LIBC_MATH)
   use_libc_builtin(GENERIC_SOURCES    divdf3)
   use_libc_builtin(GENERIC_SOURCES    divsf3)
   use_libc_builtin(GENERIC_TF_SOURCES divtf3)
-  use_libc_builtin(BF16_SOURCES       extendbfsf2)
   use_libc_builtin(GENERIC_TF_SOURCES extenddftf2)
   use_libc_builtin(GENERIC_SOURCES    extendhfsf2)
   use_libc_builtin(GENERIC_SOURCES    extendhfdf2)
@@ -320,9 +319,6 @@ if(COMPILER_RT_USE_LIBC_MATH)
   use_libc_builtin(GENERIC_SOURCES    subsf3)
   use_libc_builtin(GENERIC_TF_SOURCES subtf3)
   use_libc_builtin(GENERIC_SOURCES    truncdfsf2)  
-  use_libc_builtin(BF16_SOURCES       truncdfbf2)
-  use_libc_builtin(BF16_SOURCES       truncsfbf2)
-  use_libc_builtin(BF16_SOURCES       trunctfbf2)
   use_libc_builtin(GENERIC_TF_SOURCES trunctfdf2)
   use_libc_builtin(GENERIC_SOURCES    truncsfhf2)
   use_libc_builtin(GENERIC_SOURCES    truncdfhf2)
diff --git a/compiler-rt/lib/builtins/extendbfsf2.cpp b/compiler-rt/lib/builtins/extendbfsf2.cpp
deleted file mode 100644
index 74c56803d5c65..0000000000000
--- a/compiler-rt/lib/builtins/extendbfsf2.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file implements compiler-rt's __extendbfsf2, extend bfloat16 to float,
-/// on top of LLVM-libc's shared::extendbfsf2.
-///
-//===----------------------------------------------------------------------===//
-
-#define SRC_BFLOAT16
-#define DST_SINGLE
-#include "fp_extend.h"
-
-#include "fp_libc_config.h"
-#include "shared/builtins/extendbfsf2.h"
-
-extern "C" COMPILER_RT_ABI dst_t __extendbfsf2(src_t a) {
-  return LIBC_NAMESPACE::shared::extendbfsf2(__builtin_bit_cast(uint16_t, a));
-}
diff --git a/compiler-rt/lib/builtins/truncdfbf2.cpp b/compiler-rt/lib/builtins/truncdfbf2.cpp
deleted file mode 100644
index a5ae505b03553..0000000000000
--- a/compiler-rt/lib/builtins/truncdfbf2.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file implements compiler-rt's __truncdfbf2, truncate double to
-/// bfloat16, on top of LLVM-libc's shared::truncdfbf2.
-///
-//===----------------------------------------------------------------------===//
-
-#define SRC_DOUBLE
-#define DST_BFLOAT
-#include "fp_trunc.h"
-
-#include "fp_libc_config.h"
-#include "shared/builtins/truncdfbf2.h"
-
-extern "C" COMPILER_RT_ABI dst_t __truncdfbf2(src_t a) {
-  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncdfbf2(a));
-}
diff --git a/compiler-rt/lib/builtins/truncsfbf2.cpp b/compiler-rt/lib/builtins/truncsfbf2.cpp
deleted file mode 100644
index 91011f086ad85..0000000000000
--- a/compiler-rt/lib/builtins/truncsfbf2.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file implements compiler-rt's __truncsfbf2, truncate float to bfloat16,
-/// on top of LLVM-libc's shared::truncsfbf2.
-///
-//===----------------------------------------------------------------------===//
-
-#define SRC_SINGLE
-#define DST_BFLOAT
-#include "fp_trunc.h"
-
-#include "fp_libc_config.h"
-#include "shared/builtins/truncsfbf2.h"
-
-extern "C" COMPILER_RT_ABI dst_t __truncsfbf2(src_t a) {
-  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncsfbf2(a));
-}
diff --git a/compiler-rt/lib/builtins/trunctfbf2.cpp b/compiler-rt/lib/builtins/trunctfbf2.cpp
deleted file mode 100644
index d789111907fd3..0000000000000
--- a/compiler-rt/lib/builtins/trunctfbf2.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file implements compiler-rt's __trunctfbf2, truncate float128 to
-/// bfloat16, on top of LLVM-libc's shared::trunctfbf2.
-///
-//===----------------------------------------------------------------------===//
-
-#define QUAD_PRECISION
-#include "fp_lib.h"
-
-#include "fp_libc_config.h"
-#include "shared/builtins/trunctfbf2.h"
-
-#if defined(CRT_HAS_TF_MODE) && defined(__x86_64__)
-#define SRC_QUAD
-#define DST_BFLOAT
-#include "fp_trunc.h"
-
-extern "C" COMPILER_RT_ABI dst_t __trunctfbf2(src_t a) {
-  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::trunctfbf2(a));
-}
-#endif
diff --git a/libc/shared/builtins.h b/libc/shared/builtins.h
index dea8058f73dec..8511f967bbcaa 100644
--- a/libc/shared/builtins.h
+++ b/libc/shared/builtins.h
@@ -23,7 +23,6 @@
 #include "builtins/divdf3.h"
 #include "builtins/divsf3.h"
 #include "builtins/divtf3.h"
-#include "builtins/extendbfsf2.h"
 #include "builtins/extenddftf2.h"
 #include "builtins/extendhfdf2.h"
 #include "builtins/extendhfsf2.h"
@@ -51,12 +50,7 @@
 #include "builtins/subdf3.h"
 #include "builtins/subsf3.h"
 #include "builtins/subtf3.h"
-#include "builtins/truncdfbf2.h"
-#include "builtins/truncdfhf2.h"
 #include "builtins/truncdfsf2.h"
-#include "builtins/truncsfbf2.h"
-#include "builtins/truncsfhf2.h"
-#include "builtins/trunctfbf2.h"
 #include "builtins/trunctfdf2.h"
 #include "builtins/trunctfhf2.h"
 #include "builtins/trunctfsf2.h"
diff --git a/libc/shared/builtins/extendbfsf2.h b/libc/shared/builtins/extendbfsf2.h
deleted file mode 100644
index f660301a5e31c..0000000000000
--- a/libc/shared/builtins/extendbfsf2.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This header exposes LLVM-libc's __extendbfsf2 implementation as
-/// shared::extendbfsf2 so that it can be reused by compiler-rt's builtins.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDBFSF2_H
-#define LLVM_LIBC_SHARED_BUILTINS_EXTENDBFSF2_H
-
-#include "shared/libc_common.h"
-#include "src/__support/builtins/extendbfsf2.h"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace shared {
-
-using builtins::extendbfsf2;
-
-} // namespace shared
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDBFSF2_H
diff --git a/libc/shared/builtins/truncdfbf2.h b/libc/shared/builtins/truncdfbf2.h
deleted file mode 100644
index 2846c484fa813..0000000000000
--- a/libc/shared/builtins/truncdfbf2.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This header exposes LLVM-libc's __truncdfbf2 implementation as
-/// shared::truncdfbf2 so that it can be reused by compiler-rt's builtins.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCDFBF2_H
-#define LLVM_LIBC_SHARED_BUILTINS_TRUNCDFBF2_H
-
-#include "shared/libc_common.h"
-#include "src/__support/builtins/truncdfbf2.h"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace shared {
-
-using builtins::truncdfbf2;
-
-} // namespace shared
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCDFBF2_H
diff --git a/libc/shared/builtins/truncsfbf2.h b/libc/shared/builtins/truncsfbf2.h
deleted file mode 100644
index 93f4bfb256f84..0000000000000
--- a/libc/shared/builtins/truncsfbf2.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This header exposes LLVM-libc's __truncsfbf2 implementation as
-/// shared::truncsfbf2 so that it can be reused by compiler-rt's builtins.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCSFBF2_H
-#define LLVM_LIBC_SHARED_BUILTINS_TRUNCSFBF2_H
-
-#include "shared/libc_common.h"
-#include "src/__support/builtins/truncsfbf2.h"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace shared {
-
-using builtins::truncsfbf2;
-
-} // namespace shared
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCSFBF2_H
diff --git a/libc/shared/builtins/trunctfbf2.h b/libc/shared/builtins/trunctfbf2.h
deleted file mode 100644
index 76aca0aa13565..0000000000000
--- a/libc/shared/builtins/trunctfbf2.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This header exposes LLVM-libc's __trunctfbf2 implementation as
-/// shared::trunctfbf2 so that it can be reused by compiler-rt's builtins.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCTFBF2_H
-#define LLVM_LIBC_SHARED_BUILTINS_TRUNCTFBF2_H
-
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
-#include "shared/libc_common.h"
-#include "src/__support/builtins/trunctfbf2.h"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace shared {
-
-using builtins::trunctfbf2;
-
-} // namespace shared
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LIBC_TYPES_HAS_FLOAT128
-
-#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCTFBF2_H
diff --git a/libc/src/__support/builtins/extendbfsf2.h b/libc/src/__support/builtins/extendbfsf2.h
deleted file mode 100644
index 1ce0009a71055..0000000000000
--- a/libc/src/__support/builtins/extendbfsf2.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This header exposes LLVM-libc's __extendbfsf2 implementation as
-/// builtins::extendbfsf2 so that it can be reused by compiler-rt's builtins.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDBFSF2_H
-#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDBFSF2_H
-
-#include "hdr/stdint_proxy.h"
-#include "src/__support/FPUtil/bfloat16.h"
-#include "src/__support/macros/config.h"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace builtins {
-
-// Extend bfloat16 to float; mirrors compiler-rt's __extendbfsf2.
-LIBC_INLINE float extendbfsf2(uint16_t bits) {
-  bfloat16 x;
-  x.bits = bits;
-  return fputil::cast<float>(x);
-}
-
-} // namespace builtins
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDBFSF2_H
diff --git a/libc/src/__support/builtins/truncdfbf2.h b/libc/src/__support/builtins/truncdfbf2.h
deleted file mode 100644
index 4bccb2db9de6d..0000000000000
--- a/libc/src/__support/builtins/truncdfbf2.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This header exposes LLVM-libc's __truncdfbf2 implementation as
-/// builtins::truncdfbf2 so that it can be reused by compiler-rt's builtins.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFBF2_H
-#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFBF2_H
-
-#include "hdr/stdint_proxy.h"
-#include "src/__support/FPUtil/bfloat16.h"
-#include "src/__support/macros/config.h"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace builtins {
-
-// Truncate double to bfloat16; mirrors compiler-rt's __truncdfbf2.
-LIBC_INLINE uint16_t truncdfbf2(double x) {
-  return fputil::cast<bfloat16>(x).bits;
-}
-
-} // namespace builtins
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFBF2_H
diff --git a/libc/src/__support/builtins/truncsfbf2.h b/libc/src/__support/builtins/truncsfbf2.h
deleted file mode 100644
index 08611f20fb2a2..0000000000000
--- a/libc/src/__support/builtins/truncsfbf2.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This header exposes LLVM-libc's __truncsfbf2 implementation as
-/// builtins::truncsfbf2 so that it can be reused by compiler-rt's builtins.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCSFBF2_H
-#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCSFBF2_H
-
-#include "hdr/stdint_proxy.h"
-#include "src/__support/FPUtil/bfloat16.h"
-#include "src/__support/macros/config.h"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace builtins {
-
-// Truncate float to bfloat16; mirrors compiler-rt's __truncsfbf2.
-LIBC_INLINE uint16_t truncsfbf2(float x) {
-  return fputil::cast<bfloat16>(x).bits;
-}
-
-} // namespace builtins
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCSFBF2_H
diff --git a/libc/src/__support/builtins/trunctfbf2.h b/libc/src/__support/builtins/trunctfbf2.h
deleted file mode 100644
index 99e2833c39058..0000000000000
--- a/libc/src/__support/builtins/trunctfbf2.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This header exposes LLVM-libc's __trunctfbf2 implementation as
-/// builtins::trunctfbf2 so that it can be reused by compiler-rt's builtins.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFBF2_H
-#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFBF2_H
-
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
-#include "hdr/stdint_proxy.h"
-#include "src/__support/FPUtil/bfloat16.h"
-#include "src/__support/macros/config.h"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace builtins {
-
-// Truncate float128 to bfloat16; mirrors compiler-rt's __trunctfbf2.
-LIBC_INLINE uint16_t trunctfbf2(float128 x) {
-  return fputil::cast<bfloat16>(x).bits;
-}
-
-} // namespace builtins
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LIBC_TYPES_HAS_FLOAT128
-
-#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFBF2_H
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 270b203298527..8bad2ab78fe97 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -834,7 +834,6 @@ add_fp_unittest(
     libc.src.__support.builtins.divdf3
     libc.src.__support.builtins.divsf3
     libc.src.__support.builtins.divtf3
-    libc.src.__support.builtins.extendbfsf2
     libc.src.__support.builtins.extenddftf2
     libc.src.__support.builtins.extendhfdf2
     libc.src.__support.builtins.extendhfsf2
@@ -868,6 +867,7 @@ add_fp_unittest(
     libc.src.__support.builtins.truncsfbf2
     libc.src.__support.builtins.truncsfhf2
     libc.src.__support.builtins.trunctfbf2
+    libc.src.__support.builtins.truncdfsf2
     libc.src.__support.builtins.trunctfdf2
     libc.src.__support.builtins.trunctfhf2
     libc.src.__support.builtins.trunctfsf2
diff --git a/libc/test/shared/shared_builtins_test.cpp b/libc/test/shared/shared_builtins_test.cpp
index dc7847dbb01a0..1046dd6a0e1d8 100644
--- a/libc/test/shared/shared_builtins_test.cpp
+++ b/libc/test/shared/shared_builtins_test.cpp
@@ -46,7 +46,6 @@ TEST(LlvmLibcSharedBuiltinsTest, QuadPrecisionArithmtic) {
 
 TEST(LlvmLibcSharedBuiltinsTest, ExtendConversion) {
   EXPECT_FP_EQ(1.5, shared::extendsfdf2(1.5f));
-  EXPECT_FP_EQ(1.5f, shared::extendbfsf2(static_cast<uint16_t>(0x3FC0)));
 #ifdef LIBC_TYPES_HAS_FLOAT128
   EXPECT_FP_EQ(float128(1.5), shared::extenddftf2(1.5));
   EXPECT_FP_EQ(float128(1.5), shared::extendsftf2(1.5f));
@@ -58,12 +57,7 @@ TEST(LlvmLibcSharedBuiltinsTest, ExtendConversion) {
 }
 
 TEST(LlvmLibcSharedBuiltinsTest, TruncateConversion) {
-  EXPECT_EQ(static_cast<uint16_t>(0x3FC0), shared::truncdfbf2(1.5));
   EXPECT_FP_EQ(1.5f, shared::truncdfsf2(1.5));
-  EXPECT_EQ(static_cast<uint16_t>(0x3FC0), shared::truncsfbf2(1.5f));
-#ifdef LIBC_TYPES_HAS_FLOAT128
-  EXPECT_EQ(static_cast<uint16_t>(0x3FC0), shared::trunctfbf2(float128(1.5)));
-#endif // LIBC_TYPES_HAS_FLOAT128
 #ifdef LIBC_TYPES_HAS_FLOAT128
   EXPECT_FP_EQ(1.5, shared::trunctfdf2(float128(1.5)));
   EXPECT_FP_EQ(1.5f, shared::trunctfsf2(float128(1.5)));

>From 481ebe8cf15b56f369b408b115b619f56f6350ea Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 1 Aug 2026 22:48:53 +0300
Subject: [PATCH 5/7] fix conflict issue

---
 libc/src/__support/builtins/fpconvert_helper.h | 17 +++++++++--------
 libc/test/shared/shared_builtins_test.cpp      |  4 ----
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/libc/src/__support/builtins/fpconvert_helper.h b/libc/src/__support/builtins/fpconvert_helper.h
index 2067f1bf0bebb..b0c194986b328 100644
--- a/libc/src/__support/builtins/fpconvert_helper.h
+++ b/libc/src/__support/builtins/fpconvert_helper.h
@@ -54,11 +54,6 @@ LIBC_INLINE constexpr To fpconvert(FromBits x_bits) {
   using ToBits = fputil::FPBits<To>;
   using ToStorageType = typename ToBits::StorageType;
 
-  FromBits x_bits(x);
-
-  if constexpr (cpp::is_same_v<To, From>)
-    return x;
-
   if (x_bits.is_nan()) {
     typename FromBits::StorageType x_frac = x_bits.get_mantissa();
     if constexpr (ToBits::FRACTION_LEN >= FromBits::FRACTION_LEN) {
@@ -88,7 +83,10 @@ LIBC_INLINE constexpr To fpconvert(FromBits x_bits) {
 // Convert a floating-point value from From to To (extend or truncate).
 template <typename To, typename From>
 LIBC_INLINE constexpr To fpconvert(From x) {
-  return internal::fpconvert<To>(fputil::FPBits<From>(x));
+  if constexpr (cpp::is_same_v<To, From>)
+    return x;
+  else
+    return internal::fpconvert<To>(fputil::FPBits<From>(x));
 }
 
 // Same, for a float16/bfloat16 source delivered as raw bits.  Reconstructing
@@ -96,8 +94,11 @@ LIBC_INLINE constexpr To fpconvert(From x) {
 // ABI lowering, which would emit a circular __extendhfsf2.
 template <typename To, typename From>
 LIBC_INLINE constexpr To fpconvert_from_bits(uint16_t bits) {
-  return internal::fpconvert<To>(
-      fputil::FPBits<From>(cpp::bit_cast<From>(bits)));
+  if constexpr (cpp::is_same_v<To, From>)
+    return cpp::bit_cast<To>(bits);
+  else
+    return internal::fpconvert<To>(
+        fputil::FPBits<From>(cpp::bit_cast<From>(bits)));
 }
 
 } // namespace builtins
diff --git a/libc/test/shared/shared_builtins_test.cpp b/libc/test/shared/shared_builtins_test.cpp
index 1046dd6a0e1d8..2fed54ff00f05 100644
--- a/libc/test/shared/shared_builtins_test.cpp
+++ b/libc/test/shared/shared_builtins_test.cpp
@@ -19,10 +19,6 @@ TEST(LlvmLibcSharedBuiltinsTest, SinglePrecisionArithmtic) {
   EXPECT_FP_EQ(6.0f, shared::mulsf3(2.0f, 3.0f));
   EXPECT_FP_EQ(-5.0, shared::negsf2(5.0));
   EXPECT_FP_EQ(2.0f, shared::subsf3(5.0f, 3.0f));
-namespace shared = LIBC_NAMESPACE::shared;
-
-TEST(LlvmLibcSharedBuiltinsTest, AllFloat) {
-  // TODO: assertions for shared::*sf3 builtins.
 }
 
 TEST(LlvmLibcSharedBuiltinsTest, DoublePrecisionArithmtic) {

>From 7e79d5895e19ff2272b126f70bf24f8440091e10 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Thu, 6 Aug 2026 20:40:32 +0300
Subject: [PATCH 6/7] if defined -> ifdef

---
 compiler-rt/lib/builtins/extendhfdf2.cpp | 2 +-
 compiler-rt/lib/builtins/extendhfsf2.cpp | 2 +-
 compiler-rt/lib/builtins/extendhftf2.cpp | 2 +-
 compiler-rt/lib/builtins/truncdfhf2.cpp  | 2 +-
 compiler-rt/lib/builtins/truncsfhf2.cpp  | 2 +-
 compiler-rt/lib/builtins/trunctfhf2.cpp  | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/compiler-rt/lib/builtins/extendhfdf2.cpp b/compiler-rt/lib/builtins/extendhfdf2.cpp
index f1d40971b7f45..b7ad3985a833a 100644
--- a/compiler-rt/lib/builtins/extendhfdf2.cpp
+++ b/compiler-rt/lib/builtins/extendhfdf2.cpp
@@ -19,7 +19,7 @@
 #include "fp_libc_config.h"
 #include "shared/builtins/extendhfdf2.h"
 
-#if defined(LIBC_TYPES_HAS_FLOAT16)
+#ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfdf2(src_t a) {
   return LIBC_NAMESPACE::shared::extendhfdf2(__builtin_bit_cast(uint16_t, a));
 }
diff --git a/compiler-rt/lib/builtins/extendhfsf2.cpp b/compiler-rt/lib/builtins/extendhfsf2.cpp
index 6dc3ef17c22d5..7ab490ae39f52 100644
--- a/compiler-rt/lib/builtins/extendhfsf2.cpp
+++ b/compiler-rt/lib/builtins/extendhfsf2.cpp
@@ -19,7 +19,7 @@
 #include "fp_libc_config.h"
 #include "shared/builtins/extendhfsf2.h"
 
-#if defined(LIBC_TYPES_HAS_FLOAT16)
+#ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfsf2(src_t a) {
   return LIBC_NAMESPACE::shared::extendhfsf2(__builtin_bit_cast(uint16_t, a));
 }
diff --git a/compiler-rt/lib/builtins/extendhftf2.cpp b/compiler-rt/lib/builtins/extendhftf2.cpp
index 2b035ee639b22..219e1d1ec33d4 100644
--- a/compiler-rt/lib/builtins/extendhftf2.cpp
+++ b/compiler-rt/lib/builtins/extendhftf2.cpp
@@ -23,7 +23,7 @@
 #define DST_QUAD
 #include "fp_extend_impl.inc"
 
-#if defined(LIBC_TYPES_HAS_FLOAT16)
+#ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI dst_t __extendhftf2(src_t a) {
   return LIBC_NAMESPACE::shared::extendhftf2(__builtin_bit_cast(uint16_t, a));
 }
diff --git a/compiler-rt/lib/builtins/truncdfhf2.cpp b/compiler-rt/lib/builtins/truncdfhf2.cpp
index ab08483cdabfa..4f58283888c96 100644
--- a/compiler-rt/lib/builtins/truncdfhf2.cpp
+++ b/compiler-rt/lib/builtins/truncdfhf2.cpp
@@ -19,7 +19,7 @@
 #include "fp_libc_config.h"
 #include "shared/builtins/truncdfhf2.h"
 
-#if defined(LIBC_TYPES_HAS_FLOAT16)
+#ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI dst_t __truncdfhf2(src_t a) {
   return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncdfhf2(a));
 }
diff --git a/compiler-rt/lib/builtins/truncsfhf2.cpp b/compiler-rt/lib/builtins/truncsfhf2.cpp
index 3fa614d2970fe..3e6b82a18ff22 100644
--- a/compiler-rt/lib/builtins/truncsfhf2.cpp
+++ b/compiler-rt/lib/builtins/truncsfhf2.cpp
@@ -19,7 +19,7 @@
 #include "fp_libc_config.h"
 #include "shared/builtins/truncsfhf2.h"
 
-#if defined(LIBC_TYPES_HAS_FLOAT16)
+#ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI NOINLINE dst_t __truncsfhf2(src_t a) {
   return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncsfhf2(a));
 }
diff --git a/compiler-rt/lib/builtins/trunctfhf2.cpp b/compiler-rt/lib/builtins/trunctfhf2.cpp
index a1c06a9415229..b43cd8fba9f7a 100644
--- a/compiler-rt/lib/builtins/trunctfhf2.cpp
+++ b/compiler-rt/lib/builtins/trunctfhf2.cpp
@@ -23,7 +23,7 @@
 #define DST_HALF
 #include "fp_trunc_impl.inc"
 
-#if defined(LIBC_TYPES_HAS_FLOAT16)
+#ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI dst_t __trunctfhf2(src_t a) {
   return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::trunctfhf2(a));
 }

>From 0016edbba49868c8904a9e41c87ddcedbb8ea69f Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 8 Aug 2026 23:56:10 +0300
Subject: [PATCH 7/7] make float16 extend builtins independent of _Float16

---
 compiler-rt/lib/builtins/extendhfdf2.cpp      | 10 ++--
 compiler-rt/lib/builtins/extendhfsf2.cpp      | 10 ++--
 compiler-rt/lib/builtins/extendhftf2.cpp      | 10 ++--
 compiler-rt/lib/builtins/truncdfhf2.cpp       |  4 +-
 compiler-rt/lib/builtins/truncsfhf2.cpp       |  4 +-
 compiler-rt/lib/builtins/trunctfhf2.cpp       |  4 +-
 libc/shared/bit.h                             | 23 ++++++++
 libc/shared/builtins/extendhfdf2.h            |  6 ---
 libc/shared/builtins/extendhfsf2.h            |  6 ---
 libc/shared/builtins/extendhftf2.h            |  4 +-
 libc/src/__support/FPUtil/FPBits.h            |  3 ++
 libc/src/__support/builtins/extendhfdf2.h     |  9 +---
 libc/src/__support/builtins/extendhfsf2.h     |  9 +---
 libc/src/__support/builtins/extendhftf2.h     |  7 +--
 .../src/__support/builtins/fpconvert_helper.h | 54 ++++++++++---------
 15 files changed, 82 insertions(+), 81 deletions(-)
 create mode 100644 libc/shared/bit.h

diff --git a/compiler-rt/lib/builtins/extendhfdf2.cpp b/compiler-rt/lib/builtins/extendhfdf2.cpp
index b7ad3985a833a..095259358c613 100644
--- a/compiler-rt/lib/builtins/extendhfdf2.cpp
+++ b/compiler-rt/lib/builtins/extendhfdf2.cpp
@@ -17,14 +17,10 @@
 #include "fp_extend_impl.inc"
 
 #include "fp_libc_config.h"
+#include "shared/bit.h"
 #include "shared/builtins/extendhfdf2.h"
 
-#ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfdf2(src_t a) {
-  return LIBC_NAMESPACE::shared::extendhfdf2(__builtin_bit_cast(uint16_t, a));
+  return LIBC_NAMESPACE::shared::extendhfdf2(
+      LIBC_NAMESPACE::shared::bit_cast<uint16_t>(a));
 }
-#else
-extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfdf2(src_t a) {
-  return __extendXfYf2__(a);
-}
-#endif
diff --git a/compiler-rt/lib/builtins/extendhfsf2.cpp b/compiler-rt/lib/builtins/extendhfsf2.cpp
index 7ab490ae39f52..0bcc82058b11b 100644
--- a/compiler-rt/lib/builtins/extendhfsf2.cpp
+++ b/compiler-rt/lib/builtins/extendhfsf2.cpp
@@ -17,17 +17,13 @@
 #include "fp_extend_impl.inc"
 
 #include "fp_libc_config.h"
+#include "shared/bit.h"
 #include "shared/builtins/extendhfsf2.h"
 
-#ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfsf2(src_t a) {
-  return LIBC_NAMESPACE::shared::extendhfsf2(__builtin_bit_cast(uint16_t, a));
+  return LIBC_NAMESPACE::shared::extendhfsf2(
+      LIBC_NAMESPACE::shared::bit_cast<uint16_t>(a));
 }
-#else
-extern "C" COMPILER_RT_ABI NOINLINE dst_t __extendhfsf2(src_t a) {
-  return __extendXfYf2__(a);
-}
-#endif
 
 extern "C" {
 #if defined(__ARM_EABI__)
diff --git a/compiler-rt/lib/builtins/extendhftf2.cpp b/compiler-rt/lib/builtins/extendhftf2.cpp
index 219e1d1ec33d4..d7e3db737acaf 100644
--- a/compiler-rt/lib/builtins/extendhftf2.cpp
+++ b/compiler-rt/lib/builtins/extendhftf2.cpp
@@ -16,6 +16,7 @@
 #include "fp_lib.h"
 
 #include "fp_libc_config.h"
+#include "shared/bit.h"
 #include "shared/builtins/extendhftf2.h"
 
 #if defined(CRT_HAS_TF_MODE) && defined(COMPILER_RT_HAS_FLOAT16)
@@ -23,13 +24,8 @@
 #define DST_QUAD
 #include "fp_extend_impl.inc"
 
-#ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI dst_t __extendhftf2(src_t a) {
-  return LIBC_NAMESPACE::shared::extendhftf2(__builtin_bit_cast(uint16_t, a));
+  return LIBC_NAMESPACE::shared::extendhftf2(
+      LIBC_NAMESPACE::shared::bit_cast<uint16_t>(a));
 }
-#else
-extern "C" COMPILER_RT_ABI dst_t __extendhftf2(src_t a) {
-  return __extendXfYf2__(a);
-}
-#endif
 #endif
diff --git a/compiler-rt/lib/builtins/truncdfhf2.cpp b/compiler-rt/lib/builtins/truncdfhf2.cpp
index 4f58283888c96..77a93394b4ab6 100644
--- a/compiler-rt/lib/builtins/truncdfhf2.cpp
+++ b/compiler-rt/lib/builtins/truncdfhf2.cpp
@@ -17,11 +17,13 @@
 #include "fp_trunc_impl.inc"
 
 #include "fp_libc_config.h"
+#include "shared/bit.h"
 #include "shared/builtins/truncdfhf2.h"
 
 #ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI dst_t __truncdfhf2(src_t a) {
-  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncdfhf2(a));
+  return LIBC_NAMESPACE::shared::bit_cast<dst_t>(
+      LIBC_NAMESPACE::shared::truncdfhf2(a));
 }
 #else
 extern "C" COMPILER_RT_ABI dst_t __truncdfhf2(src_t a) {
diff --git a/compiler-rt/lib/builtins/truncsfhf2.cpp b/compiler-rt/lib/builtins/truncsfhf2.cpp
index 3e6b82a18ff22..b0ab659562ec9 100644
--- a/compiler-rt/lib/builtins/truncsfhf2.cpp
+++ b/compiler-rt/lib/builtins/truncsfhf2.cpp
@@ -17,11 +17,13 @@
 #include "fp_trunc_impl.inc"
 
 #include "fp_libc_config.h"
+#include "shared/bit.h"
 #include "shared/builtins/truncsfhf2.h"
 
 #ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI NOINLINE dst_t __truncsfhf2(src_t a) {
-  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::truncsfhf2(a));
+  return LIBC_NAMESPACE::shared::bit_cast<dst_t>(
+      LIBC_NAMESPACE::shared::truncsfhf2(a));
 }
 #else
 extern "C" COMPILER_RT_ABI NOINLINE dst_t __truncsfhf2(src_t a) {
diff --git a/compiler-rt/lib/builtins/trunctfhf2.cpp b/compiler-rt/lib/builtins/trunctfhf2.cpp
index b43cd8fba9f7a..a0a3f154edfb8 100644
--- a/compiler-rt/lib/builtins/trunctfhf2.cpp
+++ b/compiler-rt/lib/builtins/trunctfhf2.cpp
@@ -16,6 +16,7 @@
 #include "fp_lib.h"
 
 #include "fp_libc_config.h"
+#include "shared/bit.h"
 #include "shared/builtins/trunctfhf2.h"
 
 #if defined(CRT_HAS_TF_MODE) && defined(COMPILER_RT_HAS_FLOAT16)
@@ -25,7 +26,8 @@
 
 #ifdef LIBC_TYPES_HAS_FLOAT16
 extern "C" COMPILER_RT_ABI dst_t __trunctfhf2(src_t a) {
-  return __builtin_bit_cast(dst_t, LIBC_NAMESPACE::shared::trunctfhf2(a));
+  return LIBC_NAMESPACE::shared::bit_cast<dst_t>(
+      LIBC_NAMESPACE::shared::trunctfhf2(a));
 }
 #else
 extern "C" COMPILER_RT_ABI dst_t __trunctfhf2(src_t a) {
diff --git a/libc/shared/bit.h b/libc/shared/bit.h
new file mode 100644
index 0000000000000..57b5a0c8a8355
--- /dev/null
+++ b/libc/shared/bit.h
@@ -0,0 +1,23 @@
+//===-- Bit manipulation utils ----------------------------------*- 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_SHARED_BIT_H
+#define LLVM_LIBC_SHARED_BIT_H
+
+#include "libc_common.h"
+#include "src/__support/CPP/bit.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using cpp::bit_cast;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BIT_H
diff --git a/libc/shared/builtins/extendhfdf2.h b/libc/shared/builtins/extendhfdf2.h
index ebae43abfbf3b..e9eaaca15e114 100644
--- a/libc/shared/builtins/extendhfdf2.h
+++ b/libc/shared/builtins/extendhfdf2.h
@@ -15,10 +15,6 @@
 #ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDHFDF2_H
 #define LLVM_LIBC_SHARED_BUILTINS_EXTENDHFDF2_H
 
-#include "src/__support/macros/properties/types.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT16
-
 #include "shared/libc_common.h"
 #include "src/__support/builtins/extendhfdf2.h"
 
@@ -30,6 +26,4 @@ using builtins::extendhfdf2;
 } // namespace shared
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_FLOAT16
-
 #endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDHFDF2_H
diff --git a/libc/shared/builtins/extendhfsf2.h b/libc/shared/builtins/extendhfsf2.h
index 346961746bd52..cc31bc7bd6664 100644
--- a/libc/shared/builtins/extendhfsf2.h
+++ b/libc/shared/builtins/extendhfsf2.h
@@ -15,10 +15,6 @@
 #ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDHFSF2_H
 #define LLVM_LIBC_SHARED_BUILTINS_EXTENDHFSF2_H
 
-#include "src/__support/macros/properties/types.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT16
-
 #include "shared/libc_common.h"
 #include "src/__support/builtins/extendhfsf2.h"
 
@@ -30,6 +26,4 @@ using builtins::extendhfsf2;
 } // namespace shared
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_FLOAT16
-
 #endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDHFSF2_H
diff --git a/libc/shared/builtins/extendhftf2.h b/libc/shared/builtins/extendhftf2.h
index 28a3331fcfc5d..d6b8b2e4a966b 100644
--- a/libc/shared/builtins/extendhftf2.h
+++ b/libc/shared/builtins/extendhftf2.h
@@ -18,7 +18,7 @@
 #include "include/llvm-libc-types/float128.h"
 #include "src/__support/macros/properties/types.h"
 
-#if defined(LIBC_TYPES_HAS_FLOAT128) && defined(LIBC_TYPES_HAS_FLOAT16)
+#ifdef LIBC_TYPES_HAS_FLOAT128
 
 #include "shared/libc_common.h"
 #include "src/__support/builtins/extendhftf2.h"
@@ -31,6 +31,6 @@ using builtins::extendhftf2;
 } // namespace shared
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_HAS_FLOAT16
+#endif // LIBC_TYPES_HAS_FLOAT128
 
 #endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDHFTF2_H
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 83219b7573f46..7f9482dd76a27 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -786,6 +786,9 @@ struct FPRep : public FPRepImpl<fp_type, FPRep<fp_type>> {
 
 } // namespace internal
 
+// Like 'FPBits' but named by 'FPType', so no native C++ type need exist.
+template <FPType fp_type> using FPRep = internal::FPRep<fp_type>;
+
 // Returns the FPType corresponding to C++ type T on the host.
 template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
   using UnqualT = cpp::remove_cv_t<T>;
diff --git a/libc/src/__support/builtins/extendhfdf2.h b/libc/src/__support/builtins/extendhfdf2.h
index 36e747dc8112c..65eddd46338be 100644
--- a/libc/src/__support/builtins/extendhfdf2.h
+++ b/libc/src/__support/builtins/extendhfdf2.h
@@ -15,11 +15,8 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFDF2_H
 #define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFDF2_H
 
-#include "src/__support/macros/properties/types.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT16
-
 #include "hdr/stdint_proxy.h"
+#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/builtins/fpconvert_helper.h"
 #include "src/__support/macros/config.h"
 
@@ -28,12 +25,10 @@ namespace builtins {
 
 // Extend float16 to double; mirrors compiler-rt's __extendhfdf2.
 LIBC_INLINE double extendhfdf2(uint16_t bits) {
-  return fpconvert_from_bits<double, float16>(bits);
+  return fpconvert_from_bits<double, fputil::FPType::IEEE754_Binary16>(bits);
 }
 
 } // namespace builtins
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_FLOAT16
-
 #endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFDF2_H
diff --git a/libc/src/__support/builtins/extendhfsf2.h b/libc/src/__support/builtins/extendhfsf2.h
index aa24e939c8767..fc3636f1db314 100644
--- a/libc/src/__support/builtins/extendhfsf2.h
+++ b/libc/src/__support/builtins/extendhfsf2.h
@@ -15,11 +15,8 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFSF2_H
 #define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFSF2_H
 
-#include "src/__support/macros/properties/types.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT16
-
 #include "hdr/stdint_proxy.h"
+#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/builtins/fpconvert_helper.h"
 #include "src/__support/macros/config.h"
 
@@ -28,12 +25,10 @@ namespace builtins {
 
 // Extend float16 to float; mirrors compiler-rt's __extendhfsf2.
 LIBC_INLINE float extendhfsf2(uint16_t bits) {
-  return fpconvert_from_bits<float, float16>(bits);
+  return fpconvert_from_bits<float, fputil::FPType::IEEE754_Binary16>(bits);
 }
 
 } // namespace builtins
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_FLOAT16
-
 #endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFSF2_H
diff --git a/libc/src/__support/builtins/extendhftf2.h b/libc/src/__support/builtins/extendhftf2.h
index 54f34b57d7ba2..05e488a147c05 100644
--- a/libc/src/__support/builtins/extendhftf2.h
+++ b/libc/src/__support/builtins/extendhftf2.h
@@ -18,9 +18,10 @@
 #include "include/llvm-libc-types/float128.h"
 #include "src/__support/macros/properties/types.h"
 
-#if defined(LIBC_TYPES_HAS_FLOAT128) && defined(LIBC_TYPES_HAS_FLOAT16)
+#if defined(LIBC_TYPES_HAS_FLOAT128)
 
 #include "hdr/stdint_proxy.h"
+#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/builtins/fpconvert_helper.h"
 #include "src/__support/macros/config.h"
 
@@ -29,12 +30,12 @@ namespace builtins {
 
 // Extend float16 to float128; mirrors compiler-rt's __extendhftf2.
 LIBC_INLINE float128 extendhftf2(uint16_t bits) {
-  return fpconvert_from_bits<float128, float16>(bits);
+  return fpconvert_from_bits<float128, fputil::FPType::IEEE754_Binary16>(bits);
 }
 
 } // namespace builtins
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_HAS_FLOAT16
+#endif // LIBC_TYPES_HAS_FLOAT128
 
 #endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDHFTF2_H
diff --git a/libc/src/__support/builtins/fpconvert_helper.h b/libc/src/__support/builtins/fpconvert_helper.h
index b0c194986b328..ca7c61e187fab 100644
--- a/libc/src/__support/builtins/fpconvert_helper.h
+++ b/libc/src/__support/builtins/fpconvert_helper.h
@@ -45,25 +45,26 @@ namespace builtins {
 // __trunc*.
 namespace internal {
 
-// Shared conversion body, taking the source as FPBits.  FPBits is backed by an
-// unsigned integer (uint16_t for the 16-bit floats), so passing it -- rather
-// than a From value -- keeps clang from emitting a circular __extendhfsf2 for a
-// float16 argument (see the TODO above).
-template <typename To, typename FromBits>
-LIBC_INLINE constexpr To fpconvert(FromBits x_bits) {
+// Shared conversion body.  The source is named by FPType, so it needs no
+// native C++ type; only the destination does.
+template <typename To, fputil::FPType FromFPType>
+LIBC_INLINE constexpr To
+fpconvert(typename fputil::FPRep<FromFPType>::StorageType bits) {
+  using FromRep = fputil::FPRep<FromFPType>;
   using ToBits = fputil::FPBits<To>;
   using ToStorageType = typename ToBits::StorageType;
 
+  FromRep x_bits(bits);
+
   if (x_bits.is_nan()) {
-    typename FromBits::StorageType x_frac = x_bits.get_mantissa();
-    if constexpr (ToBits::FRACTION_LEN >= FromBits::FRACTION_LEN) {
-      ToStorageType to_frac =
-          static_cast<ToStorageType>(x_frac)
-          << (ToBits::FRACTION_LEN - FromBits::FRACTION_LEN);
+    typename FromRep::StorageType x_frac = x_bits.get_mantissa();
+    if constexpr (ToBits::FRACTION_LEN >= FromRep::FRACTION_LEN) {
+      ToStorageType to_frac = static_cast<ToStorageType>(x_frac)
+                              << (ToBits::FRACTION_LEN - FromRep::FRACTION_LEN);
       return ToBits::signaling_nan(x_bits.sign(), to_frac).get_val();
     }
     ToStorageType to_frac = static_cast<ToStorageType>(
-        x_frac >> (FromBits::FRACTION_LEN - ToBits::FRACTION_LEN));
+        x_frac >> (FromRep::FRACTION_LEN - ToBits::FRACTION_LEN));
     return ToBits::quiet_nan(x_bits.sign(), to_frac).get_val();
   }
 
@@ -71,10 +72,14 @@ LIBC_INLINE constexpr To fpconvert(FromBits x_bits) {
     return ToBits::inf(x_bits.sign()).get_val();
 
   // Zero and subnormals fall through: DyadicFloat gives a zero mantissa for
-  // zero, which as<To>() maps back to a correctly-signed zero.
+  // zero, which as<To>() maps back to a correctly-signed zero.  Built from
+  // parts so no From value is materialized.
   constexpr size_t MAX_FRACTION_LEN =
-      cpp::max(ToBits::FRACTION_LEN, FromBits::FRACTION_LEN);
-  fputil::DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x_bits.get_val());
+      cpp::max(ToBits::FRACTION_LEN, FromRep::FRACTION_LEN);
+  using DyadicType = fputil::DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)>;
+  DyadicType xd(
+      x_bits.sign(), x_bits.get_explicit_exponent() - FromRep::FRACTION_LEN,
+      typename DyadicType::MantissaType(x_bits.get_explicit_mantissa()));
   return xd.template as<To, /*ShouldSignalExceptions=*/true>();
 }
 
@@ -86,19 +91,16 @@ LIBC_INLINE constexpr To fpconvert(From x) {
   if constexpr (cpp::is_same_v<To, From>)
     return x;
   else
-    return internal::fpconvert<To>(fputil::FPBits<From>(x));
+    return internal::fpconvert<To, fputil::get_fp_type<From>()>(
+        cpp::bit_cast<typename fputil::FPBits<From>::StorageType>(x));
 }
 
-// Same, for a float16/bfloat16 source delivered as raw bits.  Reconstructing
-// the value here (instead of taking a From parameter) avoids clang's _Float16
-// ABI lowering, which would emit a circular __extendhfsf2.
-template <typename To, typename From>
-LIBC_INLINE constexpr To fpconvert_from_bits(uint16_t bits) {
-  if constexpr (cpp::is_same_v<To, From>)
-    return cpp::bit_cast<To>(bits);
-  else
-    return internal::fpconvert<To>(
-        fputil::FPBits<From>(cpp::bit_cast<From>(bits)));
+// Same, for a source delivered as raw bits.  Keeps _Float16 out of the
+// signature, which would otherwise lower to a circular __extendhfsf2.
+template <typename To, fputil::FPType FromFPType>
+LIBC_INLINE constexpr To
+fpconvert_from_bits(typename fputil::FPRep<FromFPType>::StorageType bits) {
+  return internal::fpconvert<To, FromFPType>(bits);
 }
 
 } // namespace builtins



More information about the libc-commits mailing list