[libc] [llvm] [libc][math][c23] Add atanbf16 function (PR #184019)

via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 6 21:16:26 PST 2026


https://github.com/Sukumarsawant updated https://github.com/llvm/llvm-project/pull/184019

>From c4c1ce9149a12a494a2bc88d9e4c50be37298c3f 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/12] 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 582e7c52726fe..f6cd05ed202a4 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -344,6 +344,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 98374e6cede73..8daa298c0deba 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -347,6 +347,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 b45b388ec9634..86ed4fa05e444 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -345,6 +345,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 5488bf1d0c7de..a28d14b964c71 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -160,6 +160,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 856bf1d55f3be..3455769fc2796 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -291,6 +291,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 8765cf189f325..7c323b9a0f1a5 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -291,6 +291,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 d27dabaff5c19..045db8fdc25c1 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -430,6 +430,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 714bd024dad1c..f6eb66d1dc191 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -260,6 +260,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 b823e1b25e6cc..c7c60e79643cc 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -434,6 +434,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 f1b3e90cfd031..e22c5eea34d21 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -476,6 +476,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 d88a49c9850ee..42cd47d04cfba 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -141,6 +141,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 c01bed59a4c3de2b9fa16d7cde4fdec0f7477050 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/12] 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 379c17b5808b9fd4a1d921992dbe601ce4966d2d 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/12] 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 f6cd05ed202a4..dc8054e166469 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -344,7 +344,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
@@ -776,6 +775,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 8daa298c0deba..668872e1e374e 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -347,7 +347,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
@@ -779,6 +778,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 86ed4fa05e444..543f989934660 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -345,7 +345,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
@@ -777,6 +776,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 a28d14b964c71..756400ab42c5c 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -160,7 +160,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
@@ -593,6 +592,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 e899bf97ea3f6..701ae49057579 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -233,6 +233,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 3455769fc2796..73e0db87e872b 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -291,7 +291,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
@@ -618,6 +617,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 7c323b9a0f1a5..8bfaafa84eab6 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -291,7 +291,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
@@ -620,6 +619,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 045db8fdc25c1..300e3859eb109 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -430,7 +430,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
@@ -849,6 +848,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 f6eb66d1dc191..866c165189b2a 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -260,7 +260,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
@@ -462,6 +461,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 c7c60e79643cc..505ce227a74a5 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -434,7 +434,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
@@ -870,6 +869,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 e22c5eea34d21..6e26228e76f6c 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -476,7 +476,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
@@ -917,6 +916,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 42cd47d04cfba..b7ee98ad4cbf3 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -141,7 +141,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
@@ -309,6 +308,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 9c97d408b5fb291ee8c3f08ebfd1e71050be47f1 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/12] 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 c1243e1937bcc..f77f6eb0e247a 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -28,6 +28,7 @@
 #include "math/atan2.h"
 #include "math/atan2f.h"
 #include "math/atan2f128.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 44b6a10352537..5ef59abcc11fb 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -260,6 +260,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 7a9370fe487e2..f2fb9e4fd2326 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -62,6 +62,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 516817be16cf6..a56934f633707 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4131,6 +4131,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 e23b477d03009..11df23c90af9a 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -25,6 +25,7 @@ add_fp_unittest(
     libc.src.__support.math.atan2
     libc.src.__support.math.atan2f
     libc.src.__support.math.atan2f128
+    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 978418714cdfe..2d0867536149f 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -396,6 +396,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 47c05c650c70a..3f9ecd83297a6 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2568,6 +2568,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 877d653a26291..044f674d7717a 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -550,6 +550,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 88028d90d2d50..59936a3a98056 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4851,6 +4851,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 b700e0fe99465..5f7c79283dec2 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -2927,6 +2927,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"],
@@ -5833,6 +5849,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 5743b55dec833045b4507cc221f4097dcb37c76b 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/12] 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 d23e5c695495538377c5ac6a88bebe7b264f5fe2 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/12] 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 a56934f633707..17985b2691955 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4132,7 +4132,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 439d93efe1a774ba3c03db36c6e51556c1d3f9b5 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/12] 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 3f9ecd83297a6..dd33f7319ce80 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2574,7 +2574,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 60fed908c3e9380ea784ed5446f1a07ea8df3df9 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/12] 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 5ef59abcc11fb..0f968b42f10cc 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -266,7 +266,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 59936a3a98056..c34ceeba37620 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4853,6 +4853,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 5f7c79283dec2..ea58ea05cd092 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -2932,7 +2932,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 b777015acfc4f4ee636fff346f744a65edf818a1 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/12] 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 7ea54fb4d8263..9cc2665d6a2df 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -275,7 +275,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           |                        |                      | 1 ULP                  |                        | 7.12.4.4               | F.10.1.4                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+

>From c76d5fd8e45fb46f98bcc87a22df219ce26b4de1 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/12] 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 6c90b97fca17b6516e1f3e049ddd31925f97cc7b 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/12] 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 ea58ea05cd092..a5eea3e233d16 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -2931,6 +2931,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",
@@ -2938,7 +2939,6 @@ libc_support_library(
         ":__support_fputil_polyeval",
         ":__support_fputil_sqrt",
         ":__support_macros_optimization",
-        ":__support_fputil_bfloat16",
     ],
 )
 

>From 172b1b07227558eb28912504cfd5a9e40e3c1aa1 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/12] 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 044f674d7717a..877d653a26291 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -550,23 +550,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);
-  }
-}



More information about the llvm-commits mailing list