[libc-commits] [libc] [llvm] [libc][math][c++23] Add log10p1bf16 math function (PR #235343)
via libc-commits
libc-commits at lists.llvm.org
Sat Oct 24 12:41:32 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Uppala Prajin (prajin-uppala)
<details>
<summary>Changes</summary>
This PR adds the `log10p1bf16` math function to LLVM libc for the `bfloat16` type. It computes `log10(1 + x)` and handles special cases like NaN, infinity, zero, and the domain boundary at `x = -1`.
The implementation uses a polynomial approximation for small inputs and range reduction with a lookup table for other inputs. Special cases are handled to maintain the expected floating-point behavior, including exception behavior.
Added unit tests for accuracy, special values, and exception handling, along with smoke tests. Updated the relevant libc entrypoint lists, CMake files, and Bazel build files to integrate the function into both build systems.
Validated the implementation using the available CMake and Bazel build and test targets.
Fixes #<!-- -->234533
---
Patch is 29.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/235343.diff
32 Files Affected:
- (modified) libc/config/baremetal/aarch64/entrypoints.txt (+1)
- (modified) libc/config/baremetal/arm/entrypoints.txt (+1)
- (modified) libc/config/baremetal/hexagon/entrypoints.txt (+1)
- (modified) libc/config/baremetal/riscv/entrypoints.txt (+1)
- (modified) libc/config/darwin/aarch64/entrypoints.txt (+1)
- (modified) libc/config/darwin/x86_64/entrypoints.txt (+1)
- (modified) libc/config/freebsd/x86_64/entrypoints.txt (+1)
- (modified) libc/config/gpu/amdgpu/entrypoints.txt (+1)
- (modified) libc/config/gpu/nvptx/entrypoints.txt (+1)
- (modified) libc/config/linux/aarch64/entrypoints.txt (+1)
- (modified) libc/config/linux/arm/entrypoints.txt (+1)
- (modified) libc/config/linux/riscv/entrypoints.txt (+1)
- (modified) libc/config/linux/x86_64/entrypoints.txt (+1)
- (modified) libc/config/windows/entrypoints.txt (+1)
- (modified) libc/docs/headers/math/index.rst (+1-1)
- (modified) libc/shared/math.h (+1)
- (added) libc/shared/math/log10p1bf16.h (+23)
- (modified) libc/src/__support/math/CMakeLists.txt (+29)
- (added) libc/src/__support/math/log10p1bf16.h (+155)
- (modified) libc/src/math/CMakeLists.txt (+1)
- (modified) libc/src/math/generic/CMakeLists.txt (+11)
- (added) libc/src/math/generic/log10p1bf16.cpp (+18)
- (added) libc/src/math/log10p1bf16.h (+21)
- (modified) libc/test/shared/CMakeLists.txt (+1)
- (modified) libc/test/shared/shared_math_test.cpp (+2)
- (modified) libc/test/src/math/CMakeLists.txt (+13)
- (added) libc/test/src/math/log10p1bf16_test.cpp (+41)
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+14)
- (added) libc/test/src/math/smoke/log10p1bf16_test.cpp (+85)
- (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+25)
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel (+5)
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel (+5)
``````````diff
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 7ec212d8709692..816f150131c83b 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 779d9fc23b28e8..a14ba955a4f3d7 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 b847a2bb1f47f0..305a1a7d06009a 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 5600b82ad3410b..622990903587d4 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 8f6c178301c2f2..bfb88309896fa4 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 2eaef608e9a7ac..770ebf0c2272ea 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -727,6 +727,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 79d0c733ec3c01..b438bc225f1ad4 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -743,6 +743,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 be4d80db3afb37..b9d52a65bf679f 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1088,6 +1088,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 21488b488283b1..523bb38fe002d6 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -689,6 +689,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 20e33295bfb206..8c78b36093cb5a 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1166,6 +1166,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 7d7c3ad1e1768d..0bad07ed9ee70d 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1188,6 +1188,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 1712b2ad26fda4..20629fb55b86fd 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -404,6 +404,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/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 575c7bd1d1a10a..2b08d82d9da8ef 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -321,7 +321,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| 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 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
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 58f0730cba5756..aa58680fd0b25e 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
@@ -5505,6 +5516,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..b1de5fd6e10d3a
--- /dev/null
+++ b/libc/src/__support/math/log10p1bf16.h
@@ -0,0 +1,155 @@
+//===-- 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 {
+
+// 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 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,
+ 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,
+};
+
+// 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 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,
+ 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; 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()) {
+ 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();
+ }
+
+ // 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();
+ }
+
+ 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();
+ }
+
+ // 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);
+
+ 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..46e98ba38e4cdc 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -402,6 +402,7 @@ add_math_entrypoint_object(ldexpbf16)
add_math_entrypoint_object(log10)
add_math_entrypoint_object(log10f)
add_math_entrypoint_object(log10f16)
+add_math_entrypoint_object(log10p1bf16)
add_math_entrypoint_object(log10p1f16)
add_math_entrypoint_object(log1p)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 13cb65ff37e0b5..ae5e52d4ab38d9 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);
+
+} // namespa...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/235343
More information about the libc-commits
mailing list