[libc-commits] [libc] [llvm] [libc][math][c23] Add exp10bf16 math function (PR #193299)
via libc-commits
libc-commits at lists.llvm.org
Mon Apr 27 13:50:39 PDT 2026
https://github.com/ProfessionalMenace updated https://github.com/llvm/llvm-project/pull/193299
>From 977e86118301ff0e8d5023e311d7af30cc4deb54 Mon Sep 17 00:00:00 2001
From: ProfessionalMenace <vondracekadam00 at gmail.com>
Date: Fri, 17 Apr 2026 02:40:29 +0200
Subject: [PATCH 1/2] exp10bf16
---
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 +
libc/docs/headers/math/index.rst | 2 +-
libc/shared/math.h | 1 +
libc/shared/math/exp10bf16.h | 23 +++
libc/src/__support/math/CMakeLists.txt | 15 ++
libc/src/__support/math/exp10bf16.h | 147 ++++++++++++++++++
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/exp10bf16.h | 21 +++
libc/src/math/generic/CMakeLists.txt | 10 ++
libc/src/math/generic/exp10bf16.cpp | 18 +++
libc/test/shared/CMakeLists.txt | 1 +
libc/test/shared/shared_math_test.cpp | 1 +
libc/test/src/math/CMakeLists.txt | 12 ++
libc/test/src/math/exp10bf16_test.cpp | 39 +++++
libc/test/src/math/smoke/CMakeLists.txt | 13 ++
libc/test/src/math/smoke/exp10bf16_test.cpp | 39 +++++
27 files changed, 354 insertions(+), 1 deletion(-)
create mode 100644 libc/shared/math/exp10bf16.h
create mode 100644 libc/src/__support/math/exp10bf16.h
create mode 100644 libc/src/math/exp10bf16.h
create mode 100644 libc/src/math/generic/exp10bf16.cpp
create mode 100644 libc/test/src/math/exp10bf16_test.cpp
create mode 100644 libc/test/src/math/smoke/exp10bf16_test.cpp
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 452abd985b3a5..8092e5461d29a 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -812,6 +812,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 41c80efc64227..d93835a407d71 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -823,6 +823,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 88eacfae12969..fc26b0f18c23b 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -820,6 +820,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 914d2b7918da1..d18997b1a93c5 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -633,6 +633,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index b941c968255e8..0811387b3ab92 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -255,6 +255,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index c76900a8371f7..a8153888fefcc 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -661,6 +661,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 6538732f785f5..10ec0f31a3c91 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -663,6 +663,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index b15edc5e3e102..5b394ae87c14e 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -896,6 +896,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 8a4d88b5ba98c..8db37401f83a0 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -499,6 +499,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 6478aed3b0391..e27641d0d5fc7 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -917,6 +917,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index d1c1d9496af67..b2dfd7c66f81f 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -974,6 +974,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 94d1d00e676d9..79c0afa79c80e 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -345,6 +345,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizebf16
libc.src.math.ceilbf16
libc.src.math.copysignbf16
+ libc.src.math.exp10bf16
libc.src.math.fabsbf16
libc.src.math.fdimbf16
libc.src.math.floorbf16
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 14152ac62435d..408eb0e6c980c 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -299,7 +299,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| exp | |check| | |check| | | |check| | | | 7.12.6.1 | F.10.3.1 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
-| exp10 | |check| | |check| | | |check| | | | 7.12.6.2 | F.10.3.2 |
+| exp10 | |check| | |check| | | |check| | |check| | | 7.12.6.2 | F.10.3.2 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| exp10m1 | |check| | | | |check| | | | 7.12.6.3 | F.10.3.3 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/shared/math.h b/libc/shared/math.h
index 80078afea59ba..4e370d5a810a3 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -101,6 +101,7 @@
#include "math/erff16.h"
#include "math/exp.h"
#include "math/exp10.h"
+#include "math/exp10bf16.h"
#include "math/exp10f.h"
#include "math/exp10f16.h"
#include "math/exp10m1f.h"
diff --git a/libc/shared/math/exp10bf16.h b/libc/shared/math/exp10bf16.h
new file mode 100644
index 0000000000000..ba6fd984a0312
--- /dev/null
+++ b/libc/shared/math/exp10bf16.h
@@ -0,0 +1,23 @@
+//===-- Shared exp10bf16 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_EXP10BF16_H
+#define LLVM_LIBC_SHARED_MATH_EXP10BF16_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/exp10bf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::exp10bf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_EXP10BF16_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 67c3b28109987..54d359b42bfff 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -1089,6 +1089,21 @@ add_header_library(
libc.src.__support.macros.config
)
+add_header_library(
+ exp10bf16
+ HDRS
+ exp10bf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.macros.optimization
+)
+
add_header_library(
exp10m1f
HDRS
diff --git a/libc/src/__support/math/exp10bf16.h b/libc/src/__support/math/exp10bf16.h
new file mode 100644
index 0000000000000..2820bb5be74e7
--- /dev/null
+++ b/libc/src/__support/math/exp10bf16.h
@@ -0,0 +1,147 @@
+//===-- Implementation header for exp10bf16 ---------------------*- 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_EXP10BF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP10BF16_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/PolyEval.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/nearest_integer.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/optimization.h"
+
+// This is an algorithm for exp10(x) in bfloat16 which is correctly rounded for
+// all rounding modes, based on the implementation of exp10bf16(x)
+// from the RLIBM project at: https://people.cs.rutgers.edu/~sn349/rlibm
+
+// Step 1 - Range reduction of edge cases:
+// Find the largest value x for which exp10bf16(x) = +0.0
+// x < log10(min subnormal bfloat16)
+// Find the smallest value x for which exp10bf16(x) = +INF
+// x > log10(max normal bfloat16)
+
+// Step 2 - Range reduction to subnormal range:
+// exp10(x) = exp2(x * log2(10)) and further decompose x * log2(10) into
+// sum of two parts - closest integer i and a fraction f
+// exp10(x) = exp2(x * log2(10)) = exp2(i + f) = exp2(i) * exp2(f)
+
+// Step 4 - Polynomial approximation:
+// Approximate the range reduced function exp2(f) on a domain (-0.5, 0.5)
+// using a fourth degree polynomial P
+// Generated by Sollya with the following command:
+// > display = hexadecimal;
+// > exp2 = 2^x;
+// > I = [-0.5, 0.5];
+// > P = fpminimax(exp2, 4, [|1, SG...|], I);
+// > E = infnorm(exp2 - P, I);
+
+// Step 4 - Output compensation:
+// exp10(x) = exp2(i) * P(f)
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+
+// Generated by Sollya with the following command:
+// round(log2(10), SG, RN);
+LIBC_INLINE_VAR constexpr float LOG2F_10 = 0x1.a934fp1;
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+constexpr fputil::ExceptValues<bfloat16, 4> EXP10BF16_EXCEPTS{
+ {// {inputs, RZ output, RU offset, RD offset, RN offset}
+ // x = -0x1.6ep-7, exp10bf16(x) = 0x1.f2p-1 (RN)
+ {0xBC37U, 0x3F79U, 1U, 0U, 0U},
+ // x = -0x1.2ap-6, exp10bf16(x) = 0x1.eap-1 (RN)
+ {0xBC95U, 0x3F75U, 1U, 0U, 0U},
+ // x = -0x1.74p-3, exp10bf16(x) = 0x1.5p-1 (RN)
+ {0xBE3AU, 0x3F28U, 1U, 0U, 0U},
+ // x = -0x1.44p-1, exp10bf16(x) = 0x1.dcp-3 (RN)
+ {0xBF22U, 0x3E6EU, 1U, 0U, 0U}}};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+LIBC_INLINE constexpr bfloat16 exp10bf16(bfloat16 x) {
+ using FPBits = typename fputil::FPBits<bfloat16>;
+ FPBits x_bits(x);
+
+ uint16_t x_u = x_bits.uintval();
+
+ // special case where exp10bf16(NaN) = NaN
+ if (LIBC_UNLIKELY(x_bits.is_nan())) {
+ if (x_bits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ return x;
+ }
+
+ // exp10bf16(x) = +0.0
+ if (x_bits.is_neg() && x_u >= 0xc222U) { // x <= -0x1.44p+5
+ return FPBits::zero().get_val();
+ }
+
+ // exp10bf16(x) = +INF
+ if (x_bits.is_pos() && x_u >= 0x421bU) { // x >= 0x1.36p+5
+ if (x_bits.is_inf()) {
+ return FPBits::inf().get_val();
+ }
+
+ switch (fputil::quick_get_round()) {
+ case FE_TONEAREST:
+ case FE_UPWARD:
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW);
+ return FPBits::inf().get_val();
+ default:
+ return FPBits::max_normal().get_val();
+ }
+ }
+
+ // Hard-to-round cases with exact results
+ if (LIBC_UNLIKELY((x_u & ~(0x3F80U | 0x4000U | 0x4040U)) == 0)) {
+ switch (x_u) {
+ case 0x3F80U: // x = 1.0
+ return fputil::cast<bfloat16>(10.0);
+ case 0x4000U: // x = 2.0
+ return fputil::cast<bfloat16>(100.0);
+ case 0x4040U: // x = 3.0
+ return fputil::cast<bfloat16>(1'000.0);
+ }
+ }
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ if (auto r = EXP10BF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value())) {
+ return r.value();
+ }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // x * log2(10)
+ float xscaled = fputil::cast<bfloat16>(x) * LOG2F_10;
+
+ // range reduction to (-0.5, 0.5)
+ float intPart = fputil::nearest_integer(xscaled);
+ float fracPart = xscaled - intPart;
+
+ // polynomial approximation of exp2(x) on (-0.5, 0.5)
+ float poly = fputil::polyeval(fracPart,
+ 0x1p0f, // Exp2(0) = Exp10(0) = 1
+ 0x1.62e0dep-1f, 0x1.ec00d6p-3f, 0x1.ca13dcp-5f,
+ 0x1.3ac75ep-7f);
+
+ // output compensation
+ float result = fputil::ldexp(poly, static_cast<int>(intPart));
+ return fputil::cast<bfloat16>(result);
+}
+
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXP10BF16_H
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index b53817e2a1729..6e351f347858e 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -160,6 +160,7 @@ add_math_entrypoint_object(exp2m1f16)
add_math_entrypoint_object(exp10)
add_math_entrypoint_object(exp10f)
add_math_entrypoint_object(exp10f16)
+add_math_entrypoint_object(exp10bf16)
add_math_entrypoint_object(exp10m1f)
add_math_entrypoint_object(exp10m1f16)
diff --git a/libc/src/math/exp10bf16.h b/libc/src/math/exp10bf16.h
new file mode 100644
index 0000000000000..3ca1c830aec3f
--- /dev/null
+++ b/libc/src/math/exp10bf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for exp10bf16 ---------------------*- 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_EXP10BF16_H
+#define LLVM_LIBC_SRC_MATH_EXP10BF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 exp10bf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_EXP10BF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 0b91d1d4404ab..86ad3329ebca3 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1383,6 +1383,16 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ exp10bf16
+ SRCS
+ exp10bf16.cpp
+ HDRS
+ ../exp10bf16.h
+ DEPENDS
+ libc.src.__support.math.exp10bf16
+)
+
add_entrypoint_object(
exp10f
SRCS
diff --git a/libc/src/math/generic/exp10bf16.cpp b/libc/src/math/generic/exp10bf16.cpp
new file mode 100644
index 0000000000000..9f02e16ecc0e3
--- /dev/null
+++ b/libc/src/math/generic/exp10bf16.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation for exp10bf16(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/exp10bf16.h"
+#include "src/__support/math/exp10bf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, exp10bf16, (bfloat16 x)) {
+ return math::exp10bf16(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 8f324ae814f71..a7834595ed172 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -110,6 +110,7 @@ add_fp_unittest(
libc.src.__support.math.exp10
libc.src.__support.math.exp10f
libc.src.__support.math.exp10f16
+ libc.src.__support.math.exp10bf16
libc.src.__support.math.expf
libc.src.__support.math.expf16
libc.src.__support.math.f16add
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index d9d5c2c621d4a..72fe717323fe9 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -490,6 +490,7 @@ TEST(LlvmLibcSharedMathTest, AllBFloat16) {
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::ceilbf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::copysignbf16(
bfloat16(0.0), bfloat16(0.0)));
+ EXPECT_FP_EQ(bfloat16(1.0), LIBC_NAMESPACE::shared::exp10bf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::fabsbf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::floorbf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(0.0),
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 4213c11eca515..96f68990ce68e 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -1156,6 +1156,18 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ exp10bf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ exp10bf16_test.cpp
+ DEPENDS
+ libc.src.math.exp10bf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_fp_unittest(
expf_test
NEED_MPFR
diff --git a/libc/test/src/math/exp10bf16_test.cpp b/libc/test/src/math/exp10bf16_test.cpp
new file mode 100644
index 0000000000000..0eddf98bb1cfb
--- /dev/null
+++ b/libc/test/src/math/exp10bf16_test.cpp
@@ -0,0 +1,39 @@
+//===-- Exhaustive tests for exp10bf16(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/exp10bf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcExp10Bf16Test = 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;
+
+TEST_F(LlvmLibcExp10Bf16Test, PositiveRange) {
+ for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+ bfloat16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x, LIBC_NAMESPACE::exp10bf16(x), 0.5);
+ }
+}
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcExp10Bf16Test, NegativeRange) {
+ for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+ bfloat16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x, LIBC_NAMESPACE::exp10bf16(x), 0.5);
+ }
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 28b85b1a25bbd..96315a46c80d7 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1358,6 +1358,19 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ exp10bf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ exp10bf16_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.exp10bf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_fp_unittest(
exp_test
SUITE
diff --git a/libc/test/src/math/smoke/exp10bf16_test.cpp b/libc/test/src/math/smoke/exp10bf16_test.cpp
new file mode 100644
index 0000000000000..c5ab7ee6fc1a6
--- /dev/null
+++ b/libc/test/src/math/smoke/exp10bf16_test.cpp
@@ -0,0 +1,39 @@
+//===-- Unittests for exp10bf16 -------------------------------------------===//
+//
+// 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/exp10bf16.h"
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcExp10Bf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcExp10Bf16Test, SpecialNumbers) {
+ EXPECT_FP_IS_NAN(LIBC_NAMESPACE::exp10bf16(aNaN));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::exp10bf16(sNaN), FE_INVALID);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::exp10bf16(inf));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::exp10bf16(neg_inf));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(1.0), LIBC_NAMESPACE::exp10bf16(zero));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(1.0), LIBC_NAMESPACE::exp10bf16(neg_zero));
+ EXPECT_MATH_ERRNO(0);
+}
+
>From 39eb6ffda9827d3fa98e28bf8529f3cb336db5a5 Mon Sep 17 00:00:00 2001
From: ProfessionalMenace <vondracekadam00 at gmail.com>
Date: Tue, 21 Apr 2026 21:22:25 +0200
Subject: [PATCH 2/2] formatting & bazel
Bazel formatting issue
---
libc/shared/math/exp10bf16.h | 2 +-
libc/test/src/math/exp10bf16_test.cpp | 6 ++--
libc/test/src/math/smoke/exp10bf16_test.cpp | 1 -
.../llvm-project-overlay/libc/BUILD.bazel | 30 +++++++++++++++++++
4 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/libc/shared/math/exp10bf16.h b/libc/shared/math/exp10bf16.h
index ba6fd984a0312..2024fb5699b54 100644
--- a/libc/shared/math/exp10bf16.h
+++ b/libc/shared/math/exp10bf16.h
@@ -1,4 +1,4 @@
-//===-- Shared exp10bf16 function --------------------------------*- C++ -*-===//
+//===-- Shared exp10bf16 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.
diff --git a/libc/test/src/math/exp10bf16_test.cpp b/libc/test/src/math/exp10bf16_test.cpp
index 0eddf98bb1cfb..db0f06fe28804 100644
--- a/libc/test/src/math/exp10bf16_test.cpp
+++ b/libc/test/src/math/exp10bf16_test.cpp
@@ -23,7 +23,8 @@ static constexpr uint16_t POS_STOP = 0x7f80U;
TEST_F(LlvmLibcExp10Bf16Test, PositiveRange) {
for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
bfloat16 x = FPBits(v).get_val();
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x, LIBC_NAMESPACE::exp10bf16(x), 0.5);
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
+ LIBC_NAMESPACE::exp10bf16(x), 0.5);
}
}
@@ -34,6 +35,7 @@ static constexpr uint16_t NEG_STOP = 0xff80U;
TEST_F(LlvmLibcExp10Bf16Test, NegativeRange) {
for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
bfloat16 x = FPBits(v).get_val();
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x, LIBC_NAMESPACE::exp10bf16(x), 0.5);
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
+ LIBC_NAMESPACE::exp10bf16(x), 0.5);
}
}
diff --git a/libc/test/src/math/smoke/exp10bf16_test.cpp b/libc/test/src/math/smoke/exp10bf16_test.cpp
index c5ab7ee6fc1a6..a9eb5d9be58d6 100644
--- a/libc/test/src/math/smoke/exp10bf16_test.cpp
+++ b/libc/test/src/math/smoke/exp10bf16_test.cpp
@@ -36,4 +36,3 @@ TEST_F(LlvmLibcExp10Bf16Test, SpecialNumbers) {
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(1.0), LIBC_NAMESPACE::exp10bf16(neg_zero));
EXPECT_MATH_ERRNO(0);
}
-
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 1be54084b85bc..d2cf544504ae0 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -4131,6 +4131,28 @@ libc_support_library(
],
)
+libc_support_library(
+ name = "__support_math_exp10bf16",
+ hdrs = ["src/__support/math/exp10bf16.h"],
+ deps = [
+ ":__support_common",
+ ":__support_fputil_bfloat16",
+ ":__support_fputil_cast",
+ ":__support_fputil_except_value_utils",
+ ":__support_fputil_fenv_impl",
+ ":__support_fputil_fp_bits",
+ ":__support_fputil_manipulation_functions",
+ ":__support_fputil_multiply_add",
+ ":__support_fputil_nearest_integer",
+ ":__support_fputil_polyeval",
+ ":__support_fputil_rounding_mode",
+ ":__support_libc_errno",
+ ":__support_macros_config",
+ ":__support_macros_optimization",
+ ":errno",
+ ],
+)
+
libc_support_library(
name = "__support_math_exp10m1f",
hdrs = ["src/__support/math/exp10m1f.h"],
@@ -7437,6 +7459,14 @@ libc_math_function(
],
)
+libc_math_function(
+ name = "exp10bf16",
+ additional_deps = [
+ ":__support_math_exp10bf16",
+ ":errno",
+ ],
+)
+
libc_math_function(
name = "exp10f",
additional_deps = [
More information about the libc-commits
mailing list