[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:52 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Zorojuro (Sukumarsawant)
<details>
<summary>Changes</summary>
This PR intends to fix the missed FP exceptions for atanpif16
---
Full diff: https://github.com/llvm/llvm-project/pull/187060.diff
4 Files Affected:
- (modified) libc/src/__support/FPUtil/dyadic_float.h (+1)
- (modified) libc/src/__support/math/atanpif16.h (+22-8)
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+1)
- (modified) libc/test/src/math/smoke/atanpif16_test.cpp (+7)
``````````diff
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..4521948973419 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);
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/187060
More information about the libc-commits
mailing list