[libc-commits] [libc] [llvm] [libc][math][c++23] Add log10p1bf16 math function (PR #235343)
Uppala Prajin via libc-commits
libc-commits at lists.llvm.org
Wed Oct 28 04:12:21 PDT 2026
https://github.com/prajin-uppala updated https://github.com/llvm/llvm-project/pull/235343
>From f2d12fefe749a79a04c574c4f018882194402cb2 Mon Sep 17 00:00:00 2001
From: prajin-uppala <cs24btech11064 at iith.ac.in>
Date: Sat, 24 Oct 2026 20:11:55 +0530
Subject: [PATCH 1/7] feat: add log10p1bf16 implementation and tests
---
libc/config/baremetal/aarch64/entrypoints.txt | 1 +
libc/config/baremetal/arm/entrypoints.txt | 1 +
libc/config/baremetal/hexagon/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/shared/math.h | 1 +
libc/shared/math/log10p1bf16.h | 23 +++
libc/src/__support/math/CMakeLists.txt | 29 ++++
libc/src/__support/math/log10p1bf16.h | 139 ++++++++++++++++++
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/generic/CMakeLists.txt | 11 ++
libc/src/math/generic/log10p1bf16.cpp | 18 +++
libc/src/math/log10p1bf16.h | 21 +++
libc/test/shared/CMakeLists.txt | 1 +
libc/test/shared/shared_math_test.cpp | 2 +
libc/test/src/math/CMakeLists.txt | 13 ++
libc/test/src/math/log10p1bf16_test.cpp | 41 ++++++
libc/test/src/math/smoke/CMakeLists.txt | 14 ++
libc/test/src/math/smoke/log10p1bf16_test.cpp | 85 +++++++++++
.../llvm-project-overlay/libc/BUILD.bazel | 26 ++++
.../libc/test/src/math/BUILD.bazel | 5 +
.../libc/test/src/math/smoke/BUILD.bazel | 5 +
31 files changed, 449 insertions(+)
create mode 100644 libc/shared/math/log10p1bf16.h
create mode 100644 libc/src/__support/math/log10p1bf16.h
create mode 100644 libc/src/math/generic/log10p1bf16.cpp
create mode 100644 libc/src/math/log10p1bf16.h
create mode 100644 libc/test/src/math/log10p1bf16_test.cpp
create mode 100644 libc/test/src/math/smoke/log10p1bf16_test.cpp
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 0202bc7a2dc56b..632a6a2f13bf64 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -856,6 +856,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index b7322502d570d4..0a964d3b05474b 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -867,6 +867,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/baremetal/hexagon/entrypoints.txt b/libc/config/baremetal/hexagon/entrypoints.txt
index 61f869457b3282..3fd82f0cee4e54 100644
--- a/libc/config/baremetal/hexagon/entrypoints.txt
+++ b/libc/config/baremetal/hexagon/entrypoints.txt
@@ -856,6 +856,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 7e68a3c374249d..210acad836d904 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -859,6 +859,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index c0ce5870c862ec..44d83686afcb6e 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -678,6 +678,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index e3fc845d2ed3af..6b0f337f22828d 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -313,6 +313,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.cbrtbf16
libc.src.math.logbbf16
diff --git a/libc/config/freebsd/x86_64/entrypoints.txt b/libc/config/freebsd/x86_64/entrypoints.txt
index 42d52b3ebc6c2c..687cac9d4d0571 100644
--- a/libc/config/freebsd/x86_64/entrypoints.txt
+++ b/libc/config/freebsd/x86_64/entrypoints.txt
@@ -610,6 +610,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index ffbcc4b1672403..7cf18751eb98f3 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -731,6 +731,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index ff31536073543e..f918678a163290 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -747,6 +747,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 7a94716e74032c..849a8760a088d9 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1090,6 +1090,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 31561b52bdca51..e503f2728baba0 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -695,6 +695,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 8c31aaad07015f..8cda1133b17b79 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1168,6 +1168,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 02aef4a1297186..0cdd971ac809ba 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1190,6 +1190,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index e0477cbf5a6f00..e9260c15f02f7c 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -406,6 +406,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10p1bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
diff --git a/libc/shared/math.h b/libc/shared/math.h
index eb72bebcb53bfa..db7105164aa2b0 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -335,6 +335,7 @@
#include "math/log10.h"
#include "math/log10f.h"
#include "math/log10f16.h"
+#include "math/log10p1bf16.h"
#include "math/log10p1f16.h"
#include "math/log1p.h"
#include "math/log1pf.h"
diff --git a/libc/shared/math/log10p1bf16.h b/libc/shared/math/log10p1bf16.h
new file mode 100644
index 00000000000000..60c869fc1b991f
--- /dev/null
+++ b/libc/shared/math/log10p1bf16.h
@@ -0,0 +1,23 @@
+//===-- Shared log10p1bf16 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_LOG10P1BF16_H
+#define LLVM_LIBC_SHARED_MATH_LOG10P1BF16_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/log10p1bf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::log10p1bf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_LOG10P1BF16_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 400e5e2d6aeaa8..e8b7bbc2315cf6 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -3125,6 +3125,17 @@ add_header_library(
libc.src.__support.macros.properties.types
)
+add_header_library(
+ check.exp_exceptions
+ HDRS
+ check/exp_exceptions.h
+ DEPENDS
+ libc.hdr.fenv_macros
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.common
+ libc.src.__support.macros.config
+)
+
add_header_library(
expf_double_eval
HDRS
@@ -5515,6 +5526,24 @@ add_header_library(
libc.src.__support.uint128
)
+add_header_library(
+ log10p1bf16
+ HDRS
+ log10p1bf16.h
+ DEPENDS
+ libc.hdr.errno_macros
+ 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.multiply_add
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+)
+
add_header_library(
log_bf16
HDRS
diff --git a/libc/src/__support/math/log10p1bf16.h b/libc/src/__support/math/log10p1bf16.h
new file mode 100644
index 00000000000000..98b79cd91ccf6d
--- /dev/null
+++ b/libc/src/__support/math/log10p1bf16.h
@@ -0,0 +1,139 @@
+//===-- Implementation header for log10p1bf16 -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_LOG10P1BF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_LOG10P1BF16_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+
+namespace log10p1bf16_internal {
+
+// Generated by Sollya with the following commands:
+// > display = hexadecimal;
+// > for i from 0 to 31 do print(round(log10(1 + i * 2^-5), SG, RN));
+LIBC_INLINE_VAR constexpr float LOG10F_F[32] = {
+ 0x0p+0f, 0x1.b5e908p-7f, 0x1.af5f92p-6f, 0x1.3ed11ap-5f,
+ 0x1.a30a9ep-5f, 0x1.02428cp-4f, 0x1.31b306p-4f, 0x1.5fe804p-4f,
+ 0x1.8cf184p-4f, 0x1.b8de4ep-4f, 0x1.e3bc1ap-4f, 0x1.06cbd6p-3f,
+ 0x1.1b3e72p-3f, 0x1.2f3b6ap-3f, 0x1.42c7e8p-3f, 0x1.55e8c6p-3f,
+ 0x1.68a288p-3f, 0x1.7af974p-3f, 0x1.8cf184p-3f, 0x1.9e8e7cp-3f,
+ 0x1.afd3e4p-3f, 0x1.c0c514p-3f, 0x1.d1653p-3f, 0x1.e1b734p-3f,
+ 0x1.f1bdeep-3f, 0x1.00be06p-2f, 0x1.087a08p-2f, 0x1.101432p-2f,
+ 0x1.178da6p-2f, 0x1.1ee778p-2f, 0x1.2622bp-2f, 0x1.2d404cp-2f,
+};
+
+// Generated by Sollya with the following commands:
+// > display = hexadecimal;
+// > for i from 0 to 31 do print(round(1 / (1 + i * 2^-5), SG, RN));
+LIBC_INLINE_VAR constexpr float ONE_OVER_F_F[32] = {
+ 0x1p+0f, 0x1.f07c2p-1f, 0x1.e1e1e2p-1f, 0x1.d41d42p-1f,
+ 0x1.c71c72p-1f, 0x1.bacf92p-1f, 0x1.af286cp-1f, 0x1.a41a42p-1f,
+ 0x1.99999ap-1f, 0x1.8f9c18p-1f, 0x1.861862p-1f, 0x1.7d05f4p-1f,
+ 0x1.745d18p-1f, 0x1.6c16c2p-1f, 0x1.642c86p-1f, 0x1.5c9882p-1f,
+ 0x1.555556p-1f, 0x1.4e5e0ap-1f, 0x1.47ae14p-1f, 0x1.414142p-1f,
+ 0x1.3b13b2p-1f, 0x1.3521dp-1f, 0x1.2f684cp-1f, 0x1.29e412p-1f,
+ 0x1.24924ap-1f, 0x1.1f7048p-1f, 0x1.1a7b96p-1f, 0x1.15b1e6p-1f,
+ 0x1.111112p-1f, 0x1.0c9714p-1f, 0x1.08421p-1f, 0x1.041042p-1f,
+};
+
+// Generated by Sollya with the following commands:
+// > display = hexadecimal;
+// > round(log10(2), SG, RN);
+LIBC_INLINE_VAR constexpr float LOG10F_2 = 0x1.344136p-2f;
+
+} // namespace log10p1bf16_internal
+
+LIBC_INLINE bfloat16 log10p1bf16(bfloat16 x) {
+ using namespace log10p1bf16_internal;
+ using FPBits = fputil::FPBits<bfloat16>;
+ FPBits x_bits(x);
+ uint16_t x_u = x_bits.uintval();
+ uint16_t x_abs = x_u & 0x7fffU;
+
+ // Handle special values and use the small-input polynomial for |x| <= 0.125.
+ if (LIBC_UNLIKELY(x_abs <= 0x3e00U || x_abs >= 0x7f80U)) {
+ // log10p1(NaN) = NaN
+ if (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;
+ }
+
+ // log10p1(+/-0) = +/-0
+ if (x_abs == 0U)
+ return x;
+
+ // log10p1(+inf) = +inf
+ if (x_u == 0x7f80U)
+ return x;
+
+ // log10p1(-inf) = NaN
+ if (x_abs >= 0x7f80U) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ float xf = static_cast<float>(x);
+ return fputil::cast<bfloat16>(
+ xf * fputil::polyeval(xf, 0x1.bcb7b2p-2f, -0x1.bcb4cp-3f,
+ 0x1.2875bcp-3f, -0x1.c2946ep-4f, 0x1.69da2p-4f));
+ }
+
+ if (LIBC_UNLIKELY(x_u == 0xbf80U)) {
+ fputil::raise_except_if_required(FE_DIVBYZERO);
+ return FPBits::inf(Sign::NEG).get_val();
+ }
+
+ if (LIBC_UNLIKELY(x_u > 0xbf80U)) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ if (LIBC_UNLIKELY(x_u == 0x4110U))
+ return FPBits(static_cast<uint16_t>(0x3f80U)).get_val();
+ if (LIBC_UNLIKELY(x_u == 0x42c6U))
+ return FPBits(static_cast<uint16_t>(0x4000U)).get_val();
+
+ float y = 1.0f + static_cast<float>(x);
+ using FPBitsFloat = fputil::FPBits<float>;
+ FPBitsFloat y_bits(y);
+
+ int e = y_bits.get_exponent();
+ y_bits.set_biased_exponent(FPBitsFloat::EXP_BIAS);
+ float mant_f = y_bits.get_val();
+
+ int f = y_bits.get_mantissa() >> (FPBitsFloat::FRACTION_LEN - 5);
+ float v = fputil::multiply_add(mant_f, ONE_OVER_F_F[f], -1.0f);
+ float log10p1_d_over_f =
+ v * fputil::polyeval(v, 0x1.bcb7bp-2f, -0x1.bce168p-3f, 0x1.28acb8p-3f);
+ float log10_1_mant = LOG10F_F[f] + log10p1_d_over_f;
+ return fputil::cast<bfloat16>(
+ fputil::multiply_add(static_cast<float>(e), LOG10F_2, log10_1_mant));
+}
+
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LOG10P1BF16_H
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 4f1dd95a6993da..3a1ab15e19a84b 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -403,6 +403,7 @@ add_math_entrypoint_object(log10)
add_math_entrypoint_object(log10f)
add_math_entrypoint_object(log10f16)
add_math_entrypoint_object(log10p1f16)
+add_math_entrypoint_object(log10p1bf16)
add_math_entrypoint_object(log1p)
add_math_entrypoint_object(log1pf)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index b4b2465b384b10..9317c208442661 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1788,6 +1788,17 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ log10p1bf16
+ SRCS
+ log10p1bf16.cpp
+ HDRS
+ ../log10p1bf16.h
+ DEPENDS
+ libc.src.__support.math.log10p1bf16
+ libc.src.errno.errno
+)
+
add_entrypoint_object(
log10p1f16
SRCS
diff --git a/libc/src/math/generic/log10p1bf16.cpp b/libc/src/math/generic/log10p1bf16.cpp
new file mode 100644
index 00000000000000..64a327b9347ead
--- /dev/null
+++ b/libc/src/math/generic/log10p1bf16.cpp
@@ -0,0 +1,18 @@
+//===-- BFloat16 log10(1 + 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/log10p1bf16.h"
+#include "src/__support/math/log10p1bf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, log10p1bf16, (bfloat16 x)) {
+ return math::log10p1bf16(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/log10p1bf16.h b/libc/src/math/log10p1bf16.h
new file mode 100644
index 00000000000000..cc4e952df08d91
--- /dev/null
+++ b/libc/src/math/log10p1bf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for log10p1bf16 -------------------*- 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_LOG10P1BF16_H
+#define LLVM_LIBC_SRC_MATH_LOG10P1BF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 log10p1bf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LOG10P1BF16_H
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index eff5bea2970fd1..70875774a8537d 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -331,6 +331,7 @@ else()
libc.src.__support.math.log
libc.src.__support.math.log10
libc.src.__support.math.log10f16
+ libc.src.__support.math.log10p1bf16
libc.src.__support.math.log10p1f16
libc.src.__support.math.log10f
libc.src.__support.math.log1p
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 68b562c48931aa..5e68ddea5214c1 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -819,6 +819,8 @@ TEST(LlvmLibcSharedMathTest, AllBFloat16) {
EXPECT_FP_EQ(bfloat16(1.0), LIBC_NAMESPACE::shared::exp2bf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(1.0), LIBC_NAMESPACE::shared::expbf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::log_bf16(bfloat16(1.0)));
+ EXPECT_FP_EQ(bfloat16(1.0),
+ LIBC_NAMESPACE::shared::log10p1bf16(bfloat16(9.0)));
bfloat16 neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val();
EXPECT_FP_EQ(neg_min_denormal,
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index d88afe6370e27b..ce3526f0d33329 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2393,6 +2393,19 @@ add_fp_unittest(
libc.src.math.logf16
)
+add_fp_unittest(
+ log10p1bf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ log10p1bf16_test.cpp
+ DEPENDS
+ libc.src.math.log10p1bf16
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
add_fp_unittest(
log_bf16_test
NEED_MPFR
diff --git a/libc/test/src/math/log10p1bf16_test.cpp b/libc/test/src/math/log10p1bf16_test.cpp
new file mode 100644
index 00000000000000..4208e2348103c8
--- /dev/null
+++ b/libc/test/src/math/log10p1bf16_test.cpp
@@ -0,0 +1,41 @@
+//===-- Full range tests for BFloat16 log10(1 + 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/__support/FPUtil/bfloat16.h"
+#include "src/math/log10p1bf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcLog10p1bf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcLog10p1bf16Test, PositiveRange) {
+ for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+ bfloat16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10p1, x,
+ LIBC_NAMESPACE::log10p1bf16(x), 0.5);
+ }
+}
+
+TEST_F(LlvmLibcLog10p1bf16Test, NegativeRange) {
+ for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+ bfloat16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10p1, x,
+ LIBC_NAMESPACE::log10p1bf16(x), 0.5);
+ }
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index d68eb7786e3b58..dc0fbb6a949f14 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4500,6 +4500,20 @@ add_fp_unittest(
libc.src.__support.FPUtil.cast
)
+add_fp_unittest(
+ log10p1bf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ log10p1bf16_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.log10p1bf16
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
add_fp_unittest(
log_bf16_test
SUITE
diff --git a/libc/test/src/math/smoke/log10p1bf16_test.cpp b/libc/test/src/math/smoke/log10p1bf16_test.cpp
new file mode 100644
index 00000000000000..8d635f39f9dfa4
--- /dev/null
+++ b/libc/test/src/math/smoke/log10p1bf16_test.cpp
@@ -0,0 +1,85 @@
+//===-- Unittests for BFloat16 log10(1 + 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 "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/macros/properties/types.h"
+#include "src/math/log10p1bf16.h"
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>;
+
+class LlvmLibcLog10p1bf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+ DECLARE_SPECIAL_CONSTANTS(bfloat16)
+
+public:
+ void test_special_numbers() {
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ aNaN, LIBC_NAMESPACE::log10p1bf16(aNaN), 0);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ aNaN, LIBC_NAMESPACE::log10p1bf16(sNaN), FE_INVALID);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ inf, LIBC_NAMESPACE::log10p1bf16(inf), 0);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ aNaN, LIBC_NAMESPACE::log10p1bf16(neg_inf), FE_INVALID);
+ EXPECT_MATH_ERRNO(EDOM);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ zero, LIBC_NAMESPACE::log10p1bf16(zero), 0);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ neg_zero, LIBC_NAMESPACE::log10p1bf16(neg_zero), 0);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ neg_inf, LIBC_NAMESPACE::log10p1bf16(bfloat16(-1.0)), FE_DIVBYZERO);
+ EXPECT_MATH_ERRNO(0);
+
+ const bfloat16 neg_two = FPBits(static_cast<uint16_t>(0xc000U)).get_val();
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ aNaN, LIBC_NAMESPACE::log10p1bf16(neg_two), FE_INVALID);
+ EXPECT_MATH_ERRNO(EDOM);
+
+ bfloat16 neg_one_adjacent =
+ FPBits(static_cast<uint16_t>(0xbf81U)).get_val();
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ aNaN, LIBC_NAMESPACE::log10p1bf16(neg_one_adjacent), FE_INVALID);
+ EXPECT_MATH_ERRNO(EDOM);
+
+ bfloat16 neg_inf_adjacent =
+ FPBits(static_cast<uint16_t>(0xff7fU)).get_val();
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ aNaN, LIBC_NAMESPACE::log10p1bf16(neg_inf_adjacent), FE_INVALID);
+ EXPECT_MATH_ERRNO(EDOM);
+
+ const bfloat16 one = bfloat16(1.0);
+ const bfloat16 nine = bfloat16(9.0);
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ one, LIBC_NAMESPACE::log10p1bf16(nine), 0);
+ EXPECT_MATH_ERRNO(0);
+
+ const bfloat16 two = bfloat16(2.0);
+ const bfloat16 ninety_nine = bfloat16(99.0);
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ two, LIBC_NAMESPACE::log10p1bf16(ninety_nine), 0);
+ EXPECT_MATH_ERRNO(0);
+ }
+};
+
+TEST_F(LlvmLibcLog10p1bf16Test, SpecialNumbers) { test_special_numbers(); }
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 751e08c7323cfb..b66995b86e7d99 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -10475,6 +10475,25 @@ libc_support_library(
],
)
+libc_support_library(
+ name = "__support_math_log10p1bf16",
+ hdrs = ["src/__support/math/log10p1bf16.h"],
+ deps = [
+ ":__support_common",
+ ":__support_fputil_bfloat16",
+ ":__support_fputil_cast",
+ ":__support_fputil_fenv_impl",
+ ":__support_fputil_fp_bits",
+ ":__support_fputil_multiply_add",
+ ":__support_fputil_polyeval",
+ ":__support_macros_attributes",
+ ":__support_macros_config",
+ ":__support_macros_optimization",
+ ":hdr_errno_macros",
+ ":hdr_fenv_macros",
+ ],
+)
+
libc_support_library(
name = "__support_math_log10p1f16",
hdrs = ["src/__support/math/log10p1f16.h"],
@@ -14561,6 +14580,13 @@ libc_math_function(
],
)
+libc_math_function(
+ name = "log10p1bf16",
+ additional_deps = [
+ ":__support_math_log10p1bf16",
+ ],
+)
+
libc_math_function(
name = "log10p1f16",
additional_deps = [
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 c39dc612851536..742efe13a98871 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
@@ -1115,6 +1115,11 @@ math_mpfr_test(name = "log2p1f16")
math_mpfr_test(name = "log10f16")
+math_mpfr_test(
+ name = "log10p1bf16",
+ deps = ["//libc:__support_fputil_bfloat16"],
+)
+
math_mpfr_test(name = "log10p1f16")
math_mpfr_test(name = "lgammaf16")
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 dad78bc78a3545..01f25d838a8b25 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
@@ -2405,6 +2405,11 @@ math_test(name = "log2f16")
math_test(name = "log2p1f16")
+math_test(
+ name = "log10p1bf16",
+ deps = ["//libc:__support_fputil_bfloat16"],
+)
+
math_test(name = "log10p1f16")
math_test(name = "logf16")
>From a83c202b35185fff2a666fd7274abb814a1cc331 Mon Sep 17 00:00:00 2001
From: prajin-uppala <cs24btech11064 at iith.ac.in>
Date: Sun, 25 Oct 2026 00:05:08 +0530
Subject: [PATCH 2/7] chore: update log10p1bf16 comments and build files
---
libc/src/__support/math/log10p1bf16.h | 22 ++++++++++++++++---
libc/src/math/CMakeLists.txt | 2 +-
.../llvm-project-overlay/libc/BUILD.bazel | 1 -
3 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/libc/src/__support/math/log10p1bf16.h b/libc/src/__support/math/log10p1bf16.h
index 98b79cd91ccf6d..b1de5fd6e10d3a 100644
--- a/libc/src/__support/math/log10p1bf16.h
+++ b/libc/src/__support/math/log10p1bf16.h
@@ -26,9 +26,12 @@ namespace math {
namespace log10p1bf16_internal {
+// The top five mantissa bits select F = 1 + f * 2^-5, where f is in [0, 31].
+// BFloat16 has seven explicit mantissa bits, so the table uses five of those
+// bits for lookup and the remaining two bits to refine the residual.
// Generated by Sollya with the following commands:
// > display = hexadecimal;
-// > for i from 0 to 31 do print(round(log10(1 + i * 2^-5), SG, RN));
+// > for f from 0 to 31 do print(round(log10(1 + f * 2^-5), SG, RN));
LIBC_INLINE_VAR constexpr float LOG10F_F[32] = {
0x0p+0f, 0x1.b5e908p-7f, 0x1.af5f92p-6f, 0x1.3ed11ap-5f,
0x1.a30a9ep-5f, 0x1.02428cp-4f, 0x1.31b306p-4f, 0x1.5fe804p-4f,
@@ -40,9 +43,11 @@ LIBC_INLINE_VAR constexpr float LOG10F_F[32] = {
0x1.178da6p-2f, 0x1.1ee778p-2f, 0x1.2622bp-2f, 0x1.2d404cp-2f,
};
+// ONE_OVER_F_F[f] stores the reciprocal of the same representative F. It is
+// used to form the residual v = M * (1 / F) - 1.
// Generated by Sollya with the following commands:
// > display = hexadecimal;
-// > for i from 0 to 31 do print(round(1 / (1 + i * 2^-5), SG, RN));
+// > for f from 0 to 31 do print(round(1 / (1 + f * 2^-5), SG, RN));
LIBC_INLINE_VAR constexpr float ONE_OVER_F_F[32] = {
0x1p+0f, 0x1.f07c2p-1f, 0x1.e1e1e2p-1f, 0x1.d41d42p-1f,
0x1.c71c72p-1f, 0x1.bacf92p-1f, 0x1.af286cp-1f, 0x1.a41a42p-1f,
@@ -68,7 +73,8 @@ LIBC_INLINE bfloat16 log10p1bf16(bfloat16 x) {
uint16_t x_u = x_bits.uintval();
uint16_t x_abs = x_u & 0x7fffU;
- // Handle special values and use the small-input polynomial for |x| <= 0.125.
+ // Handle special values; for |x| <= 0.125 (bits <= 0x3e00), use a direct
+ // polynomial to avoid cancellation in the range-reduction residual.
if (LIBC_UNLIKELY(x_abs <= 0x3e00U || x_abs >= 0x7f80U)) {
// log10p1(NaN) = NaN
if (x_bits.is_nan()) {
@@ -94,12 +100,15 @@ LIBC_INLINE bfloat16 log10p1bf16(bfloat16 x) {
return FPBits::quiet_nan().get_val();
}
+ // This degree-4 polynomial is shared with log10p1f16 and approximates
+ // log10(1 + x) / x; multiplying by x gives log10(1 + x).
float xf = static_cast<float>(x);
return fputil::cast<bfloat16>(
xf * fputil::polyeval(xf, 0x1.bcb7b2p-2f, -0x1.bcb4cp-3f,
0x1.2875bcp-3f, -0x1.c2946ep-4f, 0x1.69da2p-4f));
}
+ // x = -1 has bits 0xbf80 and is the domain boundary log10(1 + x) = -inf.
if (LIBC_UNLIKELY(x_u == 0xbf80U)) {
fputil::raise_except_if_required(FE_DIVBYZERO);
return FPBits::inf(Sign::NEG).get_val();
@@ -111,11 +120,18 @@ LIBC_INLINE bfloat16 log10p1bf16(bfloat16 x) {
return FPBits::quiet_nan().get_val();
}
+ // log10(1 + 9) = 1 and log10(1 + 99) = 2 exactly; return them directly.
if (LIBC_UNLIKELY(x_u == 0x4110U))
return FPBits(static_cast<uint16_t>(0x3f80U)).get_val();
if (LIBC_UNLIKELY(x_u == 0x42c6U))
return FPBits(static_cast<uint16_t>(0x4000U)).get_val();
+ // For y = 1 + x, write y = 2^e * M, where M is in [1, 2), and select
+ // F = 1 + f * 2^-5 from the lookup tables. Then:
+ // log10(y) = e * log10(2) + log10(F) + log10(M / F).
+ // The residual v = M / F - 1 is computed using the reciprocal table. This
+ // degree-2 polynomial is shared with log10p1f16 and approximates
+ // log10(1 + v) / v, giving the correction log10(M / F).
float y = 1.0f + static_cast<float>(x);
using FPBitsFloat = fputil::FPBits<float>;
FPBitsFloat y_bits(y);
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 3a1ab15e19a84b..46e98ba38e4cdc 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -402,8 +402,8 @@ add_math_entrypoint_object(ldexpbf16)
add_math_entrypoint_object(log10)
add_math_entrypoint_object(log10f)
add_math_entrypoint_object(log10f16)
-add_math_entrypoint_object(log10p1f16)
add_math_entrypoint_object(log10p1bf16)
+add_math_entrypoint_object(log10p1f16)
add_math_entrypoint_object(log1p)
add_math_entrypoint_object(log1pf)
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index b66995b86e7d99..c7a2fbd4573c9a 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -10479,7 +10479,6 @@ libc_support_library(
name = "__support_math_log10p1bf16",
hdrs = ["src/__support/math/log10p1bf16.h"],
deps = [
- ":__support_common",
":__support_fputil_bfloat16",
":__support_fputil_cast",
":__support_fputil_fenv_impl",
>From 7e9e60340c51182cf8bf2b381594ea2df56f0557 Mon Sep 17 00:00:00 2001
From: prajin-uppala <cs24btech11064 at iith.ac.in>
Date: Sun, 25 Oct 2026 19:26:45 +0530
Subject: [PATCH 3/7] fix: use correct suite for log10p1bf16 test
---
libc/test/src/math/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index ce3526f0d33329..6937dffaf0100a 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2397,7 +2397,7 @@ add_fp_unittest(
log10p1bf16_test
NEED_MPFR
SUITE
- libc-math-unittests
+ libc-math-tests
SRCS
log10p1bf16_test.cpp
DEPENDS
>From c2d2ae9be8fc8df3fc8f98d2e1ef22749ad2a149 Mon Sep 17 00:00:00 2001
From: prajin-uppala <cs24btech11064 at iith.ac.in>
Date: Tue, 27 Oct 2026 00:41:37 +0530
Subject: [PATCH 4/7] [libc][math] Remove unrelated check.exp_exceptions target
---
libc/src/__support/math/CMakeLists.txt | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index e8b7bbc2315cf6..b61112fe050d34 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -3125,17 +3125,6 @@ add_header_library(
libc.src.__support.macros.properties.types
)
-add_header_library(
- check.exp_exceptions
- HDRS
- check/exp_exceptions.h
- DEPENDS
- libc.hdr.fenv_macros
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.common
- libc.src.__support.macros.config
-)
-
add_header_library(
expf_double_eval
HDRS
>From aed0bba5b0df5ea3a689f41c8d22802d45384609 Mon Sep 17 00:00:00 2001
From: prajin-uppala <cs24btech11064 at iith.ac.in>
Date: Tue, 27 Oct 2026 01:25:00 +0530
Subject: [PATCH 5/7] [libc][math] Fix spurious underflow in log10p1bf16
---
libc/src/__support/math/log10p1bf16.h | 6 ++++++
libc/test/src/math/smoke/log10p1bf16_test.cpp | 9 +++++++++
2 files changed, 15 insertions(+)
diff --git a/libc/src/__support/math/log10p1bf16.h b/libc/src/__support/math/log10p1bf16.h
index b1de5fd6e10d3a..c8cbd3e28eff3c 100644
--- a/libc/src/__support/math/log10p1bf16.h
+++ b/libc/src/__support/math/log10p1bf16.h
@@ -103,6 +103,12 @@ LIBC_INLINE bfloat16 log10p1bf16(bfloat16 x) {
// This degree-4 polynomial is shared with log10p1f16 and approximates
// log10(1 + x) / x; multiplying by x gives log10(1 + x).
float xf = static_cast<float>(x);
+
+ // For tiny |x|, log10(1 + x) is approximately x / ln(10).
+ // Avoid subnormal intermediate products in the polynomial evaluation.
+ if (x_abs < 0x0d80U)
+ return fputil::cast<bfloat16>(xf * 0x1.bcb7b2p-2f);
+
return fputil::cast<bfloat16>(
xf * fputil::polyeval(xf, 0x1.bcb7b2p-2f, -0x1.bcb4cp-3f,
0x1.2875bcp-3f, -0x1.c2946ep-4f, 0x1.69da2p-4f));
diff --git a/libc/test/src/math/smoke/log10p1bf16_test.cpp b/libc/test/src/math/smoke/log10p1bf16_test.cpp
index 8d635f39f9dfa4..c1dc695dfa9cb8 100644
--- a/libc/test/src/math/smoke/log10p1bf16_test.cpp
+++ b/libc/test/src/math/smoke/log10p1bf16_test.cpp
@@ -79,6 +79,15 @@ class LlvmLibcLog10p1bf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
two, LIBC_NAMESPACE::log10p1bf16(ninety_nine), 0);
EXPECT_MATH_ERRNO(0);
+
+ const bfloat16 tiny_input =
+ FPBits(static_cast<uint16_t>(0x0114U)).get_val();
+ const bfloat16 expected_tiny_result =
+ FPBits(static_cast<uint16_t>(0x0081U)).get_val();
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(expected_tiny_result,
+ LIBC_NAMESPACE::log10p1bf16(tiny_input),
+ FE_INEXACT);
}
};
>From e9e4f1ee9516492b94cc6b36c72f9b1458467b7b Mon Sep 17 00:00:00 2001
From: prajin-uppala <cs24btech11064 at iith.ac.in>
Date: Wed, 28 Oct 2026 16:17:36 +0530
Subject: [PATCH 6/7] chore: update log10p1bf16 file headers
---
libc/shared/math/log10p1bf16.h | 6 +++++-
libc/src/__support/math/log10p1bf16.h | 11 +++++++++--
libc/src/math/generic/log10p1bf16.cpp | 6 +++++-
libc/src/math/log10p1bf16.h | 6 +++++-
libc/test/src/math/log10p1bf16_test.cpp | 6 +++++-
libc/test/src/math/smoke/log10p1bf16_test.cpp | 6 +++++-
6 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/libc/shared/math/log10p1bf16.h b/libc/shared/math/log10p1bf16.h
index 60c869fc1b991f..2563c24cd90917 100644
--- a/libc/shared/math/log10p1bf16.h
+++ b/libc/shared/math/log10p1bf16.h
@@ -1,10 +1,14 @@
-//===-- Shared log10p1bf16 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
//
//===----------------------------------------------------------------------===//
+/// \file
+/// Shared wrapper for the log10p1bf16 function.
+//
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_MATH_LOG10P1BF16_H
#define LLVM_LIBC_SHARED_MATH_LOG10P1BF16_H
diff --git a/libc/src/__support/math/log10p1bf16.h b/libc/src/__support/math/log10p1bf16.h
index c8cbd3e28eff3c..3405371b0d1089 100644
--- a/libc/src/__support/math/log10p1bf16.h
+++ b/libc/src/__support/math/log10p1bf16.h
@@ -1,10 +1,14 @@
-//===-- Implementation header for log10p1bf16 -------------------*- 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
//
//===----------------------------------------------------------------------===//
+/// \file
+/// Implementation of the log10p1bf16 function.
+//
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_LOG10P1BF16_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_LOG10P1BF16_H
@@ -25,6 +29,9 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
namespace log10p1bf16_internal {
+// TODO: Reuse the lookup tables from expxf16_utils.h when they can be
+// shared with the bfloat16 implementation. See
+// https://github.com/llvm/llvm-project/pull/184283.
// The top five mantissa bits select F = 1 + f * 2^-5, where f is in [0, 31].
// BFloat16 has seven explicit mantissa bits, so the table uses five of those
@@ -94,7 +101,7 @@ LIBC_INLINE bfloat16 log10p1bf16(bfloat16 x) {
return x;
// log10p1(-inf) = NaN
- if (x_abs >= 0x7f80U) {
+ if (x_abs == 0xff80U) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return FPBits::quiet_nan().get_val();
diff --git a/libc/src/math/generic/log10p1bf16.cpp b/libc/src/math/generic/log10p1bf16.cpp
index 64a327b9347ead..c8ab4e325eadd2 100644
--- a/libc/src/math/generic/log10p1bf16.cpp
+++ b/libc/src/math/generic/log10p1bf16.cpp
@@ -1,10 +1,14 @@
-//===-- BFloat16 log10(1 + 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
//
//===----------------------------------------------------------------------===//
+/// \file
+/// Generic implementation of the log10p1bf16 function.
+//
+//===----------------------------------------------------------------------===//
#include "src/math/log10p1bf16.h"
#include "src/__support/math/log10p1bf16.h"
diff --git a/libc/src/math/log10p1bf16.h b/libc/src/math/log10p1bf16.h
index cc4e952df08d91..9e7f993e790f55 100644
--- a/libc/src/math/log10p1bf16.h
+++ b/libc/src/math/log10p1bf16.h
@@ -1,10 +1,14 @@
-//===-- Implementation header for log10p1bf16 -------------------*- 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
//
//===----------------------------------------------------------------------===//
+/// \file
+/// Declaration of the log10p1bf16 function.
+//
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_MATH_LOG10P1BF16_H
#define LLVM_LIBC_SRC_MATH_LOG10P1BF16_H
diff --git a/libc/test/src/math/log10p1bf16_test.cpp b/libc/test/src/math/log10p1bf16_test.cpp
index 4208e2348103c8..680b1ee9c65013 100644
--- a/libc/test/src/math/log10p1bf16_test.cpp
+++ b/libc/test/src/math/log10p1bf16_test.cpp
@@ -1,10 +1,14 @@
-//===-- Full range tests for BFloat16 log10(1 + 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
//
//===----------------------------------------------------------------------===//
+/// \file
+/// Full-range tests for the log10p1bf16 function.
+//
+//===----------------------------------------------------------------------===//
#include "src/__support/FPUtil/bfloat16.h"
#include "src/math/log10p1bf16.h"
diff --git a/libc/test/src/math/smoke/log10p1bf16_test.cpp b/libc/test/src/math/smoke/log10p1bf16_test.cpp
index c1dc695dfa9cb8..7f8a80365e502c 100644
--- a/libc/test/src/math/smoke/log10p1bf16_test.cpp
+++ b/libc/test/src/math/smoke/log10p1bf16_test.cpp
@@ -1,10 +1,14 @@
-//===-- Unittests for BFloat16 log10(1 + 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
//
//===----------------------------------------------------------------------===//
+/// \file
+/// Smoke tests for the log10p1bf16 function.
+//
+//===----------------------------------------------------------------------===//
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
>From 8a175a19fc541bd07a2fb625f9bae7f77ba1f560 Mon Sep 17 00:00:00 2001
From: prajin-uppala <cs24btech11064 at iith.ac.in>
Date: Wed, 28 Oct 2026 16:29:37 +0530
Subject: [PATCH 7/7] chore: update log10p1bf16 header documentation
---
libc/docs/headers/math/index.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/docs/headers/math/index.md b/libc/docs/headers/math/index.md
index 30aba90c60a9bc..f15c6f092f8bac 100644
--- a/libc/docs/headers/math/index.md
+++ b/libc/docs/headers/math/index.md
@@ -198,7 +198,7 @@ log
| lgamma | | | | {{ check }} | | | 7.12.8.3 | F.10.5.3 |
| log | {{ check }} | {{ check }} | | {{ check }} | | {{ check }} ? | 7.12.6.11 | F.10.3.11 |
| log10 | {{ check }} | {{ check }} | | {{ check }} | | | 7.12.6.12 | F.10.3.12 |
-| log10p1 | | | | {{ check }} | | | 7.12.6.13 | F.10.3.13 |
+| log10p1 | | | | {{ check }} | | {{ check }} | 7.12.6.13 | F.10.3.13 |
| log1p | {{ check }} | {{ check }} | | | | | 7.12.6.14 | F.10.3.14 |
| log2 | {{ check }} | {{ check }} | | {{ check }} | | | 7.12.6.15 | F.10.3.15 |
| log2p1 | | | | {{ check }} | | | 7.12.6.16 | F.10.3.16 |
More information about the libc-commits
mailing list