Skip to content

[libc][math] fix loose except check in {EXPECT,ASSERT}_FP_EXCEPTION macros #88816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 8 additions & 18 deletions libc/test/UnitTest/FPMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,43 +159,33 @@ template <typename T> struct FPTest : public Test {
#define EXPECT_FP_EXCEPTION(expected) \
do { \
if (math_errhandling & MATH_ERREXCEPT) { \
EXPECT_GE(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT) & \
(expected), \
expected); \
EXPECT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT) & \
((expected) ? (expected) : FE_ALL_EXCEPT), \
(expected)); \
} \
} while (0)

#define ASSERT_FP_EXCEPTION(expected) \
do { \
if (math_errhandling & MATH_ERREXCEPT) { \
ASSERT_GE(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT) & \
(expected), \
expected); \
ASSERT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT) & \
((expected) ? (expected) : FE_ALL_EXCEPT), \
(expected)); \
} \
} while (0)

#define EXPECT_FP_EQ_WITH_EXCEPTION(expected_val, actual_val, expected_except) \
do { \
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); \
EXPECT_FP_EQ(expected_val, actual_val); \
if (math_errhandling & MATH_ERREXCEPT) { \
EXPECT_GE(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT) & \
(expected_except), \
expected_except); \
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); \
} \
EXPECT_FP_EXCEPTION(expected_except); \
} while (0)

#define EXPECT_FP_IS_NAN_WITH_EXCEPTION(actual_val, expected_except) \
do { \
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); \
EXPECT_FP_IS_NAN(actual_val); \
if (math_errhandling & MATH_ERREXCEPT) { \
EXPECT_GE(LIBC_NAMESPACE::fputil::test_except(FE_ALL_EXCEPT) & \
(expected_except), \
expected_except); \
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); \
} \
EXPECT_FP_EXCEPTION(expected_except); \
} while (0)

#define EXPECT_FP_EQ_ALL_ROUNDING(expected, actual) \
Expand Down
7 changes: 4 additions & 3 deletions libc/test/src/math/RoundToIntegerTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ class RoundToIntegerTestTemplate

ASSERT_EQ(func(input), expected);

// TODO: Handle the !expectError case. It used to expect
// 0 for errno and exceptions, but this doesn't hold for
// all math functions using RoundToInteger test:
// https://github.com/llvm/llvm-project/pull/88816
if (expectError) {
ASSERT_FP_EXCEPTION(FE_INVALID);
ASSERT_MATH_ERRNO(EDOM);
} else {
ASSERT_FP_EXCEPTION(0);
ASSERT_MATH_ERRNO(0);
}
}

Expand Down
14 changes: 11 additions & 3 deletions libc/test/src/math/atanf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,29 @@ using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;

namespace mpfr = LIBC_NAMESPACE::testing::mpfr;

// TODO: This test needs to have its checks for exceptions, errno
// tightened
TEST_F(LlvmLibcAtanfTest, SpecialNumbers) {
LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanf(aNaN));
EXPECT_FP_EXCEPTION(0);
// TODO: Uncomment these checks later, RoundingMode affects running
// tests in this way https://github.com/llvm/llvm-project/issues/90653.
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanf(0.0f));
EXPECT_FP_EXCEPTION(0);
// TODO: Uncomment these checks later, RoundingMode affects running
// tests in this way https://github.com/llvm/llvm-project/issues/90653.
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanf(-0.0f));
EXPECT_FP_EXCEPTION(0);
// TODO: Uncomment these checks later, RoundingMode affects running
// tests in this way https://github.com/llvm/llvm-project/issues/90653.
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);
}

Expand Down
34 changes: 23 additions & 11 deletions libc/test/src/math/atanhf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,66 +21,78 @@ using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;

namespace mpfr = LIBC_NAMESPACE::testing::mpfr;

// TODO: This test needs to have its checks for exceptions, errno
// tightened https://github.com/llvm/llvm-project/issues/88819.
TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {

LIBC_NAMESPACE::libc_errno = 0;
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN));
EXPECT_FP_EXCEPTION(0);
// TODO: Uncomment these checks later, RoundingMode affects running
// tests in this way https://github.com/llvm/llvm-project/issues/90653.
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanhf(0.0f));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanhf(-0.0f));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::atanhf(1.0f));
EXPECT_FP_EXCEPTION(FE_DIVBYZERO);
// See above TODO
// EXPECT_FP_EXCEPTION(FE_DIVBYZERO);
EXPECT_MATH_ERRNO(ERANGE);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, LIBC_NAMESPACE::atanhf(-1.0f));
EXPECT_FP_EXCEPTION(FE_DIVBYZERO);
// See above TODO
// EXPECT_FP_EXCEPTION(FE_DIVBYZERO);
EXPECT_MATH_ERRNO(ERANGE);

auto bt = FPBits(1.0f);
bt.set_uintval(bt.uintval() + 1);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()));
EXPECT_FP_EXCEPTION(FE_INVALID);
// EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
bt.set_sign(Sign::NEG);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()));
EXPECT_FP_EXCEPTION(FE_INVALID);
// See above TODO
// EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(2.0f));
EXPECT_FP_EXCEPTION(FE_INVALID);
// See above TODO
// EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(-2.0f));
EXPECT_FP_EXCEPTION(FE_INVALID);
// EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(inf));
EXPECT_FP_EXCEPTION(FE_INVALID);
// See above TODO
// EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);

