[libc-commits] [libc] [llvm] [libc][math] Add tanhbf16 function (PR #227109)
via libc-commits
libc-commits at lists.llvm.org
Sun Oct 4 07:01:03 PDT 2026
https://github.com/mooofin updated https://github.com/llvm/llvm-project/pull/227109
>From 7aa00327a59cb237358eb731aff1d85fd642498f Mon Sep 17 00:00:00 2001
From: sid <siddharthqln at gmail.com>
Date: Tue, 29 Sep 2026 01:50:57 +0530
Subject: [PATCH 1/2] [libc][math] Add tanhbf16 function
---
libc/config/baremetal/aarch64/entrypoints.txt | 1 +
libc/config/baremetal/arm/entrypoints.txt | 1 +
libc/config/baremetal/riscv/entrypoints.txt | 1 +
libc/config/darwin/aarch64/entrypoints.txt | 1 +
libc/config/darwin/x86_64/entrypoints.txt | 1 +
libc/config/freebsd/x86_64/entrypoints.txt | 1 +
libc/config/gpu/amdgpu/entrypoints.txt | 1 +
libc/config/gpu/nvptx/entrypoints.txt | 1 +
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/arm/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/config/windows/entrypoints.txt | 1 +
libc/docs/headers/math/index.rst | 2 +-
libc/shared/math.h | 1 +
libc/shared/math/tanhbf16.h | 23 +++++
libc/src/__support/math/CMakeLists.txt | 16 ++++
libc/src/__support/math/tanhbf16.h | 85 +++++++++++++++++++
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/generic/CMakeLists.txt | 10 +++
libc/src/math/generic/tanhbf16.cpp | 19 +++++
libc/src/math/tanhbf16.h | 21 +++++
libc/test/shared/CMakeLists.txt | 1 +
libc/test/shared/shared_math_test.cpp | 1 +
libc/test/src/math/CMakeLists.txt | 13 +++
libc/test/src/math/smoke/CMakeLists.txt | 13 +++
libc/test/src/math/smoke/tanhbf16_test.cpp | 69 +++++++++++++++
libc/test/src/math/tanhbf16_test.cpp | 33 +++++++
.../llvm-project-overlay/libc/BUILD.bazel | 23 +++++
29 files changed, 343 insertions(+), 1 deletion(-)
create mode 100644 libc/shared/math/tanhbf16.h
create mode 100644 libc/src/__support/math/tanhbf16.h
create mode 100644 libc/src/math/generic/tanhbf16.cpp
create mode 100644 libc/src/math/tanhbf16.h
create mode 100644 libc/test/src/math/smoke/tanhbf16_test.cpp
create mode 100644 libc/test/src/math/tanhbf16_test.cpp
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 114534ce61ae6..ef8e23dd1f9e8 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -877,6 +877,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index c8148815c34e3..b28c8f13b12b6 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -888,6 +888,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 622d6156cff11..c8f092280afa5 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -880,6 +880,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index d702b2c5a6549..82b3cb732ad9c 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -699,6 +699,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 716ab572f8d3c..b23cb588cbf61 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -335,6 +335,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/freebsd/x86_64/entrypoints.txt b/libc/config/freebsd/x86_64/entrypoints.txt
index 8f6c178301c2f..05467df51f21a 100644
--- a/libc/config/freebsd/x86_64/entrypoints.txt
+++ b/libc/config/freebsd/x86_64/entrypoints.txt
@@ -632,6 +632,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 5c5e5891da822..93ee4fd6e4890 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -748,6 +748,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index afae725484a89..b6418e7680423 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -764,6 +764,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index e2402b1264931..c0f2bbeae5f87 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1091,6 +1091,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index f2a7f8e182658..66556bf8107a8 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -697,6 +697,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index b90ab97416a41..a38f3413d3f67 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1164,6 +1164,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 211476af8f712..a929931d799ab 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1186,6 +1186,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 3a48b49e169b3..8eea736e69339 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -425,6 +425,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.setpayloadsigbf16
libc.src.math.sqrtbf16
libc.src.math.tanbf16
+ libc.src.math.tanhbf16
libc.src.math.truncbf16
libc.src.math.totalorderbf16
libc.src.math.totalordermagbf16
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 67fc2e259eff9..ff3bbedeb3511 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -355,7 +355,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| tan | |check| | |check| | | |check| | | |check| | 7.12.4.7 | F.10.1.7 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
-| tanh | |check| | | | |check| | | | 7.12.5.6 | F.10.2.6 |
+| tanh | |check| | | | |check| | | |check| | 7.12.5.6 | F.10.2.6 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| tanpi | |check| | | | |check| | | | 7.12.4.14 | F.10.1.14 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/shared/math.h b/libc/shared/math.h
index 7b52cedf99c24..5df98e929588e 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -480,6 +480,7 @@
#include "math/tanbf16.h"
#include "math/tanf.h"
#include "math/tanf16.h"
+#include "math/tanhbf16.h"
#include "math/tanhf.h"
#include "math/tanhf16.h"
#include "math/tanpif.h"
diff --git a/libc/shared/math/tanhbf16.h b/libc/shared/math/tanhbf16.h
new file mode 100644
index 0000000000000..e1b115dda0f30
--- /dev/null
+++ b/libc/shared/math/tanhbf16.h
@@ -0,0 +1,23 @@
+//===-- Shared tanhbf16 function --------------------------------*- 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_MATH_TANHBF16_H
+#define LLVM_LIBC_SHARED_MATH_TANHBF16_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/tanhbf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::tanhbf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_TANHBF16_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 8d6a1495e1c11..0460c0037d2a4 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -5653,6 +5653,22 @@ add_header_library(
libc.include.llvm-libc-macros.float16_macros
)
+add_header_library(
+ tanhbf16
+ HDRS
+ tanhbf16.h
+ DEPENDS
+ .tanhf
+ libc.hdr.fenv_macros
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+)
+
add_header_library(
tanhf
HDRS
diff --git a/libc/src/__support/math/tanhbf16.h b/libc/src/__support/math/tanhbf16.h
new file mode 100644
index 0000000000000..6713a1d452a3a
--- /dev/null
+++ b/libc/src/__support/math/tanhbf16.h
@@ -0,0 +1,85 @@
+//===-- Implementation of tanhbf16 function -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_TANHBF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_TANHBF16_H
+
+#include "hdr/fenv_macros.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "tanhf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+
+LIBC_INLINE bfloat16 tanhbf16(bfloat16 x) {
+ using FPBits = fputil::FPBits<bfloat16>;
+ FPBits x_bits(x);
+ uint16_t x_u = x_bits.uintval();
+ uint16_t x_abs = x_u & 0x7fffU;
+
+ if (LIBC_UNLIKELY(x_bits.is_nan())) {
+ if (x_bits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ return x;
+ }
+
+ // tanh(+/-inf) = +/-1, and tanh(+/-0) = +/-0.
+ if (LIBC_UNLIKELY(x_bits.is_inf()))
+ return FPBits::one(x_bits.sign()).get_val();
+ if (LIBC_UNLIKELY(x_abs == 0))
+ return x;
+
+ // For |x| <= 0x1.7p-4, tanh(x) rounds to x in round-to-nearest. For
+ // directed rounding, its magnitude is strictly smaller than |x|.
+ if (LIBC_UNLIKELY(x_abs <= 0x3db8U)) {
+ bool toward_zero = false;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ int rounding_mode = fputil::quick_get_round();
+ toward_zero = rounding_mode == FE_TOWARDZERO ||
+ (rounding_mode == FE_DOWNWARD && x_bits.is_pos()) ||
+ (rounding_mode == FE_UPWARD && x_bits.is_neg());
+#endif
+ uint16_t result = toward_zero ? static_cast<uint16_t>(x_u - 1U) : x_u;
+ int exceptions = FE_INEXACT;
+ if ((result & 0x7fffU) < 0x0080U)
+ exceptions |= FE_UNDERFLOW;
+ fputil::raise_except_if_required(exceptions);
+ return FPBits(result).get_val();
+ }
+
+ // 0x1.bcp+1 is the first bfloat16 input whose tanh rounds to 1 in
+ // round-to-nearest. The result remains below 1 for every finite input.
+ if (LIBC_UNLIKELY(x_abs >= 0x405eU)) {
+ fputil::raise_except_if_required(FE_INEXACT);
+ bool round_to_one = true;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ int rounding_mode = fputil::quick_get_round();
+ round_to_one = rounding_mode == FE_TONEAREST ||
+ (rounding_mode == FE_UPWARD && x_bits.is_pos()) ||
+ (rounding_mode == FE_DOWNWARD && x_bits.is_neg());
+#endif
+ if (round_to_one)
+ return FPBits::one(x_bits.sign()).get_val();
+ return FPBits(static_cast<uint16_t>((x_u & 0x8000U) | 0x3f7fU)).get_val();
+ }
+
+ return fputil::cast<bfloat16>(tanhf(static_cast<float>(x)));
+}
+
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_TANHBF16_H
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 2c7568f0b6361..49072c724d66c 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -596,6 +596,7 @@ add_math_entrypoint_object(tanf)
add_math_entrypoint_object(tanf16)
add_math_entrypoint_object(tanh)
+add_math_entrypoint_object(tanhbf16)
add_math_entrypoint_object(tanhf)
add_math_entrypoint_object(tanhf16)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 28b8e954530dd..2a6275548e3c2 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3765,6 +3765,16 @@ add_entrypoint_object(
libc.src.__support.math.sinhf16
)
+add_entrypoint_object(
+ tanhbf16
+ SRCS
+ tanhbf16.cpp
+ HDRS
+ ../tanhbf16.h
+ DEPENDS
+ libc.src.__support.math.tanhbf16
+)
+
add_entrypoint_object(
tanhf
SRCS
diff --git a/libc/src/math/generic/tanhbf16.cpp b/libc/src/math/generic/tanhbf16.cpp
new file mode 100644
index 0000000000000..09028eb829aa4
--- /dev/null
+++ b/libc/src/math/generic/tanhbf16.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation for tanhbf16(x) function ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/tanhbf16.h"
+#include "src/__support/common.h"
+#include "src/__support/math/tanhbf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, tanhbf16, (bfloat16 x)) {
+ return math::tanhbf16(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/tanhbf16.h b/libc/src/math/tanhbf16.h
new file mode 100644
index 0000000000000..4ba909be30a91
--- /dev/null
+++ b/libc/src/math/tanhbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for tanhbf16 ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_TANHBF16_H
+#define LLVM_LIBC_SRC_MATH_TANHBF16_H
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 tanhbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_TANHBF16_H
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 74eda7cdaf065..e9348213984a5 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -485,6 +485,7 @@ else()
libc.src.__support.math.tanbf16
libc.src.__support.math.tanf
libc.src.__support.math.tanf16
+ libc.src.__support.math.tanhbf16
libc.src.__support.math.tanhf
libc.src.__support.math.tanhf16
libc.src.__support.math.tanpif
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 7b785331f36c6..5e715a49afcc0 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -902,5 +902,6 @@ TEST(LlvmLibcSharedMathTest, AllBFloat16) {
EXPECT_FP_EQ(bfloat16(0.0),
LIBC_NAMESPACE::shared::roundevenbf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::tanbf16(bfloat16(0.0)));
+ EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::tanhbf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::truncbf16(bfloat16(0.0)));
}
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 1fd0772aa5031..7623f7d61fece 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2625,6 +2625,19 @@ add_fp_unittest(
libc.src.math.sinhf16
)
+add_fp_unittest(
+ tanhbf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ tanhbf16_test.cpp
+ DEPENDS
+ libc.src.math.tanhbf16
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_fp_unittest(
tanhf_test
NEED_MPFR
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 0bfe73a2e643a..e06b5b54f5144 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4774,6 +4774,19 @@ add_fp_unittest(
libc.src.__support.FPUtil.cast
)
+add_fp_unittest(
+ tanhbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ tanhbf16_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.tanhbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_fp_unittest(
tanhf_test
SUITE
diff --git a/libc/test/src/math/smoke/tanhbf16_test.cpp b/libc/test/src/math/smoke/tanhbf16_test.cpp
new file mode 100644
index 0000000000000..0aa9383d97bbf
--- /dev/null
+++ b/libc/test/src/math/smoke/tanhbf16_test.cpp
@@ -0,0 +1,69 @@
+//===-- Unittests for tanhbf16 --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/tanhbf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcTanhBf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
+
+TEST_F(LlvmLibcTanhBf16Test, SpecialNumbers) {
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::tanhbf16(aNaN));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::tanhbf16(sNaN),
+ FE_INVALID);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(1.0f), LIBC_NAMESPACE::tanhbf16(inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-1.0f), LIBC_NAMESPACE::tanhbf16(neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::tanhbf16(zero));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::tanhbf16(neg_zero));
+ EXPECT_MATH_ERRNO(0);
+}
+
+TEST_F(LlvmLibcTanhBf16Test, SmallAndLargeValues) {
+ bfloat16 x = FPBits(uint16_t(0x3d80U)).get_val(); // 0.0625
+ bfloat16 below_x = FPBits(uint16_t(0x3d7fU)).get_val();
+ EXPECT_FP_EQ_WITH_EXCEPTION_ROUNDING_NEAREST(x, LIBC_NAMESPACE::tanhbf16(x),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION_ROUNDING_DOWNWARD(
+ below_x, LIBC_NAMESPACE::tanhbf16(x), FE_INEXACT);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ROUNDING_NEAREST(
+ bfloat16(1.0f), LIBC_NAMESPACE::tanhbf16(max_normal), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION_ROUNDING_DOWNWARD(
+ FPBits(uint16_t(0x3f7fU)).get_val(), LIBC_NAMESPACE::tanhbf16(max_normal),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION_ROUNDING_UPWARD(
+ FPBits(uint16_t(0xbf7fU)).get_val(),
+ LIBC_NAMESPACE::tanhbf16(neg_max_normal), FE_INEXACT);
+ EXPECT_MATH_ERRNO(0);
+}
+
+TEST_F(LlvmLibcTanhBf16Test, TinyValues) {
+ bfloat16 smallest = FPBits(uint16_t(0x0001U)).get_val();
+ bfloat16 neg_smallest = FPBits(uint16_t(0x8001U)).get_val();
+ EXPECT_FP_EQ_WITH_EXCEPTION_ROUNDING_NEAREST(
+ smallest, LIBC_NAMESPACE::tanhbf16(smallest), FE_UNDERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION_ROUNDING_DOWNWARD(
+ zero, LIBC_NAMESPACE::tanhbf16(smallest), FE_UNDERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION_ROUNDING_UPWARD(
+ neg_zero, LIBC_NAMESPACE::tanhbf16(neg_smallest),
+ FE_UNDERFLOW | FE_INEXACT);
+
+ bfloat16 min_normal = FPBits(uint16_t(0x0080U)).get_val();
+ bfloat16 max_subnormal = FPBits(uint16_t(0x007fU)).get_val();
+ EXPECT_FP_EQ_WITH_EXCEPTION_ROUNDING_DOWNWARD(
+ max_subnormal, LIBC_NAMESPACE::tanhbf16(min_normal),
+ FE_UNDERFLOW | FE_INEXACT);
+ EXPECT_MATH_ERRNO(0);
+}
diff --git a/libc/test/src/math/tanhbf16_test.cpp b/libc/test/src/math/tanhbf16_test.cpp
new file mode 100644
index 0000000000000..78b28b77e0167
--- /dev/null
+++ b/libc/test/src/math/tanhbf16_test.cpp
@@ -0,0 +1,33 @@
+//===-- Exhaustive test for tanhbf16 --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/tanhbf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcTanhBf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcTanhBf16Test, PositiveRange) {
+ for (uint32_t v = 0; v <= 0x7f80U; ++v) {
+ bfloat16 x = FPBits(static_cast<uint16_t>(v)).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Tanh, x,
+ LIBC_NAMESPACE::tanhbf16(x), 0.5);
+ }
+}
+
+TEST_F(LlvmLibcTanhBf16Test, NegativeRange) {
+ for (uint32_t v = 0x8000U; v <= 0xff80U; ++v) {
+ bfloat16 x = FPBits(static_cast<uint16_t>(v)).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Tanh, x,
+ LIBC_NAMESPACE::tanhbf16(x), 0.5);
+ }
+}
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 72a3e709e4af4..6e7ba5300ecf7 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -11456,6 +11456,22 @@ libc_support_library(
],
)
+libc_support_library(
+ name = "__support_math_tanhbf16",
+ hdrs = ["src/__support/math/tanhbf16.h"],
+ deps = [
+ ":__support_fputil_bfloat16",
+ ":__support_fputil_cast",
+ ":__support_fputil_fenv_impl",
+ ":__support_fputil_fp_bits",
+ ":__support_fputil_rounding_mode",
+ ":__support_math_tanhf",
+ ":__support_macros_config",
+ ":__support_macros_optimization",
+ ":hdr_fenv_macros",
+ ],
+)
+
libc_support_library(
name = "__support_math_tanhf",
hdrs = ["src/__support/math/tanhf.h"],
@@ -14980,6 +14996,13 @@ libc_math_function(
],
)
+libc_math_function(
+ name = "tanhbf16",
+ additional_deps = [
+ ":__support_math_tanhbf16",
+ ],
+)
+
libc_math_function(
name = "tanhf",
additional_deps = [
>From 7207f90aaa916eee3415eb66d7bb967026f4bb5f Mon Sep 17 00:00:00 2001
From: sid <siddharthqln at gmail.com>
Date: Sun, 4 Oct 2026 19:22:01 +0530
Subject: [PATCH 2/2] fix tanhbf16 Bazel build and tests
---
utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 3 ++-
.../llvm-project-overlay/libc/test/src/math/BUILD.bazel | 7 +++++++
.../libc/test/src/math/smoke/BUILD.bazel | 7 +++++++
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 6e7ba5300ecf7..b4d85213623e1 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -11465,9 +11465,9 @@ libc_support_library(
":__support_fputil_fenv_impl",
":__support_fputil_fp_bits",
":__support_fputil_rounding_mode",
- ":__support_math_tanhf",
":__support_macros_config",
":__support_macros_optimization",
+ ":__support_math_tanhf",
":hdr_fenv_macros",
],
)
@@ -14999,6 +14999,7 @@ libc_math_function(
libc_math_function(
name = "tanhbf16",
additional_deps = [
+ ":__support_fputil_bfloat16",
":__support_math_tanhbf16",
],
)
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel
index f9d21bcabeaa5..d5f02cf58bc61 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel
@@ -876,6 +876,13 @@ math_mpfr_test(
],
)
+math_mpfr_test(
+ name = "tanhbf16",
+ deps = [
+ "//libc:__support_fputil_bfloat16",
+ ],
+)
+
math_mpfr_test(name = "tanhf")
math_mpfr_test(
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel
index 0a79dcd33a587..e78a5e63bb24b 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel
@@ -2131,6 +2131,13 @@ math_test(name = "tan")
math_test(name = "tanf")
+math_test(
+ name = "tanhbf16",
+ deps = [
+ "//libc:__support_fputil_bfloat16",
+ ],
+)
+
math_test(name = "tanhf")
math_test(name = "tanpif")
More information about the libc-commits
mailing list