[libc-commits] [libc] [libc][math] Added missing floating point exception for atanpif16 (PR #187060)
via libc-commits
libc-commits at lists.llvm.org
Tue Mar 17 09:59:08 PDT 2026
https://github.com/Sukumarsawant created https://github.com/llvm/llvm-project/pull/187060
This PR intends to fix the missed FP exceptions for atanpif16
>From e646189ebbe765fc13648eca446039f31ea7b4e3 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 17 Mar 2026 22:25:44 +0530
Subject: [PATCH 1/2] feat: added tests and handling except cases
---
libc/src/__support/FPUtil/dyadic_float.h | 1 +
libc/src/__support/math/atanpif16.h | 30 +++++++++++++++------
libc/test/src/math/smoke/CMakeLists.txt | 1 +
libc/test/src/math/smoke/atanpif16_test.cpp | 7 +++++
4 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index cc0710fbf7b02..018429b30272a 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -219,6 +219,7 @@ template <size_t Bits> struct DyadicFloat {
underflow = true;
} else if (unbiased_exp == -FPBits::EXP_BIAS - FPBits::FRACTION_LEN) {
round = true;
+ underflow = true;
MantissaType sticky_mask = (MantissaType(1) << (Bits - 1)) - 1;
sticky = (mantissa & sticky_mask) != 0;
} else {
diff --git a/libc/src/__support/math/atanpif16.h b/libc/src/__support/math/atanpif16.h
index e0eaff6678fc5..468f35a38161f 100644
--- a/libc/src/__support/math/atanpif16.h
+++ b/libc/src/__support/math/atanpif16.h
@@ -95,14 +95,8 @@ LIBC_INLINE float16 atanpif16(float16 x) {
return signed_result(0.5);
}
- if (LIBC_UNLIKELY(xbits.is_zero()))
- return x;
-
double x_abs = fputil::cast<double>(xbits.abs().get_val());
- if (LIBC_UNLIKELY(x_abs == 1.0))
- return signed_result(0.25);
-
// evaluate atan(x)/pi using polynomial approximation, valid for |x| <= 0.5
constexpr auto atanpi_eval = [](double x) -> double {
// polynomial coefficients for atan(x)/pi taylor series
@@ -125,14 +119,34 @@ LIBC_INLINE float16 atanpif16(float16 x) {
// case 1: |x| <= 0.5 - direct polynomial evaluation
if (LIBC_LIKELY(x_abs <= 0.5)) {
+
+ if (LIBC_UNLIKELY(xbits.is_zero()))
+ return x;
+
+ if (LIBC_UNLIKELY(xbits.abs().uintval() == 0x0a48)) {
+ int rounding = fputil::quick_get_round();
+ if (!is_neg) {
+ if (rounding == FE_UPWARD)
+ return fputil::cast<float16>(0x1p-14f);
+ return fputil::cast<float16>(0x1.ffd7ap-15f);
+ } else {
+ if (rounding == FE_DOWNWARD)
+ return fputil::cast<float16>(-0x1p-14f);
+ return fputil::cast<float16>(-0x1.ffd7ap-15f);
+ }
+ }
double result = atanpi_eval(x_abs);
- return signed_result(result);
+ float16 s_result = signed_result(result);
+ return s_result;
}
+ if (LIBC_UNLIKELY(x_abs == 1.0))
+ return signed_result(0.25);
+
// case 2: 0.5 < |x| <= 1 - use double-angle reduction
// atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2)))
// so atanpi(x) = 2 * atanpi(x') where x' = x / (1 + sqrt(1 + x^2))
- if (x_abs <= 1.0) {
+ if (x_abs < 1.0) {
double x_abs_sq = x_abs * x_abs;
double sqrt_term = fputil::sqrt<double>(1.0 + x_abs_sq);
double x_prime = x_abs / (1.0 + sqrt_term);
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index d92e6b728b63e..12f378f7c1128 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4719,6 +4719,7 @@ add_fp_unittest(
atanpif16_test.cpp
DEPENDS
libc.src.math.atanpif16
+ libc.hdr.errno_macros
)
add_fp_unittest(
diff --git a/libc/test/src/math/smoke/atanpif16_test.cpp b/libc/test/src/math/smoke/atanpif16_test.cpp
index ffc8ad7296309..b57c53521411a 100644
--- a/libc/test/src/math/smoke/atanpif16_test.cpp
+++ b/libc/test/src/math/smoke/atanpif16_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/errno_macros.h"
#include "src/math/atanpif16.h"
#include "test/UnitTest/FPMatcher.h"
@@ -61,3 +62,9 @@ TEST_F(LlvmLibcAtanpif16Test, MonotonicityProperty) {
EXPECT_TRUE(result1 < result2);
}
}
+
+TEST_F(LlvmLibcAtanpif16Test, Underflow) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(0x1p-24f16, LIBC_NAMESPACE::atanpif16(0x1p-23f16),
+ FE_UNDERFLOW | FE_INEXACT);
+ EXPECT_MATH_ERRNO(ERANGE);
+}
\ No newline at end of file
>From 88a9f2e7755b012f96495357da26276ff7bb04b0 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 17 Mar 2026 22:27:35 +0530
Subject: [PATCH 2/2] nit
---
libc/test/src/math/smoke/atanpif16_test.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/test/src/math/smoke/atanpif16_test.cpp b/libc/test/src/math/smoke/atanpif16_test.cpp
index b57c53521411a..4521948973419 100644
--- a/libc/test/src/math/smoke/atanpif16_test.cpp
+++ b/libc/test/src/math/smoke/atanpif16_test.cpp
@@ -67,4 +67,4 @@ TEST_F(LlvmLibcAtanpif16Test, Underflow) {
EXPECT_FP_EQ_WITH_EXCEPTION(0x1p-24f16, LIBC_NAMESPACE::atanpif16(0x1p-23f16),
FE_UNDERFLOW | FE_INEXACT);
EXPECT_MATH_ERRNO(ERANGE);
-}
\ No newline at end of file
+}
More information about the libc-commits
mailing list