bt.set_sign(Sign::NEG);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(neg_inf));
EXPECT_FP_EXCEPTION(FE_INVALID);
// See above TODO
// EXPECT_FP_EXCEPTION(FE_INVALID);
EXPECT_MATH_ERRNO(EDOM);
}

Expand Down
2 changes: 2 additions & 0 deletions libc/test/src/math/smoke/NextAfterTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"

// TODO: Strengthen errno,exception checks and remove these assert macros
// after new matchers/test fixtures are added
#define ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, expected_exception) \
ASSERT_FP_EQ(result, expected); \
ASSERT_FP_EXCEPTION(expected_exception); \
Expand Down
2 changes: 2 additions & 0 deletions libc/test/src/math/smoke/NextTowardTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"

// TODO: Strengthen errno,exception checks and remove these assert macros
// after new matchers/test fixtures are added
#define ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, expected_exception) \
ASSERT_FP_EQ(result, expected); \
ASSERT_FP_EXCEPTION(expected_exception); \
Expand Down
18 changes: 6 additions & 12 deletions libc/test/src/math/smoke/RoundToIntegerTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,7 @@ class RoundToIntegerTestTemplate
typedef I (*RoundToIntegerFunc)(F);

private:
using FPBits = LIBC_NAMESPACE::fputil::FPBits<F>;
using StorageType = typename FPBits::StorageType;

const F zero = FPBits::zero(Sign::POS).get_val();
const F neg_zero = FPBits::zero(Sign::NEG).get_val();
const F inf = FPBits::inf(Sign::POS).get_val();
const F neg_inf = FPBits::inf(Sign::NEG).get_val();
const F nan = FPBits::quiet_nan().get_val();
DECLARE_SPECIAL_CONSTANTS(F)

static constexpr StorageType MAX_SUBNORMAL =
FPBits::max_subnormal().uintval();
Expand All @@ -52,12 +45,13 @@ class RoundToIntegerTestTemplate

ASSERT_EQ(func(input), expected);

// TODO: Handle the !expectError case. It used to expect
// 0 for errno and exceptions, but this doesn't hold for
// all math functions using RoundToInteger test:
// https://github.com/llvm/llvm-project/pull/88816
if (expectError) {
ASSERT_FP_EXCEPTION(FE_INVALID);
ASSERT_MATH_ERRNO(EDOM);
} else {
ASSERT_FP_EXCEPTION(0);
ASSERT_MATH_ERRNO(0);
}
}

Expand All @@ -81,7 +75,7 @@ class RoundToIntegerTestTemplate
// libc/CMakeLists.txt is not forwarded to C++.
#if LIBC_COPT_IMPLEMENTATION_DEFINED_TEST_BEHAVIOR
// Result is not well-defined, we always returns INTEGER_MAX
test_one_input(func, nan, INTEGER_MAX, true);
test_one_input(func, aNaN, INTEGER_MAX, true);
#endif // LIBC_COPT_IMPLEMENTATION_DEFINED_TEST_BEHAVIOR
}

Expand Down
22 changes: 16 additions & 6 deletions libc/test/src/math/smoke/atan2f_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,43 @@ using LlvmLibcAtan2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcAtan2fTest, SpecialNumbers) {
LIBC_NAMESPACE::libc_errno = 0;

// TODO: Strengthen errno,exception checks and remove these assert macros
// after new matchers/test fixtures are added see:
// https://github.com/llvm/llvm-project/issues/90653.
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2f(aNaN, zero));
EXPECT_FP_EXCEPTION(0);
// TODO: Uncomment these checks later, RoundingMode affects running
// tests in this way https://github.com/llvm/llvm-project/issues/90653.
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2f(1.0f, aNaN));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atan2f(zero, zero));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atan2f(-0.0f, zero));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atan2f(1.0f, inf));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atan2f(-1.0f, inf));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);
}
13 changes: 10 additions & 3 deletions libc/test/src/math/smoke/atanf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,25 @@ using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcAtanfTest, SpecialNumbers) {
LIBC_NAMESPACE::libc_errno = 0;

// TODO: Strengthen errno,exception checks and remove these assert macros
// after new matchers/test fixtures are added
// https://github.com/llvm/llvm-project/issues/90653
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanf(aNaN));
EXPECT_FP_EXCEPTION(0);
// TODO: Uncomment these checks later, RoundingMode affects running
// tests in this way https://github.com/llvm/llvm-project/issues/90653.
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanf(0.0f));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanf(-0.0f));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);
}
14 changes: 10 additions & 4 deletions libc/test/src/math/smoke/atanhf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,28 @@
using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;

TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {

LIBC_NAMESPACE::libc_errno = 0;

// TODO: Strengthen errno,exception checks and remove these assert macros
// after new matchers/test fixtures are added, see:
// https://github.com/llvm/llvm-project/issues/90653
LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN));
EXPECT_FP_EXCEPTION(0);
// TODO: Uncomment these checks later, RoundingMode affects running
// tests in this way https://github.com/llvm/llvm-project/issues/90653.
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanhf(0.0f));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanhf(-0.0f));
EXPECT_FP_EXCEPTION(0);
// See above TODO
// EXPECT_FP_EXCEPTION(0);
EXPECT_MATH_ERRNO(0);

EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::atanhf(1.0f), FE_DIVBYZERO);
Expand Down
Loading