[libc-commits] [libc] [libc][math][c++23] Add log10bf16 math function (PR #177269)
Krishna Pandey via libc-commits
libc-commits at lists.llvm.org
Sat Feb 21 10:34:38 PST 2026
https://github.com/krishna2803 updated https://github.com/llvm/llvm-project/pull/177269
>From edbf97d3e7cb8b513531cd542ca4181aa3633e87 Mon Sep 17 00:00:00 2001
From: Krishna Pandey <kpandey81930 at gmail.com>
Date: Thu, 22 Jan 2026 04:31:16 +0530
Subject: [PATCH 1/7] feat: implement log10bf16 higher math function
Signed-off-by: Krishna Pandey <kpandey81930 at gmail.com>
---
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/generic/CMakeLists.txt | 17 ++++
libc/src/math/generic/log10bf16.cpp | 146 +++++++++++++++++++++++++++
libc/src/math/log10bf16.h | 21 ++++
4 files changed, 185 insertions(+)
create mode 100644 libc/src/math/generic/log10bf16.cpp
create mode 100644 libc/src/math/log10bf16.h
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index e37e22fdb58e6..30b7afbf4e53e 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -381,6 +381,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(log10bf16)
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 6e58434415ead..9d9e6f256872b 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1997,6 +1997,23 @@ add_entrypoint_object(
libc.src.__support.math.expxf16_utils
)
+add_entrypoint_object(
+ log10bf16
+ SRCS
+ log10bf16.cpp
+ HDRS
+ ../log10bf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.except_value_utils
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+)
+
add_entrypoint_object(
log1p
SRCS
diff --git a/libc/src/math/generic/log10bf16.cpp b/libc/src/math/generic/log10bf16.cpp
new file mode 100644
index 0000000000000..4bae8e66cc80f
--- /dev/null
+++ b/libc/src/math/generic/log10bf16.cpp
@@ -0,0 +1,146 @@
+//===-- BFloat16 log10(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/log10bf16.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// Generated by Sollya with the following commands:
+// > display = hexadecimal;
+// > round(log10(2), SG, RN);
+static constexpr float LOG10F_2 = 0x1.344136p-2f;
+
+// Generated by Sollya with the following commands:
+// > display = hexadecimal;
+// > for i from 0 to 127 do print(round(log(1 + i * 2^-7), SG, RN));
+static constexpr float LOG10F_1_PLUS_M[128] = {
+ 0x0.0p0f, 0x1.bafd48p-9f, 0x1.b9476ap-8f, 0x1.49b086p-7f,
+ 0x1.b5e908p-7f, 0x1.10a83ap-6f, 0x1.45f4f6p-6f, 0x1.7adc3ep-6f,
+ 0x1.af5f92p-6f, 0x1.e3806ap-6f, 0x1.0ba01ap-5f, 0x1.25502cp-5f,
+ 0x1.3ed11ap-5f, 0x1.58238ep-5f, 0x1.714834p-5f, 0x1.8a3faep-5f,
+ 0x1.a30a9ep-5f, 0x1.bba9ap-5f, 0x1.d41d52p-5f, 0x1.ec6648p-5f,
+ 0x1.02428cp-4f, 0x1.0e3d2ap-4f, 0x1.1a2344p-4f, 0x1.25f522p-4f,
+ 0x1.31b306p-4f, 0x1.3d5d34p-4f, 0x1.48f3eep-4f, 0x1.547774p-4f,
+ 0x1.5fe804p-4f, 0x1.6b45ep-4f, 0x1.76914p-4f, 0x1.81ca64p-4f,
+ 0x1.8cf184p-4f, 0x1.9806dap-4f, 0x1.a30a9ep-4f, 0x1.adfd08p-4f,
+ 0x1.b8de4ep-4f, 0x1.c3aea4p-4f, 0x1.ce6e42p-4f, 0x1.d91d58p-4f,
+ 0x1.e3bc1ap-4f, 0x1.ee4abap-4f, 0x1.f8c968p-4f, 0x1.019c2ap-3f,
+ 0x1.06cbd6p-3f, 0x1.0bf3dp-3f, 0x1.11143p-3f, 0x1.162d08p-3f,
+ 0x1.1b3e72p-3f, 0x1.204882p-3f, 0x1.254b4ep-3f, 0x1.2a46e8p-3f,
+ 0x1.2f3b6ap-3f, 0x1.3428e2p-3f, 0x1.390f68p-3f, 0x1.3def0ep-3f,
+ 0x1.42c7e8p-3f, 0x1.479a08p-3f, 0x1.4c658p-3f, 0x1.512a64p-3f,
+ 0x1.55e8c6p-3f, 0x1.5aa0b4p-3f, 0x1.5f5244p-3f, 0x1.63fd86p-3f,
+ 0x1.68a288p-3f, 0x1.6d415ep-3f, 0x1.71da18p-3f, 0x1.766cc4p-3f,
+ 0x1.7af974p-3f, 0x1.7f8036p-3f, 0x1.84011ap-3f, 0x1.887c2ep-3f,
+ 0x1.8cf184p-3f, 0x1.916128p-3f, 0x1.95cb28p-3f, 0x1.9a2f96p-3f,
+ 0x1.9e8e7cp-3f, 0x1.a2e7e8p-3f, 0x1.a73beap-3f, 0x1.ab8a9p-3f,
+ 0x1.afd3e4p-3f, 0x1.b417f4p-3f, 0x1.b856dp-3f, 0x1.bc908p-3f,
+ 0x1.c0c514p-3f, 0x1.c4f496p-3f, 0x1.c91f14p-3f, 0x1.cd4498p-3f,
+ 0x1.d1653p-3f, 0x1.d580e6p-3f, 0x1.d997c8p-3f, 0x1.dda9dep-3f,
+ 0x1.e1b734p-3f, 0x1.e5bfd6p-3f, 0x1.e9c3cep-3f, 0x1.edc328p-3f,
+ 0x1.f1bdeep-3f, 0x1.f5b42ap-3f, 0x1.f9a5e8p-3f, 0x1.fd933p-3f,
+ 0x1.00be06p-2f, 0x1.02b044p-2f, 0x1.04a054p-2f, 0x1.068e4p-2f,
+ 0x1.087a08p-2f, 0x1.0a63b4p-2f, 0x1.0c4b46p-2f, 0x1.0e30c4p-2f,
+ 0x1.101432p-2f, 0x1.11f594p-2f, 0x1.13d4fp-2f, 0x1.15b24ap-2f,
+ 0x1.178da6p-2f, 0x1.196706p-2f, 0x1.1b3e72p-2f, 0x1.1d13ecp-2f,
+ 0x1.1ee778p-2f, 0x1.20b91ap-2f, 0x1.2288d8p-2f, 0x1.2456b4p-2f,
+ 0x1.2622bp-2f, 0x1.27ecd4p-2f, 0x1.29b522p-2f, 0x1.2b7b9ep-2f,
+ 0x1.2d404cp-2f, 0x1.2f032cp-2f, 0x1.30c448p-2f, 0x1.32839ep-2f,
+};
+
+constexpr fputil::ExceptValues<bfloat16, 4> EXPBF16_EXCEPTS = {{
+ // x = 0x4120 (10.0)
+ {0x4120U, 0x3F80U, 0U, 0U, 0U},
+ // x = 0x42C8 (100.0)
+ {0x42C8U, 0x4000U, 0U, 0U, 0U},
+ // x =0x447A (1000.0)
+ {0x447AU, 0x4040U, 0U, 0U, 0U},
+}};
+
+LLVM_LIBC_FUNCTION(bfloat16, log10bf16, (bfloat16 x)) {
+ using FPBits = fputil::FPBits<bfloat16>;
+ FPBits x_bits(x);
+
+ uint16_t x_u = x_bits.uintval();
+
+ // If x <= 0, or x is 1, or x is +inf, or x is NaN.
+ if (LIBC_UNLIKELY(x_u == 0U || x_u == 0x3f80U || x_u >= 0x7f80U)) {
+ // log(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;
+ }
+
+ // log(+/-0) = −inf
+ if ((x_u & 0x7fffU) == 0U) {
+ fputil::raise_except_if_required(FE_DIVBYZERO);
+ return FPBits::inf(Sign::NEG).get_val();
+ }
+
+ // log(1) = 0
+ if (x_u == 0x3f80U)
+ return FPBits::zero().get_val();
+
+ // x < 0
+ if (x_u > 0x8000U) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ // log(+inf) = +inf
+ return FPBits::inf().get_val();
+ }
+
+ if (fputil::fenv_is_round_up()) {
+ if (auto r = EXPBF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ }
+
+ int e = -FPBits::EXP_BIAS;
+
+ // When x is subnormal, normalize it.
+ if ((x_u & FPBits::EXP_MASK) == 0U) {
+ // Can't pass an integer to fputil::cast directly.
+ constexpr float NORMALIZE_EXP = 1U << FPBits::FRACTION_LEN;
+ x_bits = FPBits(x_bits.get_val() * fputil::cast<bfloat16>(NORMALIZE_EXP));
+ x_u = x_bits.uintval();
+ e -= FPBits::FRACTION_LEN;
+ }
+
+ // To compute log10(x), we perform the following range reduction:
+ // x = 2^e * (1 + m),
+ // log10(x) = e * log10(2) + log10(1 + m).
+ // for BFloat16, mantissa is at most 7 explicit bits, so we lookup
+ // log10(1 + m) in LOG10F_1_PLUS_M table using `m` as key.
+
+ // Get the 7-bit mantissa directly as the table index
+ uint16_t m = x_bits.get_mantissa();
+
+ // Get unbiased exponent
+ e += x_u >> FPBits::FRACTION_LEN;
+
+ return fputil::cast<bfloat16>(fputil::multiply_add(
+ static_cast<float>(e), LOG10F_2, LOG10F_1_PLUS_M[m]));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/log10bf16.h b/libc/src/math/log10bf16.h
new file mode 100644
index 0000000000000..9ee9846afdea3
--- /dev/null
+++ b/libc/src/math/log10bf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for log10bf16 ---------------------*- 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_LOG10BF16_H
+#define LLVM_LIBC_SRC_MATH_LOG10BF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 log10bf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LOG10BF16_H
>From b640ff32f1e89e48e46f95ff7b4980cde58d047e Mon Sep 17 00:00:00 2001
From: Krishna Pandey <kpandey81930 at gmail.com>
Date: Thu, 22 Jan 2026 04:31:48 +0530
Subject: [PATCH 2/7] chore: add smoke and general tests for log10bf16 higher
math function
Signed-off-by: Krishna Pandey <kpandey81930 at gmail.com>
---
libc/test/src/math/CMakeLists.txt | 12 +++++
libc/test/src/math/log10bf16_test.cpp | 41 ++++++++++++++++
libc/test/src/math/smoke/CMakeLists.txt | 13 ++++++
libc/test/src/math/smoke/log10bf16_test.cpp | 52 +++++++++++++++++++++
4 files changed, 118 insertions(+)
create mode 100644 libc/test/src/math/log10bf16_test.cpp
create mode 100644 libc/test/src/math/smoke/log10bf16_test.cpp
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index ff5c511922171..4767becd56d60 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2163,6 +2163,18 @@ add_fp_unittest(
libc.src.math.log10f16
)
+add_fp_unittest(
+ log10bf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ log10bf16_test.cpp
+ DEPENDS
+ libc.src.math.log10bf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_fp_unittest(
log1p_test
NEED_MPFR
diff --git a/libc/test/src/math/log10bf16_test.cpp b/libc/test/src/math/log10bf16_test.cpp
new file mode 100644
index 0000000000000..45e64fb725ae3
--- /dev/null
+++ b/libc/test/src/math/log10bf16_test.cpp
@@ -0,0 +1,41 @@
+//===-- Full range tests for BFloat16 log10(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/log10bf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcLogBf16Test = 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(LlvmLibcLogBf16Test, PositiveRange) {
+ for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+ bfloat16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10, x,
+ LIBC_NAMESPACE::log10bf16(x), 0.5);
+ }
+}
+
+TEST_F(LlvmLibcLogBf16Test, NegativeRange) {
+ for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+ bfloat16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10, x,
+ LIBC_NAMESPACE::log10bf16(x), 0.5);
+ }
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 5afd3a9f22967..4688d457430d7 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4442,6 +4442,19 @@ add_fp_unittest(
libc.src.__support.FPUtil.cast
)
+add_fp_unittest(
+ log10bf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ log10bf16_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.log10bf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_fp_unittest(
log1p_test
SUITE
diff --git a/libc/test/src/math/smoke/log10bf16_test.cpp b/libc/test/src/math/smoke/log10bf16_test.cpp
new file mode 100644
index 0000000000000..2c4c3b5876252
--- /dev/null
+++ b/libc/test/src/math/smoke/log10bf16_test.cpp
@@ -0,0 +1,52 @@
+//===-- Unittests for BFloat16 log10(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/bfloat16.h"
+#include "src/__support/macros/properties/types.h"
+#include "src/math/log10bf16.h"
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+class LlvmLibcLogBf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+ DECLARE_SPECIAL_CONSTANTS(bfloat16)
+
+public:
+ void test_special_numbers() {
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::log10bf16(aNaN));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::log10bf16(sNaN),
+ FE_INVALID);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::log10bf16(inf));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::log10bf16(neg_inf));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ neg_inf, LIBC_NAMESPACE::log10bf16(zero), FE_DIVBYZERO);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ neg_inf, LIBC_NAMESPACE::log10bf16(neg_zero), FE_DIVBYZERO);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::log10bf16(bfloat16(1.0)));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::log10bf16(bfloat16(-1.0)));
+ EXPECT_MATH_ERRNO(EDOM);
+ }
+};
+
+TEST_F(LlvmLibcLogBf16Test, SpecialNumbers) { test_special_numbers(); }
>From 8c56e1fb87bb93a1b38098f688ab57e474dbf0d0 Mon Sep 17 00:00:00 2001
From: Krishna Pandey <kpandey81930 at gmail.com>
Date: Thu, 22 Jan 2026 04:33:08 +0530
Subject: [PATCH 3/7] chore: update entrypoints
Signed-off-by: Krishna Pandey <kpandey81930 at gmail.com>
---
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/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 +
12 files changed, 12 insertions(+)
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 742d96761c415..adf5e5470785c 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -817,6 +817,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 95cb0dea8e49e..ae495aef6cdd2 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -820,6 +820,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 3fc71280f5163..cfbfa072bb2f3 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -818,6 +818,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 3909417f9730d..d849f424cbf82 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -634,6 +634,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 e899bf97ea3f6..e52243ebcabaa 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -276,6 +276,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 0dda7d5c683ec..a88774f23f4de 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -659,6 +659,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 6070fb5b17b3c..7a7394cf838ce 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -661,6 +661,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 970c825bbfc96..f89ccf9fe22fc 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -890,6 +890,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 f04ac40145d3a..4969f47e09c4a 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -503,6 +503,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 7baf4de9d8a5b..4d6bfb1682378 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -911,6 +911,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 9399b284fa2da..53b9085afbae6 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -957,6 +957,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
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 3a76595b258e2..f1ceb56b11c69 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -349,6 +349,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llogbbf16
libc.src.math.llrintbf16
libc.src.math.llroundbf16
+ libc.src.math.log10bf16
libc.src.math.log_bf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
>From c6bd25e37852a6f7e61a4e8700051cb5dc321096 Mon Sep 17 00:00:00 2001
From: Krishna Pandey <kpandey81930 at gmail.com>
Date: Thu, 22 Jan 2026 04:33:53 +0530
Subject: [PATCH 4/7] docs: add log10bf16 higher math function
Signed-off-by: Krishna Pandey <kpandey81930 at gmail.com>
---
libc/docs/headers/math/index.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 51bb17ff8dab6..f03a626894c01 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -321,7 +321,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| 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 |
+| log10 | |check| | |check| | | |check| | | |check| | 7.12.6.12 | F.10.3.12 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| log10p1 | | | | | | | 7.12.6.13 | F.10.3.13 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
@@ -636,4 +636,4 @@ References
* `The GNU C Library (glibc) <https://www.gnu.org/software/libc/>`_.
* `The GNU MPFR Library <https://www.mpfr.org/>`_.
* `C++23 Standard <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf>`_.
-* `BFloat16 <https://en.wikipedia.org/wiki/Bfloat16_floating-point_format>`_.
\ No newline at end of file
+* `BFloat16 <https://en.wikipedia.org/wiki/Bfloat16_floating-point_format>`_.
>From 683c8ce12ec6528246d5097c2f10d4e222c571c7 Mon Sep 17 00:00:00 2001
From: Krishna Pandey <kpandey81930 at gmail.com>
Date: Thu, 5 Feb 2026 00:45:47 +0530
Subject: [PATCH 5/7] refactor: header only log10bf16
Signed-off-by: Krishna Pandey <kpandey81930 at gmail.com>
---
libc/shared/math.h | 1 +
libc/shared/math/log10bf16.h | 23 ++++
libc/src/__support/math/CMakeLists.txt | 15 +++
libc/src/__support/math/log10bf16.h | 154 +++++++++++++++++++++++++
libc/src/math/generic/CMakeLists.txt | 9 +-
libc/src/math/generic/log10bf16.cpp | 133 +--------------------
6 files changed, 196 insertions(+), 139 deletions(-)
create mode 100644 libc/shared/math/log10bf16.h
create mode 100644 libc/src/__support/math/log10bf16.h
diff --git a/libc/shared/math.h b/libc/shared/math.h
index bad2b07ecb993..419fcdc5eea98 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -74,6 +74,7 @@
#include "math/llogbf.h"
#include "math/log.h"
#include "math/log10.h"
+#include "math/log10bf16.h"
#include "math/log1p.h"
#include "math/log2.h"
#include "math/logbf.h"
diff --git a/libc/shared/math/log10bf16.h b/libc/shared/math/log10bf16.h
new file mode 100644
index 0000000000000..1bb1442212318
--- /dev/null
+++ b/libc/shared/math/log10bf16.h
@@ -0,0 +1,23 @@
+//===-- Shared log10bf16 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_LOG10BF16_H
+#define LLVM_LIBC_SHARED_MATH_LOG10BF16_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/log10bf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::log10bf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_LOG10BF16_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index bcc5b1024b8da..19cabd2b87e70 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -1139,6 +1139,21 @@ add_header_library(
libc.src.__support.macros.optimization
)
+add_header_library(
+ log10bf16
+ HDRS
+ log10bf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.except_value_utils
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+)
+
add_header_library(
log1p
HDRS
diff --git a/libc/src/__support/math/log10bf16.h b/libc/src/__support/math/log10bf16.h
new file mode 100644
index 0000000000000..e04b7fe885071
--- /dev/null
+++ b/libc/src/__support/math/log10bf16.h
@@ -0,0 +1,154 @@
+//===-- Implementation header for BFloat16 log10(x) 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_SRC___SUPPORT_MATH_LOG10BF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_LOG10BF16_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+// Generated by Sollya with the following commands:
+// > display = hexadecimal;
+// > round(log10(2), SG, RN);
+static constexpr float LOG10F_2 = 0x1.344136p-2f;
+
+// Generated by Sollya with the following commands:
+// > display = hexadecimal;
+// > for i from 0 to 127 do print(round(log(1 + i * 2^-7), SG, RN));
+static constexpr float LOG10F_1_PLUS_M[128] = {
+ 0x0.0p0f, 0x1.bafd48p-9f, 0x1.b9476ap-8f, 0x1.49b086p-7f,
+ 0x1.b5e908p-7f, 0x1.10a83ap-6f, 0x1.45f4f6p-6f, 0x1.7adc3ep-6f,
+ 0x1.af5f92p-6f, 0x1.e3806ap-6f, 0x1.0ba01ap-5f, 0x1.25502cp-5f,
+ 0x1.3ed11ap-5f, 0x1.58238ep-5f, 0x1.714834p-5f, 0x1.8a3faep-5f,
+ 0x1.a30a9ep-5f, 0x1.bba9ap-5f, 0x1.d41d52p-5f, 0x1.ec6648p-5f,
+ 0x1.02428cp-4f, 0x1.0e3d2ap-4f, 0x1.1a2344p-4f, 0x1.25f522p-4f,
+ 0x1.31b306p-4f, 0x1.3d5d34p-4f, 0x1.48f3eep-4f, 0x1.547774p-4f,
+ 0x1.5fe804p-4f, 0x1.6b45ep-4f, 0x1.76914p-4f, 0x1.81ca64p-4f,
+ 0x1.8cf184p-4f, 0x1.9806dap-4f, 0x1.a30a9ep-4f, 0x1.adfd08p-4f,
+ 0x1.b8de4ep-4f, 0x1.c3aea4p-4f, 0x1.ce6e42p-4f, 0x1.d91d58p-4f,
+ 0x1.e3bc1ap-4f, 0x1.ee4abap-4f, 0x1.f8c968p-4f, 0x1.019c2ap-3f,
+ 0x1.06cbd6p-3f, 0x1.0bf3dp-3f, 0x1.11143p-3f, 0x1.162d08p-3f,
+ 0x1.1b3e72p-3f, 0x1.204882p-3f, 0x1.254b4ep-3f, 0x1.2a46e8p-3f,
+ 0x1.2f3b6ap-3f, 0x1.3428e2p-3f, 0x1.390f68p-3f, 0x1.3def0ep-3f,
+ 0x1.42c7e8p-3f, 0x1.479a08p-3f, 0x1.4c658p-3f, 0x1.512a64p-3f,
+ 0x1.55e8c6p-3f, 0x1.5aa0b4p-3f, 0x1.5f5244p-3f, 0x1.63fd86p-3f,
+ 0x1.68a288p-3f, 0x1.6d415ep-3f, 0x1.71da18p-3f, 0x1.766cc4p-3f,
+ 0x1.7af974p-3f, 0x1.7f8036p-3f, 0x1.84011ap-3f, 0x1.887c2ep-3f,
+ 0x1.8cf184p-3f, 0x1.916128p-3f, 0x1.95cb28p-3f, 0x1.9a2f96p-3f,
+ 0x1.9e8e7cp-3f, 0x1.a2e7e8p-3f, 0x1.a73beap-3f, 0x1.ab8a9p-3f,
+ 0x1.afd3e4p-3f, 0x1.b417f4p-3f, 0x1.b856dp-3f, 0x1.bc908p-3f,
+ 0x1.c0c514p-3f, 0x1.c4f496p-3f, 0x1.c91f14p-3f, 0x1.cd4498p-3f,
+ 0x1.d1653p-3f, 0x1.d580e6p-3f, 0x1.d997c8p-3f, 0x1.dda9dep-3f,
+ 0x1.e1b734p-3f, 0x1.e5bfd6p-3f, 0x1.e9c3cep-3f, 0x1.edc328p-3f,
+ 0x1.f1bdeep-3f, 0x1.f5b42ap-3f, 0x1.f9a5e8p-3f, 0x1.fd933p-3f,
+ 0x1.00be06p-2f, 0x1.02b044p-2f, 0x1.04a054p-2f, 0x1.068e4p-2f,
+ 0x1.087a08p-2f, 0x1.0a63b4p-2f, 0x1.0c4b46p-2f, 0x1.0e30c4p-2f,
+ 0x1.101432p-2f, 0x1.11f594p-2f, 0x1.13d4fp-2f, 0x1.15b24ap-2f,
+ 0x1.178da6p-2f, 0x1.196706p-2f, 0x1.1b3e72p-2f, 0x1.1d13ecp-2f,
+ 0x1.1ee778p-2f, 0x1.20b91ap-2f, 0x1.2288d8p-2f, 0x1.2456b4p-2f,
+ 0x1.2622bp-2f, 0x1.27ecd4p-2f, 0x1.29b522p-2f, 0x1.2b7b9ep-2f,
+ 0x1.2d404cp-2f, 0x1.2f032cp-2f, 0x1.30c448p-2f, 0x1.32839ep-2f,
+};
+
+constexpr fputil::ExceptValues<bfloat16, 4> EXPBF16_EXCEPTS = {{
+ // x = 0x4120 (10.0)
+ {0x4120U, 0x3F80U, 0U, 0U, 0U},
+ // x = 0x42C8 (100.0)
+ {0x42C8U, 0x4000U, 0U, 0U, 0U},
+ // x =0x447A (1000.0)
+ {0x447AU, 0x4040U, 0U, 0U, 0U},
+}};
+
+LLVM_LIBC_FUNCTION(bfloat16, log10bf16, (bfloat16 x)) {
+ using FPBits = fputil::FPBits<bfloat16>;
+ FPBits x_bits(x);
+
+ uint16_t x_u = x_bits.uintval();
+
+ // If x <= 0, or x is 1, or x is +inf, or x is NaN.
+ if (LIBC_UNLIKELY(x_u == 0U || x_u == 0x3f80U || x_u >= 0x7f80U)) {
+ // log(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;
+ }
+
+ // log(+/-0) = −inf
+ if ((x_u & 0x7fffU) == 0U) {
+ fputil::raise_except_if_required(FE_DIVBYZERO);
+ return FPBits::inf(Sign::NEG).get_val();
+ }
+
+ // log(1) = 0
+ if (x_u == 0x3f80U)
+ return FPBits::zero().get_val();
+
+ // x < 0
+ if (x_u > 0x8000U) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ // log(+inf) = +inf
+ return FPBits::inf().get_val();
+ }
+
+ if (fputil::fenv_is_round_up()) {
+ if (auto r = EXPBF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ }
+
+ int e = -FPBits::EXP_BIAS;
+
+ // When x is subnormal, normalize it.
+ if ((x_u & FPBits::EXP_MASK) == 0U) {
+ // Can't pass an integer to fputil::cast directly.
+ constexpr float NORMALIZE_EXP = 1U << FPBits::FRACTION_LEN;
+ x_bits = FPBits(x_bits.get_val() * fputil::cast<bfloat16>(NORMALIZE_EXP));
+ x_u = x_bits.uintval();
+ e -= FPBits::FRACTION_LEN;
+ }
+
+ // To compute log10(x), we perform the following range reduction:
+ // x = 2^e * (1 + m),
+ // log10(x) = e * log10(2) + log10(1 + m).
+ // for BFloat16, mantissa is at most 7 explicit bits, so we lookup
+ // log10(1 + m) in LOG10F_1_PLUS_M table using `m` as key.
+
+ // Get the 7-bit mantissa directly as the table index
+ uint16_t m = x_bits.get_mantissa();
+
+ // Get unbiased exponent
+ e += x_u >> FPBits::FRACTION_LEN;
+
+ return fputil::cast<bfloat16>(fputil::multiply_add(
+ static_cast<float>(e), LOG10F_2, LOG10F_1_PLUS_M[m]));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LOG10BF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 9d9e6f256872b..b8e8040b5af4a 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -2004,14 +2004,7 @@ add_entrypoint_object(
HDRS
../log10bf16.h
DEPENDS
- libc.src.__support.common
- libc.src.__support.FPUtil.bfloat16
- libc.src.__support.FPUtil.cast
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.macros.config
- libc.src.__support.macros.optimization
+ libc.src.__support.math.log10bf16
)
add_entrypoint_object(
diff --git a/libc/src/math/generic/log10bf16.cpp b/libc/src/math/generic/log10bf16.cpp
index 4bae8e66cc80f..8d22eb1e4418a 100644
--- a/libc/src/math/generic/log10bf16.cpp
+++ b/libc/src/math/generic/log10bf16.cpp
@@ -7,140 +7,11 @@
//===----------------------------------------------------------------------===//
#include "src/math/log10bf16.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/bfloat16.h"
-#include "src/__support/FPUtil/cast.h"
-#include "src/__support/FPUtil/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/rounding_mode.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h"
-#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/log10bf16.h"
namespace LIBC_NAMESPACE_DECL {
-
-// Generated by Sollya with the following commands:
-// > display = hexadecimal;
-// > round(log10(2), SG, RN);
-static constexpr float LOG10F_2 = 0x1.344136p-2f;
-
-// Generated by Sollya with the following commands:
-// > display = hexadecimal;
-// > for i from 0 to 127 do print(round(log(1 + i * 2^-7), SG, RN));
-static constexpr float LOG10F_1_PLUS_M[128] = {
- 0x0.0p0f, 0x1.bafd48p-9f, 0x1.b9476ap-8f, 0x1.49b086p-7f,
- 0x1.b5e908p-7f, 0x1.10a83ap-6f, 0x1.45f4f6p-6f, 0x1.7adc3ep-6f,
- 0x1.af5f92p-6f, 0x1.e3806ap-6f, 0x1.0ba01ap-5f, 0x1.25502cp-5f,
- 0x1.3ed11ap-5f, 0x1.58238ep-5f, 0x1.714834p-5f, 0x1.8a3faep-5f,
- 0x1.a30a9ep-5f, 0x1.bba9ap-5f, 0x1.d41d52p-5f, 0x1.ec6648p-5f,
- 0x1.02428cp-4f, 0x1.0e3d2ap-4f, 0x1.1a2344p-4f, 0x1.25f522p-4f,
- 0x1.31b306p-4f, 0x1.3d5d34p-4f, 0x1.48f3eep-4f, 0x1.547774p-4f,
- 0x1.5fe804p-4f, 0x1.6b45ep-4f, 0x1.76914p-4f, 0x1.81ca64p-4f,
- 0x1.8cf184p-4f, 0x1.9806dap-4f, 0x1.a30a9ep-4f, 0x1.adfd08p-4f,
- 0x1.b8de4ep-4f, 0x1.c3aea4p-4f, 0x1.ce6e42p-4f, 0x1.d91d58p-4f,
- 0x1.e3bc1ap-4f, 0x1.ee4abap-4f, 0x1.f8c968p-4f, 0x1.019c2ap-3f,
- 0x1.06cbd6p-3f, 0x1.0bf3dp-3f, 0x1.11143p-3f, 0x1.162d08p-3f,
- 0x1.1b3e72p-3f, 0x1.204882p-3f, 0x1.254b4ep-3f, 0x1.2a46e8p-3f,
- 0x1.2f3b6ap-3f, 0x1.3428e2p-3f, 0x1.390f68p-3f, 0x1.3def0ep-3f,
- 0x1.42c7e8p-3f, 0x1.479a08p-3f, 0x1.4c658p-3f, 0x1.512a64p-3f,
- 0x1.55e8c6p-3f, 0x1.5aa0b4p-3f, 0x1.5f5244p-3f, 0x1.63fd86p-3f,
- 0x1.68a288p-3f, 0x1.6d415ep-3f, 0x1.71da18p-3f, 0x1.766cc4p-3f,
- 0x1.7af974p-3f, 0x1.7f8036p-3f, 0x1.84011ap-3f, 0x1.887c2ep-3f,
- 0x1.8cf184p-3f, 0x1.916128p-3f, 0x1.95cb28p-3f, 0x1.9a2f96p-3f,
- 0x1.9e8e7cp-3f, 0x1.a2e7e8p-3f, 0x1.a73beap-3f, 0x1.ab8a9p-3f,
- 0x1.afd3e4p-3f, 0x1.b417f4p-3f, 0x1.b856dp-3f, 0x1.bc908p-3f,
- 0x1.c0c514p-3f, 0x1.c4f496p-3f, 0x1.c91f14p-3f, 0x1.cd4498p-3f,
- 0x1.d1653p-3f, 0x1.d580e6p-3f, 0x1.d997c8p-3f, 0x1.dda9dep-3f,
- 0x1.e1b734p-3f, 0x1.e5bfd6p-3f, 0x1.e9c3cep-3f, 0x1.edc328p-3f,
- 0x1.f1bdeep-3f, 0x1.f5b42ap-3f, 0x1.f9a5e8p-3f, 0x1.fd933p-3f,
- 0x1.00be06p-2f, 0x1.02b044p-2f, 0x1.04a054p-2f, 0x1.068e4p-2f,
- 0x1.087a08p-2f, 0x1.0a63b4p-2f, 0x1.0c4b46p-2f, 0x1.0e30c4p-2f,
- 0x1.101432p-2f, 0x1.11f594p-2f, 0x1.13d4fp-2f, 0x1.15b24ap-2f,
- 0x1.178da6p-2f, 0x1.196706p-2f, 0x1.1b3e72p-2f, 0x1.1d13ecp-2f,
- 0x1.1ee778p-2f, 0x1.20b91ap-2f, 0x1.2288d8p-2f, 0x1.2456b4p-2f,
- 0x1.2622bp-2f, 0x1.27ecd4p-2f, 0x1.29b522p-2f, 0x1.2b7b9ep-2f,
- 0x1.2d404cp-2f, 0x1.2f032cp-2f, 0x1.30c448p-2f, 0x1.32839ep-2f,
-};
-
-constexpr fputil::ExceptValues<bfloat16, 4> EXPBF16_EXCEPTS = {{
- // x = 0x4120 (10.0)
- {0x4120U, 0x3F80U, 0U, 0U, 0U},
- // x = 0x42C8 (100.0)
- {0x42C8U, 0x4000U, 0U, 0U, 0U},
- // x =0x447A (1000.0)
- {0x447AU, 0x4040U, 0U, 0U, 0U},
-}};
-
LLVM_LIBC_FUNCTION(bfloat16, log10bf16, (bfloat16 x)) {
- using FPBits = fputil::FPBits<bfloat16>;
- FPBits x_bits(x);
-
- uint16_t x_u = x_bits.uintval();
-
- // If x <= 0, or x is 1, or x is +inf, or x is NaN.
- if (LIBC_UNLIKELY(x_u == 0U || x_u == 0x3f80U || x_u >= 0x7f80U)) {
- // log(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;
- }
-
- // log(+/-0) = −inf
- if ((x_u & 0x7fffU) == 0U) {
- fputil::raise_except_if_required(FE_DIVBYZERO);
- return FPBits::inf(Sign::NEG).get_val();
- }
-
- // log(1) = 0
- if (x_u == 0x3f80U)
- return FPBits::zero().get_val();
-
- // x < 0
- if (x_u > 0x8000U) {
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- // log(+inf) = +inf
- return FPBits::inf().get_val();
- }
-
- if (fputil::fenv_is_round_up()) {
- if (auto r = EXPBF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
- return r.value();
- }
-
- int e = -FPBits::EXP_BIAS;
-
- // When x is subnormal, normalize it.
- if ((x_u & FPBits::EXP_MASK) == 0U) {
- // Can't pass an integer to fputil::cast directly.
- constexpr float NORMALIZE_EXP = 1U << FPBits::FRACTION_LEN;
- x_bits = FPBits(x_bits.get_val() * fputil::cast<bfloat16>(NORMALIZE_EXP));
- x_u = x_bits.uintval();
- e -= FPBits::FRACTION_LEN;
- }
-
- // To compute log10(x), we perform the following range reduction:
- // x = 2^e * (1 + m),
- // log10(x) = e * log10(2) + log10(1 + m).
- // for BFloat16, mantissa is at most 7 explicit bits, so we lookup
- // log10(1 + m) in LOG10F_1_PLUS_M table using `m` as key.
-
- // Get the 7-bit mantissa directly as the table index
- uint16_t m = x_bits.get_mantissa();
-
- // Get unbiased exponent
- e += x_u >> FPBits::FRACTION_LEN;
-
- return fputil::cast<bfloat16>(fputil::multiply_add(
- static_cast<float>(e), LOG10F_2, LOG10F_1_PLUS_M[m]));
+ return math::log10bf16(x);
}
} // namespace LIBC_NAMESPACE_DECL
>From 84fe15ed20d55eae01bf1f1afa6508254454937c Mon Sep 17 00:00:00 2001
From: Krishna Pandey <kpandey81930 at gmail.com>
Date: Thu, 5 Feb 2026 00:46:10 +0530
Subject: [PATCH 6/7] chore: add shader tests for log10bf16
Signed-off-by: Krishna Pandey <kpandey81930 at gmail.com>
---
libc/test/shared/CMakeLists.txt | 1 +
libc/test/shared/shared_math_test.cpp | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 3fc36ed0c2198..464ce2b2f8107 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -67,6 +67,7 @@ add_fp_unittest(
libc.src.__support.math.ldexpf
libc.src.__support.math.log
libc.src.__support.math.log10
+ libc.src.__support.math.log10bf16
libc.src.__support.math.log1p
libc.src.__support.math.log2
libc.src.__support.math.logbf
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 45ba79de87226..aeb77c825a317 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "shared/math.h"
+#include "src/__support/macros/properties/types.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -134,3 +135,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat128) {
}
#endif // LIBC_TYPES_HAS_FLOAT128
+
+TEST(LlvmLibcSharedMathTest, AllBFloat16) {
+ EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::log10bf16(bfloat16(1.0)));
+}
>From ac20abd35f4a3b760c443e13d51a15ac4f30a380 Mon Sep 17 00:00:00 2001
From: Krishna Pandey <kpandey81930 at gmail.com>
Date: Thu, 5 Feb 2026 00:55:46 +0530
Subject: [PATCH 7/7] fix: headers and mangling issue
Signed-off-by: Krishna Pandey <kpandey81930 at gmail.com>
---
libc/src/__support/math/CMakeLists.txt | 1 +
libc/src/__support/math/log10bf16.h | 3 +--
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 19cabd2b87e70..ae1b6cdbad141 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -1150,6 +1150,7 @@ add_header_library(
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.config
libc.src.__support.macros.optimization
)
diff --git a/libc/src/__support/math/log10bf16.h b/libc/src/__support/math/log10bf16.h
index e04b7fe885071..63a5a6dadfb67 100644
--- a/libc/src/__support/math/log10bf16.h
+++ b/libc/src/__support/math/log10bf16.h
@@ -18,7 +18,6 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
-#include "src/__support/macros/properties/types.h"
namespace LIBC_NAMESPACE_DECL {
@@ -76,7 +75,7 @@ constexpr fputil::ExceptValues<bfloat16, 4> EXPBF16_EXCEPTS = {{
{0x447AU, 0x4040U, 0U, 0U, 0U},
}};
-LLVM_LIBC_FUNCTION(bfloat16, log10bf16, (bfloat16 x)) {
+LIBC_INLINE static bfloat16 log10bf16(bfloat16 x) {
using FPBits = fputil::FPBits<bfloat16>;
FPBits x_bits(x);
More information about the libc-commits
mailing list