[libc-commits] [libc] [llvm] [libc][math][c23] Add atanbf16 function (PR #184019)
via libc-commits
libc-commits at lists.llvm.org
Fri Mar 20 12:51:43 PDT 2026
https://github.com/Sukumarsawant updated https://github.com/llvm/llvm-project/pull/184019
>From fd993caf087456bc759235c8ad33c56e3910e262 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Fri, 27 Feb 2026 17:10:28 +0530
Subject: [PATCH 01/19] ADD : entrypoints
---
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/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 +
11 files changed, 11 insertions(+)
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 9fa9744cf109d..2066227cdfe91 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -354,6 +354,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2f
# libc.src.math.atan2l
libc.src.math.atan
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 83717616e3135..fd4a29ec357ef 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -363,6 +363,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2f
libc.src.math.atan2l
libc.src.math.atan
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 3c922062d2f8b..02897e43391c9 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -359,6 +359,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2f
# libc.src.math.atan2l
libc.src.math.atan
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 11f142266d9a9..3b1911660278c 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -171,6 +171,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 98c27d300ad9d..51fdccd3369a6 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -292,6 +292,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan2l
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 532fcda9ab3be..da203aa5013dd 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -292,6 +292,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan2l
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 92cf42a296264..487c6f87e9fb0 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -445,6 +445,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 737d6fcc6016a..d328ffc944055 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -271,6 +271,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.cbrt
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 312329895e081..8007506f75ed1 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -449,6 +449,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 1039c28eb5c6f..e24f44cfa6f93 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -494,6 +494,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 089cd1c8ede89..ca3a8f15b31a3 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -151,6 +151,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
+ libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.cbrt
>From c600bd10bb142dff90f5e8f811b79bc464848c24 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 13:05:48 +0530
Subject: [PATCH 02/19] feat: implementation for atanbf16
---
libc/src/__support/math/atanbf16.h | 123 +++++++++++++++++++++++++++++
libc/src/math/generic/atanbf16.cpp | 18 +++++
2 files changed, 141 insertions(+)
create mode 100644 libc/src/__support/math/atanbf16.h
create mode 100644 libc/src/math/generic/atanbf16.cpp
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
new file mode 100644
index 0000000000000..d87a7e320bde0
--- /dev/null
+++ b/libc/src/__support/math/atanbf16.h
@@ -0,0 +1,123 @@
+//===-- Half-precision atanfb16(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/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.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/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/atanbf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// Generated by Sollya using the following command:
+// > display = hexadecimal ;
+// > round(pi/2, SG, RN);
+static constexpr float PI_2 = 0x1.921fb6p0f;
+
+// #ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+// static constexpr size_t N_EXCEPTS = 6;
+
+// static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ATANF16_EXCEPTS{{
+// // (input, RZ output, RU offset, RD offset, RN offset)
+// {0x2745, 0x2744, 1, 0, 1},
+// {0x3099, 0x3090, 1, 0, 1},
+// {0x3c6c, 0x3aae, 1, 0, 1},
+// {0x466e, 0x3daa, 1, 0, 1},
+// {0x48ae, 0x3ddb, 1, 0, 0},
+// {0x5619, 0x3e3d, 1, 0, 1},
+// }};
+// #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+// checklist
+// +/- INF (done)
+// NaN -> signaled NaN quiet NaN
+// Normal range
+// Denormal range
+// zero
+
+LLVM_LIBC_FUNCTION(bfloat16, atanbf16, (bfloat16 x)) {
+ using FPBits = fputil::FPBits<bfloat16>;
+ FPBits xbits(x);
+
+ uint16_t x_u = xbits.uintval();
+ uint16_t x_abs = x_u & 0x7fff;
+ bool x_sign = x_u >> 15;
+ float sign = (x_sign ? (-1.0f) : (1.0f));
+
+ // |x| is +/-inf or NaN
+ if (LIBC_UNLIKELY(x_abs >= 0x7F80)) {
+ // NaN
+ if (xbits.is_nan()) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ return x;
+ }
+
+ // atanbf16(+/-inf) = +/-pi/2
+ // atanfb16(x) = sign(x) * atanbf16(x) -> [odd function]
+ return fputil::cast<bfloat16>(sign * PI_2);
+ }
+
+ // #ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // // Handle exceptional values
+ // if (auto r = ATANF16_EXCEPTS.lookup_odd(x_abs, x_sign);
+ // LIBC_UNLIKELY(r.has_value()))
+ // return r.value();
+ // #endif
+
+ // +/- 0
+ if (LIBC_UNLIKELY(x_abs == 0)) {
+ return (x);
+ }
+ float xf = x;
+ float x_sq = xf * xf;
+
+ // |x| <= 1
+ // Taylor series -> [x - x^3/3 + x^5/5 - x^7/7 ...]
+ // x * [1 - x^2/3 + x^4/5 - x^6/7...] -> x * P(x)
+ // atan(x) = x * poly(x^2)
+ // atan(x)/x = poly(x^2)
+
+ // Degree 6 polynomial of atan(x) generated using Sollya with command :
+ // > display = hexadecimal ;
+ // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6|], [|SG, SG, SG, SG|], [0, 1]);
+ if (x_abs <= 0x3f80) {
+ float result = fputil::polyeval(x_sq, 0x1.ffe432p-1f, -0x1.4da0c4p-2f,
+ 0x1.3ea034p-3f, -0x1.6b1fecp-5f);
+ return fputil::cast<bfloat16>(xf * result);
+ }
+
+ // if |x| > 1
+ // use identity atan(|x|) = sign(x) * [pi/2 - atan(1/|x|)];
+
+ float x_inv_sq = 1.0f / x_sq;
+ float x_inv = fputil::sqrt<float>(x_inv_sq);
+
+ // now use the same taylor series for t = 1/|x| ; since 1/|x| < 1
+ // can be factorized into 1/x * [ 1 - (1/x)^2/3 + (1/x)^4/5 - (1/x)^6/7 ....]
+ // atan(|x|) = (1/|x|) * P(1/|x|);
+
+ // Degree 6 polynomial of atan(1/|x|) generated using Sollya with command :
+ // > display = hexadecimal ;
+ // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6|], [|SG, SG, SG, SG|], [0, 1]);
+ // (here its atan(1/|x|)/(1/|x|))
+ float result = fputil::polyeval(x_inv_sq, 0x1.ffe432p-1f, -0x1.4da0c4p-2f,
+ 0x1.3ea034p-3f, -0x1.6b1fecp-5f);
+ return fputil::cast<bfloat16>(sign *
+ fputil::multiply_add(x_inv, -result, PI_2));
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+// zoro's ends here
diff --git a/libc/src/math/generic/atanbf16.cpp b/libc/src/math/generic/atanbf16.cpp
new file mode 100644
index 0000000000000..96ea511c03153
--- /dev/null
+++ b/libc/src/math/generic/atanbf16.cpp
@@ -0,0 +1,18 @@
+//===-- Half-precision atanbf16(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/atanbf16.h"
+#include "src/__support/math/atanbf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, atanbf16, (bfloat16 x)) {
+ return math::atanbf16(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
>From 5aca49272a8b2774e929c85acd26f82a79c375cd Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 13:22:15 +0530
Subject: [PATCH 03/19] feat: add atanbf16 to entrypoints.txt
---
libc/config/baremetal/aarch64/entrypoints.txt | 2 +-
libc/config/baremetal/arm/entrypoints.txt | 2 +-
libc/config/baremetal/riscv/entrypoints.txt | 2 +-
libc/config/darwin/aarch64/entrypoints.txt | 2 +-
libc/config/darwin/x86_64/entrypoints.txt | 1 +
libc/config/gpu/amdgpu/entrypoints.txt | 2 +-
libc/config/gpu/nvptx/entrypoints.txt | 2 +-
libc/config/linux/aarch64/entrypoints.txt | 2 +-
libc/config/linux/arm/entrypoints.txt | 2 +-
libc/config/linux/riscv/entrypoints.txt | 2 +-
libc/config/linux/x86_64/entrypoints.txt | 2 +-
libc/config/windows/entrypoints.txt | 2 +-
libc/shared/math/atanbf16.h | 26 +++++++++++++++++++
13 files changed, 38 insertions(+), 11 deletions(-)
create mode 100644 libc/shared/math/atanbf16.h
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 2066227cdfe91..84600efc5e0d1 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -354,7 +354,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2f
# libc.src.math.atan2l
libc.src.math.atan
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
@@ -790,6 +789,7 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index fd4a29ec357ef..5e87069b03256 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -363,7 +363,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2f
libc.src.math.atan2l
libc.src.math.atan
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
@@ -799,6 +798,7 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 02897e43391c9..17b7afe24f33b 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -359,7 +359,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2f
# libc.src.math.atan2l
libc.src.math.atan
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
@@ -795,6 +794,7 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 3b1911660278c..091b2d5dcfa4d 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -171,7 +171,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
@@ -608,6 +607,7 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index b0c247464c850..cad973f1ac069 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -234,6 +234,7 @@ set(TARGET_LIBM_ENTRYPOINTS
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 51fdccd3369a6..7aaf3470dceab 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -292,7 +292,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan2l
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
@@ -624,6 +623,7 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index da203aa5013dd..96c0902d729dc 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -292,7 +292,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan2l
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
@@ -626,6 +625,7 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 487c6f87e9fb0..ce99f305a616c 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -445,7 +445,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
@@ -869,6 +868,7 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index d328ffc944055..a7a15f0a1e383 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -271,7 +271,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.cbrt
@@ -475,6 +474,7 @@ set(TARGET_LIBM_ENTRYPOINTS
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 8007506f75ed1..6b518d0812143 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -449,7 +449,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
@@ -890,6 +889,7 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index e24f44cfa6f93..5fe7b156c503a 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -494,7 +494,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.canonicalize
@@ -940,6 +939,7 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index ca3a8f15b31a3..43113b9bdc7a0 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -151,7 +151,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atan2
libc.src.math.atan2f
libc.src.math.atan
- libc.src.math.atanbf16
libc.src.math.atanf
libc.src.math.atanhf
libc.src.math.cbrt
@@ -321,6 +320,7 @@ set(TARGET_LIBM_ENTRYPOINTS
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.atanbf16
libc.src.math.bf16add
libc.src.math.bf16addf
libc.src.math.bf16addl
diff --git a/libc/shared/math/atanbf16.h b/libc/shared/math/atanbf16.h
new file mode 100644
index 0000000000000..d6408d84911bc
--- /dev/null
+++ b/libc/shared/math/atanbf16.h
@@ -0,0 +1,26 @@
+//===-- Shared atanbf16 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_ATANBF16_H
+#define LLVM_LIBC_SHARED_MATH_ATANBF16_H
+
+#include "shared/libc_common.h"
+
+#include "src/__support/math/atanbf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace shared {
+
+using math::atanbf16;
+
+} // namespace shared
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_ATANBF16_H
\ No newline at end of file
>From b44fe4afb9887bbabb6f285b80a4c97e8c2b45e2 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 17:10:46 +0530
Subject: [PATCH 04/19] feat: smoke and exhaustive test added. Made header
only.
---
libc/shared/math.h | 1 +
libc/src/__support/math/CMakeLists.txt | 17 ++++++
libc/src/__support/math/atanbf16.h | 44 +++++---------
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/atanbf16.h | 21 +++++++
libc/src/math/generic/CMakeLists.txt | 10 ++++
libc/test/shared/CMakeLists.txt | 1 +
libc/test/shared/shared_math_test.cpp | 1 +
libc/test/src/math/CMakeLists.txt | 14 +++++
libc/test/src/math/atanbf16_test.cpp | 47 +++++++++++++++
libc/test/src/math/exhaustive/CMakeLists.txt | 17 ++++++
.../src/math/exhaustive/atanbf16_test.cpp | 59 +++++++++++++++++++
libc/test/src/math/smoke/CMakeLists.txt | 13 ++++
libc/test/src/math/smoke/atanbf16_test.cpp | 45 ++++++++++++++
.../llvm-project-overlay/libc/BUILD.bazel | 21 +++++++
15 files changed, 282 insertions(+), 30 deletions(-)
create mode 100644 libc/src/math/atanbf16.h
create mode 100644 libc/test/src/math/atanbf16_test.cpp
create mode 100644 libc/test/src/math/exhaustive/atanbf16_test.cpp
create mode 100644 libc/test/src/math/smoke/atanbf16_test.cpp
diff --git a/libc/shared/math.h b/libc/shared/math.h
index 75d7aa2ca35e7..21b9d6aac3c7a 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -30,6 +30,7 @@
#include "math/atan2f.h"
#include "math/atan2f128.h"
#include "math/atan2f16.h"
+#include "math/atanbf16.h"
#include "math/atanf.h"
#include "math/atanf16.h"
#include "math/atanhf.h"
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index df5afed184ba2..df10cab199400 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -289,6 +289,23 @@ add_header_library(
libc.src.__support.macros.optimization
)
+add_header_library(
+ atanbf16
+ HDRS
+ atanbf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.except_value_utils
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.FPUtil.sqrt
+ libc.src.__support.macros.optimization
+ libc.src.__support.FPUtil.bfloat16
+
+)
+
add_header_library(
atanf
HDRS
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
index d87a7e320bde0..d5c8bfc605844 100644
--- a/libc/src/__support/math/atanbf16.h
+++ b/libc/src/__support/math/atanbf16.h
@@ -6,8 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#include "hdr/errno_macros.h"
-#include "hdr/fenv_macros.h"
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ATANBF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ATANBF16_H
+
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -16,36 +17,18 @@
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/macros/optimization.h"
-#include "src/math/atanbf16.h"
+#include "src/__support/FPUtil/bfloat16.h"
namespace LIBC_NAMESPACE_DECL {
-// Generated by Sollya using the following command:
-// > display = hexadecimal ;
-// > round(pi/2, SG, RN);
-static constexpr float PI_2 = 0x1.921fb6p0f;
-
-// #ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-// static constexpr size_t N_EXCEPTS = 6;
-
-// static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ATANF16_EXCEPTS{{
-// // (input, RZ output, RU offset, RD offset, RN offset)
-// {0x2745, 0x2744, 1, 0, 1},
-// {0x3099, 0x3090, 1, 0, 1},
-// {0x3c6c, 0x3aae, 1, 0, 1},
-// {0x466e, 0x3daa, 1, 0, 1},
-// {0x48ae, 0x3ddb, 1, 0, 0},
-// {0x5619, 0x3e3d, 1, 0, 1},
-// }};
-// #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-// checklist
-// +/- INF (done)
-// NaN -> signaled NaN quiet NaN
-// Normal range
-// Denormal range
-// zero
-
-LLVM_LIBC_FUNCTION(bfloat16, atanbf16, (bfloat16 x)) {
+namespace math {
+
+LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
+ // Generated by Sollya using the following command:
+ // > display = hexadecimal ;
+ // > round(pi/2, SG, RN);
+ constexpr float PI_2 = 0x1.921fb6p0f;
+
using FPBits = fputil::FPBits<bfloat16>;
FPBits xbits(x);
@@ -64,7 +47,6 @@ LLVM_LIBC_FUNCTION(bfloat16, atanbf16, (bfloat16 x)) {
}
return x;
}
-
// atanbf16(+/-inf) = +/-pi/2
// atanfb16(x) = sign(x) * atanbf16(x) -> [odd function]
return fputil::cast<bfloat16>(sign * PI_2);
@@ -117,7 +99,9 @@ LLVM_LIBC_FUNCTION(bfloat16, atanbf16, (bfloat16 x)) {
0x1.3ea034p-3f, -0x1.6b1fecp-5f);
return fputil::cast<bfloat16>(sign *
fputil::multiply_add(x_inv, -result, PI_2));
+}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ATANBF16_H
// zoro's ends here
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 98dba11f34c86..5bdb8d99eedeb 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -63,6 +63,7 @@ add_math_entrypoint_object(asinpif)
add_math_entrypoint_object(asinpif16)
add_math_entrypoint_object(atan)
+add_math_entrypoint_object(atanbf16)
add_math_entrypoint_object(atanf)
add_math_entrypoint_object(atanf16)
diff --git a/libc/src/math/atanbf16.h b/libc/src/math/atanbf16.h
new file mode 100644
index 0000000000000..54fd3a44acd8a
--- /dev/null
+++ b/libc/src/math/atanbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for atanbf16 ---------------------*- 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_ATANBF16_H
+#define LLVM_LIBC_SRC_MATH_ATANBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 atanbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ATANBF16_H
\ No newline at end of file
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 7f3972cb21cb6..a727768d9233b 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4145,6 +4145,16 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ atanf
+ SRCS
+ atanbf16.cpp
+ HDRS
+ ../atanbf16.h
+ DEPENDS
+ libc.src.__support.math.atanbf16
+)
+
add_entrypoint_object(
atanf
SRCS
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 15b3ce128d385..390ae21defafc 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -27,6 +27,7 @@ add_fp_unittest(
libc.src.__support.math.atan2f
libc.src.__support.math.atan2f128
libc.src.__support.math.atan2f16
+ libc.src.__support.math.atanbf16
libc.src.__support.math.atanf
libc.src.__support.math.atanf16
libc.src.__support.math.atanhf
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index f443afd824a72..ae21d73b952cf 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -416,6 +416,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat128) {
TEST(LlvmLibcSharedMathTest, AllBFloat16) {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>;
+ EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::atanbf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(5.0), LIBC_NAMESPACE::shared::bf16add(2.0, 3.0));
EXPECT_FP_EQ(bfloat16(2.0f), LIBC_NAMESPACE::shared::bf16divf(4.0f, 2.0f));
EXPECT_FP_EQ(bfloat16(2.0), LIBC_NAMESPACE::shared::bf16divl(6.0L, 3.0L));
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 2710f4cbdbe31..b254066cdc4c1 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2616,6 +2616,20 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ atanbf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ hypotbf16_test.cpp
+ DEPENDS
+ libc.src.math.atanbf16
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.bfloat16
+)
+
+
add_fp_unittest(
atanf16_test
NEED_MPFR
diff --git a/libc/test/src/math/atanbf16_test.cpp b/libc/test/src/math/atanbf16_test.cpp
new file mode 100644
index 0000000000000..7f0f8f126e60b
--- /dev/null
+++ b/libc/test/src/math/atanbf16_test.cpp
@@ -0,0 +1,47 @@
+//===-- Exhaustive test for atanbf16 ---------------------------------------===//
+//
+// 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/atanbf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcAtanBf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// Normal range: [+0, +int]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// Normal range: [-0, -int]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcAtanBf16Test, NormalPositiveRange) {
+ for (uint16_t v1 = POS_START; v1 <= POS_STOP; v1++) {
+
+ bfloat16 x = FPBits(v1).get_val();
+
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
+
+}
+
+TEST_F(LlvmLibcAtanBf16Test, NormalNegativeRange) {
+ for (uint16_t v1 = NEG_START; v1 <= NEG_STOP; v1++) {
+
+ bfloat16 x = FPBits(v1).get_val();
+
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
+
+}
\ No newline at end of file
diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt
index 2d1301d3a1e66..77a794ad5dfb9 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -619,6 +619,23 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ atanbf16_test
+ NO_RUN_POSTBUILD
+ NEED_MPFR
+ SUITE
+ libc_math_exhaustive_tests
+ SRCS
+ atanbf16_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.atanbf16
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.bfloat16
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
atanf_test
NO_RUN_POSTBUILD
diff --git a/libc/test/src/math/exhaustive/atanbf16_test.cpp b/libc/test/src/math/exhaustive/atanbf16_test.cpp
new file mode 100644
index 0000000000000..28062fde4ae16
--- /dev/null
+++ b/libc/test/src/math/exhaustive/atanbf16_test.cpp
@@ -0,0 +1,59 @@
+//===-- Exhaustive test for atanbf16 ---------------------------------------===//
+//
+// 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/atanbf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcAtanBf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// Normal range: [+0, +int]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// Normal range: [-0, -int]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcAtanBf16Test, NormalPositiveRange) {
+ for (uint16_t v1 = POS_START; v1 <= POS_STOP; v1++) {
+
+ bfloat16 x = FPBits(v1).get_val();
+
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
+
+}
+
+TEST_F(LlvmLibcAtanBf16Test, NormalNegativeRange) {
+ for (uint16_t v1 = NEG_START; v1 <= NEG_STOP; v1++) {
+
+ bfloat16 x = FPBits(v1).get_val();
+
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
+
+}
+
+TEST_F(LlvmLibcAtanBf16Test, SpecialNumbers) {
+ constexpr bfloat16 VALUES[] = {zero, neg_zero, inf,
+ neg_inf, min_normal, max_normal};
+ for (size_t i = 0; i < 6; ++i) {
+ bfloat16 x = VALUES[i];
+
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
+
+}
\ No newline at end of file
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index d92e6b728b63e..6c9e7f02f4292 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4904,6 +4904,19 @@ add_fp_unittest(
libc.src.math.atan
)
+add_fp_unittest(
+ atanbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ atanbf16_test.cpp
+ DEPENDS
+ libc.src.math.atanbf16
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_fp_unittest(
atanf16_test
SUITE
diff --git a/libc/test/src/math/smoke/atanbf16_test.cpp b/libc/test/src/math/smoke/atanbf16_test.cpp
new file mode 100644
index 0000000000000..8eb477d02ca59
--- /dev/null
+++ b/libc/test/src/math/smoke/atanbf16_test.cpp
@@ -0,0 +1,45 @@
+//===-- Unittests for atanbf16 --------------------------------------------===//
+//
+// 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/atanbf16.h"
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+class LlvmLibcAtanBf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+ DECLARE_SPECIAL_CONSTANTS(bfloat16)
+public:
+ void test_special_numbers() {
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanbf16(aNaN));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanbf16(sNaN), FE_INVALID);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::atanbf16(zero));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atanbf16(neg_zero));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.92p-1f), LIBC_NAMESPACE::atanbf16(bfloat16(1.0)));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.92p-1f), LIBC_NAMESPACE::atanbf16(bfloat16(-1.0)));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.92p0f), LIBC_NAMESPACE::atanbf16(inf));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.92p0f), LIBC_NAMESPACE::atanbf16(neg_inf));
+ EXPECT_MATH_ERRNO(0);
+ }
+};
+TEST_F(LlvmLibcAtanBf16Test, SpecialNumbers) { test_special_numbers(); }
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 05ac491edbad8..1d998be00eaca 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3096,6 +3096,22 @@ libc_support_library(
],
)
+libc_support_library(
+ name = "__support_math_atanbf16",
+ hdrs = ["src/__support/math/atanbf16.h"],
+ deps = [
+ ":__support_fputil_cast",
+ ":__support_fputil_except_value_utils",
+ ":__support_fputil_fenv_impl",
+ ":__support_fputil_fp_bits",
+ ":__support_fputil_multiply_add",
+ ":__support_fputil_polyeval",
+ ":__support_fputil_sqrt",
+ ":__support_macros_optimization",
+ ":__support_fputil_bfloat16",
+ ],
+)
+
libc_support_library(
name = "__support_math_atanf",
hdrs = ["src/__support/math/atanf.h"],
@@ -6297,6 +6313,11 @@ libc_math_function(
],
)
+libc_math_function(
+ name = "atanbf16",
+ additional_deps = [":__support_math_atanbf16"],
+)
+
libc_math_function(
name = "atanf",
additional_deps = [":__support_math_atanf"],
>From 8ae42a7de93b0b076fab3b368e633ab828c5e5db Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 17:11:55 +0530
Subject: [PATCH 05/19] chore: formatted
---
libc/src/__support/math/atanbf16.h | 2 +-
libc/test/src/math/atanbf16_test.cpp | 21 +++++++------
.../src/math/exhaustive/atanbf16_test.cpp | 30 +++++++++----------
libc/test/src/math/smoke/atanbf16_test.cpp | 19 +++++++-----
4 files changed, 37 insertions(+), 35 deletions(-)
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
index d5c8bfc605844..21eee02a044df 100644
--- a/libc/src/__support/math/atanbf16.h
+++ b/libc/src/__support/math/atanbf16.h
@@ -12,12 +12,12 @@
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/bfloat16.h"
#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/except_value_utils.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/macros/optimization.h"
-#include "src/__support/FPUtil/bfloat16.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/src/math/atanbf16_test.cpp b/libc/test/src/math/atanbf16_test.cpp
index 7f0f8f126e60b..4801b9b32d572 100644
--- a/libc/test/src/math/atanbf16_test.cpp
+++ b/libc/test/src/math/atanbf16_test.cpp
@@ -1,4 +1,5 @@
-//===-- Exhaustive test for atanbf16 ---------------------------------------===//
+//===-- Exhaustive test for atanbf16
+//---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -27,21 +28,19 @@ static constexpr uint16_t NEG_STOP = 0xff80U;
TEST_F(LlvmLibcAtanBf16Test, NormalPositiveRange) {
for (uint16_t v1 = POS_START; v1 <= POS_STOP; v1++) {
- bfloat16 x = FPBits(v1).get_val();
-
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
- LIBC_NAMESPACE::atanbf16(x), 0.5);
- }
+ bfloat16 x = FPBits(v1).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
}
TEST_F(LlvmLibcAtanBf16Test, NormalNegativeRange) {
for (uint16_t v1 = NEG_START; v1 <= NEG_STOP; v1++) {
- bfloat16 x = FPBits(v1).get_val();
+ bfloat16 x = FPBits(v1).get_val();
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
- LIBC_NAMESPACE::atanbf16(x), 0.5);
- }
-
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
}
\ No newline at end of file
diff --git a/libc/test/src/math/exhaustive/atanbf16_test.cpp b/libc/test/src/math/exhaustive/atanbf16_test.cpp
index 28062fde4ae16..7216ad2f9dc6f 100644
--- a/libc/test/src/math/exhaustive/atanbf16_test.cpp
+++ b/libc/test/src/math/exhaustive/atanbf16_test.cpp
@@ -1,4 +1,5 @@
-//===-- Exhaustive test for atanbf16 ---------------------------------------===//
+//===-- Exhaustive test for atanbf16
+//---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -27,33 +28,30 @@ static constexpr uint16_t NEG_STOP = 0xff80U;
TEST_F(LlvmLibcAtanBf16Test, NormalPositiveRange) {
for (uint16_t v1 = POS_START; v1 <= POS_STOP; v1++) {
- bfloat16 x = FPBits(v1).get_val();
-
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
- LIBC_NAMESPACE::atanbf16(x), 0.5);
- }
+ bfloat16 x = FPBits(v1).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
}
TEST_F(LlvmLibcAtanBf16Test, NormalNegativeRange) {
for (uint16_t v1 = NEG_START; v1 <= NEG_STOP; v1++) {
- bfloat16 x = FPBits(v1).get_val();
+ bfloat16 x = FPBits(v1).get_val();
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
- LIBC_NAMESPACE::atanbf16(x), 0.5);
- }
-
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
}
TEST_F(LlvmLibcAtanBf16Test, SpecialNumbers) {
constexpr bfloat16 VALUES[] = {zero, neg_zero, inf,
neg_inf, min_normal, max_normal};
for (size_t i = 0; i < 6; ++i) {
- bfloat16 x = VALUES[i];
+ bfloat16 x = VALUES[i];
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
- LIBC_NAMESPACE::atanbf16(x), 0.5);
- }
-
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
}
\ No newline at end of file
diff --git a/libc/test/src/math/smoke/atanbf16_test.cpp b/libc/test/src/math/smoke/atanbf16_test.cpp
index 8eb477d02ca59..b5baf1dcaf934 100644
--- a/libc/test/src/math/smoke/atanbf16_test.cpp
+++ b/libc/test/src/math/smoke/atanbf16_test.cpp
@@ -19,8 +19,9 @@ class LlvmLibcAtanBf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
void test_special_numbers() {
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanbf16(aNaN));
EXPECT_MATH_ERRNO(0);
-
- EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanbf16(sNaN), FE_INVALID);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ aNaN, LIBC_NAMESPACE::atanbf16(sNaN), FE_INVALID);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::atanbf16(zero));
@@ -29,17 +30,21 @@ class LlvmLibcAtanBf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atanbf16(neg_zero));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.92p-1f), LIBC_NAMESPACE::atanbf16(bfloat16(1.0)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.92p-1f),
+ LIBC_NAMESPACE::atanbf16(bfloat16(1.0)));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.92p-1f), LIBC_NAMESPACE::atanbf16(bfloat16(-1.0)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.92p-1f),
+ LIBC_NAMESPACE::atanbf16(bfloat16(-1.0)));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.92p0f), LIBC_NAMESPACE::atanbf16(inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.92p0f),
+ LIBC_NAMESPACE::atanbf16(inf));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.92p0f), LIBC_NAMESPACE::atanbf16(neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.92p0f),
+ LIBC_NAMESPACE::atanbf16(neg_inf));
EXPECT_MATH_ERRNO(0);
- }
+ }
};
TEST_F(LlvmLibcAtanBf16Test, SpecialNumbers) { test_special_numbers(); }
>From 59d426713a4230b72fb3e8932e980c19c8166b4b Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 17:38:10 +0530
Subject: [PATCH 06/19] chore: EOL and spell
---
libc/shared/math/atanbf16.h | 2 +-
libc/src/math/atanbf16.h | 2 +-
libc/src/math/generic/CMakeLists.txt | 2 +-
libc/test/src/math/exhaustive/atanbf16_test.cpp | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libc/shared/math/atanbf16.h b/libc/shared/math/atanbf16.h
index d6408d84911bc..b3f6d280a70e8 100644
--- a/libc/shared/math/atanbf16.h
+++ b/libc/shared/math/atanbf16.h
@@ -23,4 +23,4 @@ using math::atanbf16;
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SHARED_MATH_ATANBF16_H
\ No newline at end of file
+#endif // LLVM_LIBC_SHARED_MATH_ATANBF16_H
diff --git a/libc/src/math/atanbf16.h b/libc/src/math/atanbf16.h
index 54fd3a44acd8a..571b436cb2d3d 100644
--- a/libc/src/math/atanbf16.h
+++ b/libc/src/math/atanbf16.h
@@ -18,4 +18,4 @@ bfloat16 atanbf16(bfloat16 x);
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_MATH_ATANBF16_H
\ No newline at end of file
+#endif // LLVM_LIBC_SRC_MATH_ATANBF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index a727768d9233b..bdc49ebfe9f89 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4146,7 +4146,7 @@ add_entrypoint_object(
)
add_entrypoint_object(
- atanf
+ atanbf16
SRCS
atanbf16.cpp
HDRS
diff --git a/libc/test/src/math/exhaustive/atanbf16_test.cpp b/libc/test/src/math/exhaustive/atanbf16_test.cpp
index 7216ad2f9dc6f..5812067b61516 100644
--- a/libc/test/src/math/exhaustive/atanbf16_test.cpp
+++ b/libc/test/src/math/exhaustive/atanbf16_test.cpp
@@ -54,4 +54,4 @@ TEST_F(LlvmLibcAtanBf16Test, SpecialNumbers) {
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
LIBC_NAMESPACE::atanbf16(x), 0.5);
}
-}
\ No newline at end of file
+}
>From b227db23a3d626adbd2308aab86dd29bfd79fc18 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 17:42:14 +0530
Subject: [PATCH 07/19] chore: Cmake
---
libc/test/src/math/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index b254066cdc4c1..3f7e01a1a480f 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2622,7 +2622,7 @@ add_fp_unittest(
SUITE
libc-math-unittests
SRCS
- hypotbf16_test.cpp
+ atanbf16_test.cpp
DEPENDS
libc.src.math.atanbf16
libc.src.__support.FPUtil.fp_bits
>From e064c9dd9f74a6fe2a91e1ea7d4a2d0d79c293af Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 17:51:56 +0530
Subject: [PATCH 08/19] feat: fix: conversion/cast errors
test: removed a smoke test
t1
t2
t3
t4
t5
t6
t7
t8
t9
t10
t11
t12
t13
t13
t13
t13
t14
t15
t15
fix: test handling done using mpfr
final
fixed?
final final
formatted
---
libc/src/__support/math/CMakeLists.txt | 1 -
libc/src/__support/math/atanbf16.h | 55 ++++++++-----------
libc/test/src/math/atanbf16_test.cpp | 16 +++++-
.../src/math/exhaustive/atanbf16_test.cpp | 3 +-
libc/test/src/math/smoke/CMakeLists.txt | 1 +
libc/test/src/math/smoke/atanbf16_test.cpp | 23 +++-----
.../llvm-project-overlay/libc/BUILD.bazel | 1 -
7 files changed, 47 insertions(+), 53 deletions(-)
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index df10cab199400..602e1588dc1d5 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -295,7 +295,6 @@ add_header_library(
atanbf16.h
DEPENDS
libc.src.__support.FPUtil.cast
- libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
index 21eee02a044df..ba519c08b94b0 100644
--- a/libc/src/__support/math/atanbf16.h
+++ b/libc/src/__support/math/atanbf16.h
@@ -1,4 +1,4 @@
-//===-- Half-precision atanfb16(x) function -------------------------------===//
+//===-- bfloat16 precision atanbf16(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.
@@ -14,7 +14,6 @@
#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/multiply_add.h"
#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/macros/optimization.h"
@@ -25,7 +24,7 @@ namespace math {
LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
// Generated by Sollya using the following command:
- // > display = hexadecimal ;
+ // > display = hexadecimal;
// > round(pi/2, SG, RN);
constexpr float PI_2 = 0x1.921fb6p0f;
@@ -35,7 +34,7 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
uint16_t x_u = xbits.uintval();
uint16_t x_abs = x_u & 0x7fff;
bool x_sign = x_u >> 15;
- float sign = (x_sign ? (-1.0f) : (1.0f));
+ float sign = (x_sign ? -1.0f : 1.0f);
// |x| is +/-inf or NaN
if (LIBC_UNLIKELY(x_abs >= 0x7F80)) {
@@ -48,21 +47,13 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
return x;
}
// atanbf16(+/-inf) = +/-pi/2
- // atanfb16(x) = sign(x) * atanbf16(x) -> [odd function]
return fputil::cast<bfloat16>(sign * PI_2);
}
- // #ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // // Handle exceptional values
- // if (auto r = ATANF16_EXCEPTS.lookup_odd(x_abs, x_sign);
- // LIBC_UNLIKELY(r.has_value()))
- // return r.value();
- // #endif
+ // atanbf16(+/-0) = +/-0
+ if (LIBC_UNLIKELY(x_abs == 0))
+ return x;
- // +/- 0
- if (LIBC_UNLIKELY(x_abs == 0)) {
- return (x);
- }
float xf = x;
float x_sq = xf * xf;
@@ -72,36 +63,36 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
// atan(x) = x * poly(x^2)
// atan(x)/x = poly(x^2)
- // Degree 6 polynomial of atan(x) generated using Sollya with command :
+ // Degree 14 polynomial of atan(x) generated using Sollya with command :
// > display = hexadecimal ;
- // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6|], [|SG, SG, SG, SG|], [0, 1]);
+ // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|SG, SG,
+ // SG..SG|], [0, 1]);
if (x_abs <= 0x3f80) {
- float result = fputil::polyeval(x_sq, 0x1.ffe432p-1f, -0x1.4da0c4p-2f,
- 0x1.3ea034p-3f, -0x1.6b1fecp-5f);
+ float result = fputil::polyeval(
+ x_sq, 0x1.fffffcp-1f, -0x1.55519ep-2f, 0x1.98f6a8p-3f, -0x1.1f0a92p-3f,
+ 0x1.95b654p-4f, -0x1.e65492p-5f, 0x1.8c0c36p-6f, -0x1.32316ep-8f);
return fputil::cast<bfloat16>(xf * result);
}
- // if |x| > 1
- // use identity atan(|x|) = sign(x) * [pi/2 - atan(1/|x|)];
-
+ // If |x| > 1:
+ // atan(x) = sign(x) * (pi/2 - atan(1/|x|))
+ // Since 1/|x| < 1, we can use the same polynomial.
float x_inv_sq = 1.0f / x_sq;
float x_inv = fputil::sqrt<float>(x_inv_sq);
- // now use the same taylor series for t = 1/|x| ; since 1/|x| < 1
- // can be factorized into 1/x * [ 1 - (1/x)^2/3 + (1/x)^4/5 - (1/x)^6/7 ....]
- // atan(|x|) = (1/|x|) * P(1/|x|);
-
- // Degree 6 polynomial of atan(1/|x|) generated using Sollya with command :
+ // Degree 14 polynomial of atan(1/|x|) generated using Sollya with command :
// > display = hexadecimal ;
- // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6|], [|SG, SG, SG, SG|], [0, 1]);
- // (here its atan(1/|x|)/(1/|x|))
- float result = fputil::polyeval(x_inv_sq, 0x1.ffe432p-1f, -0x1.4da0c4p-2f,
- 0x1.3ea034p-3f, -0x1.6b1fecp-5f);
+ // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|SG, SG, SG...
+ // SG|], [0, 1]); (here its atan(1/|x|)/(1/|x|))
+ float result =
+ fputil::polyeval(x_inv_sq, 0x1.fffffcp-1f, -0x1.55519ep-2f,
+ 0x1.98f6a8p-3f, -0x1.1f0a92p-3f, 0x1.95b654p-4f,
+ -0x1.e65492p-5f, 0x1.8c0c36p-6f, -0x1.32316ep-8f);
return fputil::cast<bfloat16>(sign *
fputil::multiply_add(x_inv, -result, PI_2));
}
+
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ATANBF16_H
-// zoro's ends here
diff --git a/libc/test/src/math/atanbf16_test.cpp b/libc/test/src/math/atanbf16_test.cpp
index 4801b9b32d572..24452d312bfc2 100644
--- a/libc/test/src/math/atanbf16_test.cpp
+++ b/libc/test/src/math/atanbf16_test.cpp
@@ -1,5 +1,4 @@
-//===-- Exhaustive test for atanbf16
-//---------------------------------------===//
+//===-- Unittests for atanbf16 -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -43,4 +42,15 @@ TEST_F(LlvmLibcAtanBf16Test, NormalNegativeRange) {
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
LIBC_NAMESPACE::atanbf16(x), 0.5);
}
-}
\ No newline at end of file
+}
+
+TEST_F(LlvmLibcAtanBf16Test, SpecialNumbers) {
+ constexpr bfloat16 VALUES[] = {zero, neg_zero, inf,
+ neg_inf, min_normal, max_normal};
+ for (size_t i = 0; i < 6; ++i) {
+ bfloat16 x = VALUES[i];
+
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
+}
diff --git a/libc/test/src/math/exhaustive/atanbf16_test.cpp b/libc/test/src/math/exhaustive/atanbf16_test.cpp
index 5812067b61516..347d9a932d7ff 100644
--- a/libc/test/src/math/exhaustive/atanbf16_test.cpp
+++ b/libc/test/src/math/exhaustive/atanbf16_test.cpp
@@ -1,5 +1,4 @@
-//===-- Exhaustive test for atanbf16
-//---------------------------------------===//
+//===-- Exhaustive tests for atanb16 addition -----------------------------===//
//
// 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/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 6c9e7f02f4292..9d97c90cfaeb9 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4906,6 +4906,7 @@ add_fp_unittest(
add_fp_unittest(
atanbf16_test
+ NEED_MPFR
SUITE
libc-math-smoke-tests
SRCS
diff --git a/libc/test/src/math/smoke/atanbf16_test.cpp b/libc/test/src/math/smoke/atanbf16_test.cpp
index b5baf1dcaf934..ab79f712979af 100644
--- a/libc/test/src/math/smoke/atanbf16_test.cpp
+++ b/libc/test/src/math/smoke/atanbf16_test.cpp
@@ -13,6 +13,8 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
class LlvmLibcAtanBf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(bfloat16)
public:
@@ -30,21 +32,14 @@ class LlvmLibcAtanBf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atanbf16(neg_zero));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.92p-1f),
- LIBC_NAMESPACE::atanbf16(bfloat16(1.0)));
- EXPECT_MATH_ERRNO(0);
-
- EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.92p-1f),
- LIBC_NAMESPACE::atanbf16(bfloat16(-1.0)));
- EXPECT_MATH_ERRNO(0);
+ bfloat16 VALUES[] = {inf, neg_inf, bfloat16(1.0f),
+ bfloat16(-1.0)};
+ for (size_t i = 0; i < 4; ++i) {
+ bfloat16 x = VALUES[i];
- EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.92p0f),
- LIBC_NAMESPACE::atanbf16(inf));
- EXPECT_MATH_ERRNO(0);
-
- EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.92p0f),
- LIBC_NAMESPACE::atanbf16(neg_inf));
- EXPECT_MATH_ERRNO(0);
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
+ LIBC_NAMESPACE::atanbf16(x), 0.5);
+ }
}
};
TEST_F(LlvmLibcAtanBf16Test, SpecialNumbers) { test_special_numbers(); }
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 1d998be00eaca..d331a411629c4 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3101,7 +3101,6 @@ libc_support_library(
hdrs = ["src/__support/math/atanbf16.h"],
deps = [
":__support_fputil_cast",
- ":__support_fputil_except_value_utils",
":__support_fputil_fenv_impl",
":__support_fputil_fp_bits",
":__support_fputil_multiply_add",
>From 5dd79a3c55d6f31adcc5ee0a7156195f870cbb1d Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 23:09:21 +0530
Subject: [PATCH 09/19] feat: smoke test and exhaustive tests added
---
libc/docs/headers/math/index.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 8692bf37c05b1..202ef034b8ace 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -271,7 +271,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| asinpi | |check| | | | |check| | | | 7.12.4.9 | F.10.1.9 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
-| atan | |check| | 1 ULP | | |check| | | | 7.12.4.3 | F.10.1.3 |
+| atan | |check| | 1 ULP | | |check| | | |check| | 7.12.4.3 | F.10.1.3 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| atan2 | |check| | 1 ULP | | |check| | 1 ULP | | 7.12.4.4 | F.10.1.4 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
>From 4241952c1d8c97841b356178d03344e4b0351c84 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 23:35:37 +0530
Subject: [PATCH 10/19] chore: Clang
---
libc/test/src/math/atanbf16_test.cpp | 2 +-
libc/test/src/math/smoke/atanbf16_test.cpp | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/libc/test/src/math/atanbf16_test.cpp b/libc/test/src/math/atanbf16_test.cpp
index 24452d312bfc2..69d9b52d89a22 100644
--- a/libc/test/src/math/atanbf16_test.cpp
+++ b/libc/test/src/math/atanbf16_test.cpp
@@ -1,4 +1,4 @@
-//===-- Unittests for atanbf16 -----------------------------------------------===//
+//===-- Unittests for atanbf16 --------------------------------------------===//
//
// 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/smoke/atanbf16_test.cpp b/libc/test/src/math/smoke/atanbf16_test.cpp
index ab79f712979af..6e15955316946 100644
--- a/libc/test/src/math/smoke/atanbf16_test.cpp
+++ b/libc/test/src/math/smoke/atanbf16_test.cpp
@@ -32,8 +32,7 @@ class LlvmLibcAtanBf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atanbf16(neg_zero));
EXPECT_MATH_ERRNO(0);
- bfloat16 VALUES[] = {inf, neg_inf, bfloat16(1.0f),
- bfloat16(-1.0)};
+ bfloat16 VALUES[] = {inf, neg_inf, bfloat16(1.0f), bfloat16(-1.0)};
for (size_t i = 0; i < 4; ++i) {
bfloat16 x = VALUES[i];
>From 3b4ba394c43ccf79dadbd192722cf54617f08317 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 1 Mar 2026 23:39:59 +0530
Subject: [PATCH 11/19] chore: bazel
---
utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index d331a411629c4..63d051c14dc05 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3100,6 +3100,7 @@ libc_support_library(
name = "__support_math_atanbf16",
hdrs = ["src/__support/math/atanbf16.h"],
deps = [
+ ":__support_fputil_bfloat16",
":__support_fputil_cast",
":__support_fputil_fenv_impl",
":__support_fputil_fp_bits",
@@ -3107,7 +3108,6 @@ libc_support_library(
":__support_fputil_polyeval",
":__support_fputil_sqrt",
":__support_macros_optimization",
- ":__support_fputil_bfloat16",
],
)
>From f97cd22d55a44cd8b279352372776186d7c556d8 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 3 Mar 2026 20:50:46 +0530
Subject: [PATCH 12/19] chore: removed redundant exhaustive
---
libc/test/src/math/exhaustive/CMakeLists.txt | 17 ------
.../src/math/exhaustive/atanbf16_test.cpp | 56 -------------------
2 files changed, 73 deletions(-)
delete mode 100644 libc/test/src/math/exhaustive/atanbf16_test.cpp
diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt
index 77a794ad5dfb9..2d1301d3a1e66 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -619,23 +619,6 @@ add_fp_unittest(
-lpthread
)
-add_fp_unittest(
- atanbf16_test
- NO_RUN_POSTBUILD
- NEED_MPFR
- SUITE
- libc_math_exhaustive_tests
- SRCS
- atanbf16_test.cpp
- DEPENDS
- .exhaustive_test
- libc.src.math.atanbf16
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.bfloat16
- LINK_LIBRARIES
- -lpthread
-)
-
add_fp_unittest(
atanf_test
NO_RUN_POSTBUILD
diff --git a/libc/test/src/math/exhaustive/atanbf16_test.cpp b/libc/test/src/math/exhaustive/atanbf16_test.cpp
deleted file mode 100644
index 347d9a932d7ff..0000000000000
--- a/libc/test/src/math/exhaustive/atanbf16_test.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- Exhaustive tests for atanb16 addition -----------------------------===//
-//
-// 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/atanbf16.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include "utils/MPFRWrapper/MPFRUtils.h"
-
-using LlvmLibcAtanBf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
-
-namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-
-// Normal range: [+0, +int]
-static constexpr uint16_t POS_START = 0x0000U;
-static constexpr uint16_t POS_STOP = 0x7f80U;
-
-// Normal range: [-0, -int]
-static constexpr uint16_t NEG_START = 0x8000U;
-static constexpr uint16_t NEG_STOP = 0xff80U;
-
-TEST_F(LlvmLibcAtanBf16Test, NormalPositiveRange) {
- for (uint16_t v1 = POS_START; v1 <= POS_STOP; v1++) {
-
- bfloat16 x = FPBits(v1).get_val();
-
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
- LIBC_NAMESPACE::atanbf16(x), 0.5);
- }
-}
-
-TEST_F(LlvmLibcAtanBf16Test, NormalNegativeRange) {
- for (uint16_t v1 = NEG_START; v1 <= NEG_STOP; v1++) {
-
- bfloat16 x = FPBits(v1).get_val();
-
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
- LIBC_NAMESPACE::atanbf16(x), 0.5);
- }
-}
-
-TEST_F(LlvmLibcAtanBf16Test, SpecialNumbers) {
- constexpr bfloat16 VALUES[] = {zero, neg_zero, inf,
- neg_inf, min_normal, max_normal};
- for (size_t i = 0; i < 6; ++i) {
- bfloat16 x = VALUES[i];
-
- EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
- LIBC_NAMESPACE::atanbf16(x), 0.5);
- }
-}
>From 09846dc549b5073cf4d03e21b819bc918695aa7d Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 18 Mar 2026 22:03:17 +0530
Subject: [PATCH 13/19] nit
---
libc/test/src/math/CMakeLists.txt | 2 --
1 file changed, 2 deletions(-)
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 3f7e01a1a480f..ceed946e2386e 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -69,7 +69,6 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
-
add_fp_unittest(
cospif16_test
NEED_MPFR
@@ -2629,7 +2628,6 @@ add_fp_unittest(
libc.src.__support.FPUtil.bfloat16
)
-
add_fp_unittest(
atanf16_test
NEED_MPFR
>From 4bce8edb52dfce1711b49f02bb95048c8ddcda2a Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Fri, 20 Mar 2026 23:22:15 +0530
Subject: [PATCH 14/19] chore: added comments about worst case + polynomial
error
---
libc/src/__support/math/atanbf16.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
index ba519c08b94b0..566234e2252b0 100644
--- a/libc/src/__support/math/atanbf16.h
+++ b/libc/src/__support/math/atanbf16.h
@@ -67,6 +67,12 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
// > display = hexadecimal ;
// > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|SG, SG,
// SG..SG|], [0, 1]);
+ //
+ // absolute error for the polynomial given by:
+ // dirtyinfnorm(atan(x) - x * P(x), [0, 1]) gives
+ // error ~ 0x1.482168p-24
+ // worst case error for it being ~ 0x1.dcf750p-23
+ // satisfying -> error < worst_case
if (x_abs <= 0x3f80) {
float result = fputil::polyeval(
x_sq, 0x1.fffffcp-1f, -0x1.55519ep-2f, 0x1.98f6a8p-3f, -0x1.1f0a92p-3f,
@@ -84,6 +90,11 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
// > display = hexadecimal ;
// > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|SG, SG, SG...
// SG|], [0, 1]); (here its atan(1/|x|)/(1/|x|))
+ // absolute error for the polynomial given by:
+ // dirtyinfnorm(atan(x) - x * P(x), [0, 1]) gives
+ // error ~ 0x1.482168p-24
+ // worst case error for it being ~ 0x1.dcf750p-23
+ // satisfying -> error < worst_case
float result =
fputil::polyeval(x_inv_sq, 0x1.fffffcp-1f, -0x1.55519ep-2f,
0x1.98f6a8p-3f, -0x1.1f0a92p-3f, 0x1.95b654p-4f,
>From 5f7ccca1f25df0e811c7d053ea42699551bd4758 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Fri, 20 Mar 2026 23:39:37 +0530
Subject: [PATCH 15/19] chore: used rel_err and added lambda function
---
libc/src/__support/math/atanbf16.h | 32 +++++++++++-------------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
index 566234e2252b0..6a3af8f6db333 100644
--- a/libc/src/__support/math/atanbf16.h
+++ b/libc/src/__support/math/atanbf16.h
@@ -57,7 +57,6 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
float xf = x;
float x_sq = xf * xf;
- // |x| <= 1
// Taylor series -> [x - x^3/3 + x^5/5 - x^7/7 ...]
// x * [1 - x^2/3 + x^4/5 - x^6/7...] -> x * P(x)
// atan(x) = x * poly(x^2)
@@ -68,15 +67,20 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
// > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|SG, SG,
// SG..SG|], [0, 1]);
//
- // absolute error for the polynomial given by:
- // dirtyinfnorm(atan(x) - x * P(x), [0, 1]) gives
- // error ~ 0x1.482168p-24
+ // relative error for the polynomial given by:
+ // > dirtyinfnorm(atan(x)/x - P(x), [0, 1]);
+ // gives error ~ 0x1p-23
// worst case error for it being ~ 0x1.dcf750p-23
// satisfying -> error < worst_case
+ auto atan_eval = [](float x0) {
+ return fputil::polyeval(x0, 0x1.fffffcp-1f, -0x1.55519ep-2f, 0x1.98f6a8p-3f,
+ -0x1.1f0a92p-3f, 0x1.95b654p-4f, -0x1.e65492p-5f,
+ 0x1.8c0c36p-6f, -0x1.32316ep-8f);
+ };
+
+ // |x| <= 1
if (x_abs <= 0x3f80) {
- float result = fputil::polyeval(
- x_sq, 0x1.fffffcp-1f, -0x1.55519ep-2f, 0x1.98f6a8p-3f, -0x1.1f0a92p-3f,
- 0x1.95b654p-4f, -0x1.e65492p-5f, 0x1.8c0c36p-6f, -0x1.32316ep-8f);
+ float result = atan_eval(x_sq);
return fputil::cast<bfloat16>(xf * result);
}
@@ -86,19 +90,7 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
float x_inv_sq = 1.0f / x_sq;
float x_inv = fputil::sqrt<float>(x_inv_sq);
- // Degree 14 polynomial of atan(1/|x|) generated using Sollya with command :
- // > display = hexadecimal ;
- // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|SG, SG, SG...
- // SG|], [0, 1]); (here its atan(1/|x|)/(1/|x|))
- // absolute error for the polynomial given by:
- // dirtyinfnorm(atan(x) - x * P(x), [0, 1]) gives
- // error ~ 0x1.482168p-24
- // worst case error for it being ~ 0x1.dcf750p-23
- // satisfying -> error < worst_case
- float result =
- fputil::polyeval(x_inv_sq, 0x1.fffffcp-1f, -0x1.55519ep-2f,
- 0x1.98f6a8p-3f, -0x1.1f0a92p-3f, 0x1.95b654p-4f,
- -0x1.e65492p-5f, 0x1.8c0c36p-6f, -0x1.32316ep-8f);
+ float result = atan_eval(x_inv_sq);
return fputil::cast<bfloat16>(sign *
fputil::multiply_add(x_inv, -result, PI_2));
}
>From 55d54a397afa606dd2109c35f23f42412d1f5c42 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 21 Mar 2026 01:07:22 +0530
Subject: [PATCH 16/19] optimize: leading coeffecient 1 + tiny x
---
libc/src/__support/math/atanbf16.h | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
index 6a3af8f6db333..b61002f9bcd97 100644
--- a/libc/src/__support/math/atanbf16.h
+++ b/libc/src/__support/math/atanbf16.h
@@ -27,7 +27,7 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
// > display = hexadecimal;
// > round(pi/2, SG, RN);
constexpr float PI_2 = 0x1.921fb6p0f;
-
+
using FPBits = fputil::FPBits<bfloat16>;
FPBits xbits(x);
@@ -51,9 +51,12 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
}
// atanbf16(+/-0) = +/-0
- if (LIBC_UNLIKELY(x_abs == 0))
- return x;
+ // For smaller x
+if (LIBC_UNLIKELY(x_abs <= 0x3db8)) {
+ return fputil::cast<bfloat16>(
+ fputil::multiply_add(static_cast<float>(x), -0x1p-25f, static_cast<float>(x)));
+}
float xf = x;
float x_sq = xf * xf;
@@ -73,15 +76,13 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
// worst case error for it being ~ 0x1.dcf750p-23
// satisfying -> error < worst_case
auto atan_eval = [](float x0) {
- return fputil::polyeval(x0, 0x1.fffffcp-1f, -0x1.55519ep-2f, 0x1.98f6a8p-3f,
- -0x1.1f0a92p-3f, 0x1.95b654p-4f, -0x1.e65492p-5f,
- 0x1.8c0c36p-6f, -0x1.32316ep-8f);
+ return fputil::polyeval(x0,-0x1.5552c4p-2f, 0x1.990f2p-3f, -0x1.1f7dccp-3f, 0x1.97e49p-4f, -0x1.ebff34p-5f, 0x1.938e46p-6f, -0x1.3a28bcp-8f);
};
// |x| <= 1
if (x_abs <= 0x3f80) {
float result = atan_eval(x_sq);
- return fputil::cast<bfloat16>(xf * result);
+ return fputil::cast<bfloat16>(fputil::multiply_add(xf * x_sq, result, xf));
}
// If |x| > 1:
@@ -91,8 +92,8 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
float x_inv = fputil::sqrt<float>(x_inv_sq);
float result = atan_eval(x_inv_sq);
- return fputil::cast<bfloat16>(sign *
- fputil::multiply_add(x_inv, -result, PI_2));
+float atan_inv = fputil::multiply_add(x_inv * x_inv_sq, result, x_inv);
+return fputil::cast<bfloat16>(sign * (PI_2 - atan_inv));
}
} // namespace math
>From 883c0808baff36a815fa6c405a6a1ef5fe48e9cb Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 21 Mar 2026 01:08:55 +0530
Subject: [PATCH 17/19] nit
---
libc/src/__support/math/atanbf16.h | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
index b61002f9bcd97..af26825788f86 100644
--- a/libc/src/__support/math/atanbf16.h
+++ b/libc/src/__support/math/atanbf16.h
@@ -27,7 +27,7 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
// > display = hexadecimal;
// > round(pi/2, SG, RN);
constexpr float PI_2 = 0x1.921fb6p0f;
-
+
using FPBits = fputil::FPBits<bfloat16>;
FPBits xbits(x);
@@ -51,12 +51,13 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
}
// atanbf16(+/-0) = +/-0
-
+if (LIBC_UNLIKELY(x_abs == 0))
+ return x;
// For smaller x
-if (LIBC_UNLIKELY(x_abs <= 0x3db8)) {
- return fputil::cast<bfloat16>(
- fputil::multiply_add(static_cast<float>(x), -0x1p-25f, static_cast<float>(x)));
-}
+ if (LIBC_UNLIKELY(x_abs <= 0x3db8)) {
+ return fputil::cast<bfloat16>(fputil::multiply_add(
+ static_cast<float>(x), -0x1p-25f, static_cast<float>(x)));
+ }
float xf = x;
float x_sq = xf * xf;
@@ -76,13 +77,15 @@ if (LIBC_UNLIKELY(x_abs <= 0x3db8)) {
// worst case error for it being ~ 0x1.dcf750p-23
// satisfying -> error < worst_case
auto atan_eval = [](float x0) {
- return fputil::polyeval(x0,-0x1.5552c4p-2f, 0x1.990f2p-3f, -0x1.1f7dccp-3f, 0x1.97e49p-4f, -0x1.ebff34p-5f, 0x1.938e46p-6f, -0x1.3a28bcp-8f);
+ return fputil::polyeval(x0, -0x1.5552c4p-2f, 0x1.990f2p-3f, -0x1.1f7dccp-3f,
+ 0x1.97e49p-4f, -0x1.ebff34p-5f, 0x1.938e46p-6f,
+ -0x1.3a28bcp-8f);
};
// |x| <= 1
if (x_abs <= 0x3f80) {
float result = atan_eval(x_sq);
- return fputil::cast<bfloat16>(fputil::multiply_add(xf * x_sq, result, xf));
+ return fputil::cast<bfloat16>(fputil::multiply_add(xf * x_sq, result, xf));
}
// If |x| > 1:
@@ -92,8 +95,8 @@ if (LIBC_UNLIKELY(x_abs <= 0x3db8)) {
float x_inv = fputil::sqrt<float>(x_inv_sq);
float result = atan_eval(x_inv_sq);
-float atan_inv = fputil::multiply_add(x_inv * x_inv_sq, result, x_inv);
-return fputil::cast<bfloat16>(sign * (PI_2 - atan_inv));
+ float atan_inv = fputil::multiply_add(x_inv * x_inv_sq, result, x_inv);
+ return fputil::cast<bfloat16>(sign * (PI_2 - atan_inv));
}
} // namespace math
>From a9289dc68e4a88b1df2e094177f2f5fe31405180 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 21 Mar 2026 01:17:44 +0530
Subject: [PATCH 18/19] updated comments for new polynomial
---
libc/src/__support/math/atanbf16.h | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
index af26825788f86..d5b53e907cfe1 100644
--- a/libc/src/__support/math/atanbf16.h
+++ b/libc/src/__support/math/atanbf16.h
@@ -51,13 +51,9 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
}
// atanbf16(+/-0) = +/-0
-if (LIBC_UNLIKELY(x_abs == 0))
- return x;
- // For smaller x
- if (LIBC_UNLIKELY(x_abs <= 0x3db8)) {
- return fputil::cast<bfloat16>(fputil::multiply_add(
- static_cast<float>(x), -0x1p-25f, static_cast<float>(x)));
- }
+ if (LIBC_UNLIKELY(x_abs == 0))
+ return x;
+
float xf = x;
float x_sq = xf * xf;
@@ -68,12 +64,12 @@ if (LIBC_UNLIKELY(x_abs == 0))
// Degree 14 polynomial of atan(x) generated using Sollya with command :
// > display = hexadecimal ;
- // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|SG, SG,
+ // > P = fpminimax(atan(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|1, SG,
// SG..SG|], [0, 1]);
//
// relative error for the polynomial given by:
// > dirtyinfnorm(atan(x)/x - P(x), [0, 1]);
- // gives error ~ 0x1p-23
+ // gives error ~ 0x1.ee44001p-24
// worst case error for it being ~ 0x1.dcf750p-23
// satisfying -> error < worst_case
auto atan_eval = [](float x0) {
@@ -82,6 +78,11 @@ if (LIBC_UNLIKELY(x_abs == 0))
-0x1.3a28bcp-8f);
};
+ // For smaller x
+ if (LIBC_UNLIKELY(x_abs <= 0x3db8)) {
+ return fputil::cast<bfloat16>(fputil::multiply_add(xf, -0x1p-25f, xf));
+ }
+
// |x| <= 1
if (x_abs <= 0x3f80) {
float result = atan_eval(x_sq);
>From 22c82480d1ae20d58ca87b866d3a4722a2fd3ed6 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 21 Mar 2026 01:21:03 +0530
Subject: [PATCH 19/19] nit
---
libc/src/__support/math/atanbf16.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/math/atanbf16.h b/libc/src/__support/math/atanbf16.h
index d5b53e907cfe1..cbaf3da4e10ee 100644
--- a/libc/src/__support/math/atanbf16.h
+++ b/libc/src/__support/math/atanbf16.h
@@ -52,7 +52,7 @@ LIBC_INLINE bfloat16 atanbf16(bfloat16 x) {
// atanbf16(+/-0) = +/-0
if (LIBC_UNLIKELY(x_abs == 0))
- return x;
+ return x;
float xf = x;
float x_sq = xf * xf;
More information about the libc-commits
mailing list