[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