[libc-commits] [libc] f0d05bb - [libc][math] Fix signed zeros for acosf, acoshf, and atanf in FE_DOWNWARD mode.
Tue Ly via libc-commits
libc-commits at lists.llvm.org
Thu Sep 7 08:21:49 PDT 2023
Author: Tue Ly
Date: 2023-09-07T15:21:33Z
New Revision: f0d05bb69947174c38b13f735af507c43379a553
URL: https://github.com/llvm/llvm-project/commit/f0d05bb69947174c38b13f735af507c43379a553
DIFF: https://github.com/llvm/llvm-project/commit/f0d05bb69947174c38b13f735af507c43379a553.diff
LOG: [libc][math] Fix signed zeros for acosf, acoshf, and atanf in FE_DOWNWARD mode.
Fix signed zeros for acosf, acoshf, and atanf in FE_DOWNWARD mode.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D159476
Added:
Modified:
libc/src/math/generic/acosf.cpp
libc/src/math/generic/acoshf.cpp
libc/src/math/generic/atanf.cpp
libc/test/src/math/acosf_test.cpp
libc/test/src/math/acoshf_test.cpp
libc/test/src/math/asinf_test.cpp
libc/test/src/math/asinhf_test.cpp
libc/test/src/math/atanf_test.cpp
libc/test/src/math/atanhf_test.cpp
Removed:
################################################################################
diff --git a/libc/src/math/generic/acosf.cpp b/libc/src/math/generic/acosf.cpp
index 41152e06ff1f5d..ab13467b4a0a5f 100644
--- a/libc/src/math/generic/acosf.cpp
+++ b/libc/src/math/generic/acosf.cpp
@@ -73,8 +73,13 @@ LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
return static_cast<float>(fputil::multiply_add(-x3, r, M_MATH_PI_2 - xd));
}
- // |x| > 1, return NaNs.
- if (LIBC_UNLIKELY(x_abs > 0x3f80'0000U)) {
+ // |x| >= 1, return 0, 2pi, or NaNs.
+ if (LIBC_UNLIKELY(x_abs >= 0x3f80'0000U)) {
+ if (x_abs == 0x3f80'0000U)
+ return x_sign ? /* x == -1.0f */ fputil::round_result_slightly_down(
+ 0x1.921fb6p+1f)
+ : /* x == 1.0f */ 0.0f;
+
if (x_abs <= 0x7f80'0000U) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
@@ -82,7 +87,7 @@ LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
return x + FPBits::build_quiet_nan(0);
}
- // When 0.5 < |x| <= 1, we perform range reduction as follow:
+ // When 0.5 < |x| < 1, we perform range reduction as follow:
//
// Assume further that 0.5 < x <= 1, and let:
// y = acos(x)
@@ -100,7 +105,7 @@ LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
// |x| <= 0.5:
// acos(x) ~ 2 * sqrt(u) * P(u).
//
- // When -1 <= x <= -0.5, we use the identity:
+ // When -1 < x <= -0.5, we use the identity:
// acos(x) = pi - acos(-x)
// which is reduced to the postive case.
diff --git a/libc/src/math/generic/acoshf.cpp b/libc/src/math/generic/acoshf.cpp
index f8e5a90a4d056c..ce352764fbbc19 100644
--- a/libc/src/math/generic/acoshf.cpp
+++ b/libc/src/math/generic/acoshf.cpp
@@ -23,7 +23,9 @@ LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
FPBits_t xbits(x);
uint32_t x_u = xbits.uintval();
- if (LIBC_UNLIKELY(x < 1.0f)) {
+ if (LIBC_UNLIKELY(x <= 1.0f)) {
+ if (x == 1.0f)
+ return 0.0f;
// x < 1.
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/atanf.cpp b/libc/src/math/generic/atanf.cpp
index 9b0c11996a5b2b..5037806d37a1b1 100644
--- a/libc/src/math/generic/atanf.cpp
+++ b/libc/src/math/generic/atanf.cpp
@@ -17,6 +17,11 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(float, atanf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
+
+ // x == 0.0
+ if (LIBC_UNLIKELY(x == 0.0f))
+ return x;
+
FPBits xbits(x);
bool sign = xbits.get_sign();
xbits.set_sign(false);
diff --git a/libc/test/src/math/acosf_test.cpp b/libc/test/src/math/acosf_test.cpp
index 1d4000c10eb837..63895ec3e30aef 100644
--- a/libc/test/src/math/acosf_test.cpp
+++ b/libc/test/src/math/acosf_test.cpp
@@ -26,13 +26,22 @@ DECLARE_SPECIAL_CONSTANTS(float)
TEST(LlvmLibcAcosfTest, SpecialNumbers) {
libc_errno = 0;
- EXPECT_FP_EQ(aNaN, __llvm_libc::acosf(aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::acosf(aNaN));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(aNaN, __llvm_libc::acosf(inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::acosf(inf));
EXPECT_MATH_ERRNO(EDOM);
- EXPECT_FP_EQ(aNaN, __llvm_libc::acosf(neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::acosf(neg_inf));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(zero, __llvm_libc::acosf(1.0f));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::acosf(2.0f));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::acosf(-2.0f));
EXPECT_MATH_ERRNO(EDOM);
}
diff --git a/libc/test/src/math/acoshf_test.cpp b/libc/test/src/math/acoshf_test.cpp
index 148813ce28495b..895503c6bc73cd 100644
--- a/libc/test/src/math/acoshf_test.cpp
+++ b/libc/test/src/math/acoshf_test.cpp
@@ -26,19 +26,19 @@ DECLARE_SPECIAL_CONSTANTS(float)
TEST(LlvmLibcAcoshfTest, SpecialNumbers) {
libc_errno = 0;
- EXPECT_FP_EQ(aNaN, __llvm_libc::acoshf(aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::acoshf(aNaN));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(aNaN, __llvm_libc::acoshf(0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::acoshf(0.0f));
EXPECT_MATH_ERRNO(EDOM);
- EXPECT_FP_EQ(0.0f, __llvm_libc::acoshf(1.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0f, __llvm_libc::acoshf(1.0f));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(inf, __llvm_libc::acoshf(inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, __llvm_libc::acoshf(inf));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(aNaN, __llvm_libc::acoshf(neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::acoshf(neg_inf));
EXPECT_MATH_ERRNO(EDOM);
}
diff --git a/libc/test/src/math/asinf_test.cpp b/libc/test/src/math/asinf_test.cpp
index cd1431ae739390..cc99e5b7b6cac8 100644
--- a/libc/test/src/math/asinf_test.cpp
+++ b/libc/test/src/math/asinf_test.cpp
@@ -27,19 +27,19 @@ DECLARE_SPECIAL_CONSTANTS(float)
TEST(LlvmLibcAsinfTest, SpecialNumbers) {
libc_errno = 0;
- EXPECT_FP_EQ(aNaN, __llvm_libc::asinf(aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::asinf(aNaN));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(0.0f, __llvm_libc::asinf(0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0f, __llvm_libc::asinf(0.0f));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(-0.0f, __llvm_libc::asinf(-0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, __llvm_libc::asinf(-0.0f));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(aNaN, __llvm_libc::asinf(inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::asinf(inf));
EXPECT_MATH_ERRNO(EDOM);
- EXPECT_FP_EQ(aNaN, __llvm_libc::asinf(neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::asinf(neg_inf));
EXPECT_MATH_ERRNO(EDOM);
}
diff --git a/libc/test/src/math/asinhf_test.cpp b/libc/test/src/math/asinhf_test.cpp
index f7ba2eae4b7fe9..cadb9572c372e8 100644
--- a/libc/test/src/math/asinhf_test.cpp
+++ b/libc/test/src/math/asinhf_test.cpp
@@ -26,19 +26,19 @@ DECLARE_SPECIAL_CONSTANTS(float)
TEST(LlvmLibcAsinhfTest, SpecialNumbers) {
libc_errno = 0;
- EXPECT_FP_EQ(aNaN, __llvm_libc::asinhf(aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::asinhf(aNaN));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(0.0f, __llvm_libc::asinhf(0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0f, __llvm_libc::asinhf(0.0f));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(-0.0f, __llvm_libc::asinhf(-0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, __llvm_libc::asinhf(-0.0f));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(inf, __llvm_libc::asinhf(inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, __llvm_libc::asinhf(inf));
EXPECT_MATH_ERRNO(0);
- EXPECT_FP_EQ(neg_inf, __llvm_libc::asinhf(neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, __llvm_libc::asinhf(neg_inf));
EXPECT_MATH_ERRNO(0);
}
diff --git a/libc/test/src/math/atanf_test.cpp b/libc/test/src/math/atanf_test.cpp
index 208104cc26dd97..cd60b8d8a775e6 100644
--- a/libc/test/src/math/atanf_test.cpp
+++ b/libc/test/src/math/atanf_test.cpp
@@ -28,17 +28,17 @@ DECLARE_SPECIAL_CONSTANTS(float)
TEST(LlvmLibcAtanfTest, SpecialNumbers) {
libc_errno = 0;
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(aNaN, __llvm_libc::atanf(aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::atanf(aNaN));
EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(0.0f, __llvm_libc::atanf(0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0f, __llvm_libc::atanf(0.0f));
EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(-0.0f, __llvm_libc::atanf(-0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, __llvm_libc::atanf(-0.0f));
EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);
}
diff --git a/libc/test/src/math/atanhf_test.cpp b/libc/test/src/math/atanhf_test.cpp
index 7dce915714844d..021a3f177b821e 100644
--- a/libc/test/src/math/atanhf_test.cpp
+++ b/libc/test/src/math/atanhf_test.cpp
@@ -26,27 +26,27 @@ DECLARE_SPECIAL_CONSTANTS(float)
TEST(LlvmLibcAtanhfTest, SpecialNumbers) {
libc_errno = 0;
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(aNaN, __llvm_libc::atanhf(aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::atanhf(aNaN));
EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(0.0f, __llvm_libc::atanhf(0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0f, __llvm_libc::atanhf(0.0f));
EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(-0.0f, __llvm_libc::atanhf(-0.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, __llvm_libc::atanhf(-0.0f));
EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(inf, __llvm_libc::atanhf(1.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, __llvm_libc::atanhf(1.0f));
EXPECT_FP_EXCEPTION(FE_DIVBYZERO);
EXPECT_MATH_ERRNO(ERANGE);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(neg_inf, __llvm_libc::atanhf(-1.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, __llvm_libc::atanhf(-1.0f));
EXPECT_FP_EXCEPTION(FE_DIVBYZERO);
EXPECT_MATH_ERRNO(ERANGE);
@@ -54,33 +54,33 @@ TEST(LlvmLibcAtanhfTest, SpecialNumbers) {
bt.bits += 1;
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(aNaN, __llvm_libc::atanhf(bt.get_val()));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::atanhf(bt.get_val()));
EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
bt.set_sign(true);
- EXPECT_FP_EQ(aNaN, __llvm_libc::atanhf(bt.get_val()));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::atanhf(bt.get_val()));
EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(aNaN, __llvm_libc::atanhf(2.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::atanhf(2.0f));
EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(aNaN, __llvm_libc::atanhf(-2.0f));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::atanhf(-2.0f));
EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
- EXPECT_FP_EQ(aNaN, __llvm_libc::atanhf(inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::atanhf(inf));
EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);
bt.set_sign(true);
- EXPECT_FP_EQ(aNaN, __llvm_libc::atanhf(neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, __llvm_libc::atanhf(neg_inf));
EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);
}
More information about the libc-commits
mailing list