[libc-commits] [libc] [libc][math] adds more FP test macros and fixes bug in `{EXPECT, ASSERT}_FP_EXCEPTION` (PR #88816)

Michael Flanders via libc-commits libc-commits at lists.llvm.org
Tue Apr 30 12:46:26 PDT 2024


https://github.com/Flandini updated https://github.com/llvm/llvm-project/pull/88816

>From 47933acb98f7223db340e779438b93463bcb4613 Mon Sep 17 00:00:00 2001
From: Michael Flanders <flanders.michaelk at gmail.com>
Date: Mon, 15 Apr 2024 16:32:36 -0700
Subject: [PATCH 1/5] adds more FPMatchers for checking errno and exceptions

update tests that break after FPMatcher changes
---
 libc/test/UnitTest/FPMatcher.h                | 106 +++++++++++++++---
 libc/test/src/math/smoke/NextAfterTest.h      |  95 ++++++----------
 libc/test/src/math/smoke/RoundToIntegerTest.h |  14 +--
 libc/test/src/math/smoke/atan2f_test.cpp      |  48 +++-----
 libc/test/src/math/smoke/atanf_test.cpp       |  20 +---
 libc/test/src/math/smoke/atanhf_test.cpp      |  56 ++++-----
 6 files changed, 171 insertions(+), 168 deletions(-)

diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index c58c322c981e43..3d496bcaaf804d 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -159,43 +159,92 @@ 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_NO_ERRNO_EXCEPTION(expected_val, actual_val)              \
+  do {                                                                         \
+    LIBC_NAMESPACE::libc_errno = 0;                                            \
+    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
+    EXPECT_FP_EQ(expected_val, actual_val);                                    \
+    EXPECT_FP_EXCEPTION(0);                                                    \
+    EXPECT_MATH_ERRNO(0);                                                      \
+  } while (0)
+
+#define ASSERT_FP_EQ_NO_ERRNO_EXCEPTION(expected_val, actual_val)              \
+  do {                                                                         \
+    LIBC_NAMESPACE::libc_errno = 0;                                            \
+    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
+    ASSERT_FP_EQ(expected_val, actual_val);                                    \
+    ASSERT_FP_EXCEPTION(0);                                                    \
+    ASSERT_MATH_ERRNO(0);                                                      \
+  } 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 ASSERT_FP_EQ_WITH_EXCEPTION(expected_val, actual_val, expected_except) \
+  do {                                                                         \
+    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
+    ASSERT_FP_EQ(expected_val, actual_val);                                    \
+    ASSERT_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_WITH_ERRNO(expected_val, actual_val, expected_errno)      \
+  do {                                                                         \
+    LIBC_NAMESPACE::libc_errno = 0;                                            \
+    EXPECT_FP_EQ(expected_val, actual_val);                                    \
+    EXPECT_MATH_ERRNO(expected_errno);                                         \
+  } while (0)
+
+#define ASSERT_FP_EQ_WITH_ERRNO(expected_val, actual_val, expected_errno)      \
+  do {                                                                         \
+    LIBC_NAMESPACE::libc_errno = 0;                                            \
+    ASSERT_FP_EQ(expected_val, actual_val);                                    \
+    ASSERT_MATH_ERRNO(expected_errno);                                         \
+  } while (0)
+
+#define EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(expected_val, actual_val,            \
+                                          expected_errno, expected_except)     \
+  do {                                                                         \
+    LIBC_NAMESPACE::libc_errno = 0;                                            \
+    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
+    EXPECT_FP_EQ(expected_val, actual_val);                                    \
+    EXPECT_MATH_ERRNO(expected_errno);                                         \
+    EXPECT_FP_EXCEPTION(expected_except);                                      \
+  } while (0)
+
+#define ASSERT_FP_EQ_WITH_ERRNO_EXCEPTION(expected_val, actual_val,            \
+                                          expected_errno, expected_except)     \
+  do {                                                                         \
+    LIBC_NAMESPACE::libc_errno = 0;                                            \
+    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
+    ASSERT_FP_EQ(expected_val, actual_val);                                    \
+    ASSERT_MATH_ERRNO(expected_errno);                                         \
+    ASSERT_FP_EXCEPTION(expected_except);                                      \
   } while (0)
 
 #define EXPECT_FP_EQ_ALL_ROUNDING(expected, actual)                            \
@@ -240,4 +289,25 @@ template <typename T> struct FPTest : public Test {
 #define EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(expected, actual)                    \
   EXPECT_FP_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::TowardZero)
 
+#define EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(expected, actual)         \
+  do {                                                                         \
+    using namespace LIBC_NAMESPACE::fputil::testing;                           \
+    ForceRoundingMode __r1(RoundingMode::Nearest);                             \
+    if (__r1.success) {                                                        \
+      EXPECT_FP_EQ_NO_ERRNO_EXCEPTION((expected), (actual));                   \
+    }                                                                          \
+    ForceRoundingMode __r2(RoundingMode::Upward);                              \
+    if (__r2.success) {                                                        \
+      EXPECT_FP_EQ_NO_ERRNO_EXCEPTION((expected), (actual));                   \
+    }                                                                          \
+    ForceRoundingMode __r3(RoundingMode::Downward);                            \
+    if (__r3.success) {                                                        \
+      EXPECT_FP_EQ_NO_ERRNO_EXCEPTION((expected), (actual));                   \
+    }                                                                          \
+    ForceRoundingMode __r4(RoundingMode::TowardZero);                          \
+    if (__r4.success) {                                                        \
+      EXPECT_FP_EQ_NO_ERRNO_EXCEPTION((expected), (actual));                   \
+    }                                                                          \
+  } while (0)
+
 #endif // LLVM_LIBC_TEST_UNITTEST_FPMATCHER_H
diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h
index 65dba9338285b6..6b450941f11f62 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -18,17 +18,6 @@
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
 
-#define ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, expected_exception)      \
-  ASSERT_FP_EQ(result, expected);                                              \
-  ASSERT_FP_EXCEPTION(expected_exception);                                     \
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT)
-
-#define ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected)                          \
-  ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_UNDERFLOW)
-
-#define ASSERT_FP_EQ_WITH_OVERFLOW(result, expected)                           \
-  ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_OVERFLOW)
-
 template <typename T>
 class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
@@ -61,139 +50,127 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
     // 'from' is zero|neg_zero.
     T x = zero;
-    T result = func(x, T(1));
     StorageType expected_bits = 1;
     T expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, T(1)));
 
-    result = func(x, T(-1));
     expected_bits = FPBits::SIGN_MASK + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, T(-1)));
 
     x = neg_zero;
-    result = func(x, 1);
     expected_bits = 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 1));
 
-    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, -1));
 
     // 'from' is max subnormal value.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_subnormal);
-    result = func(x, 1);
+    T result = func(x, 1);
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
-    ASSERT_FP_EQ(result, expected);
+    ASSERT_FP_EQ(expected, result);
 
-    result = func(x, 0);
     expected_bits = max_subnormal - 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 0));
 
     x = -x;
 
     result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + min_normal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(result, expected);
+    ASSERT_FP_EQ(expected, result);
 
-    result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_subnormal - 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 0));
 
     // 'from' is min subnormal value.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_subnormal);
-    result = func(x, 1);
     expected_bits = min_subnormal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), 0);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 1));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(0.0, func(x, 0));
 
     x = -x;
-    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + min_subnormal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), T(-0.0));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, -1));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(T(-0.0), func(x, 0));
 
     // 'from' is min normal.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
-    result = func(x, 0);
     expected_bits = max_subnormal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 0));
 
     result = func(x, inf);
     expected_bits = min_normal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(result, expected);
+    ASSERT_FP_EQ(expected, result);
 
     x = -x;
-    result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_subnormal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 0));
 
     result = func(x, -inf);
     expected_bits = FPBits::SIGN_MASK + min_normal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(result, expected);
+    ASSERT_FP_EQ(expected, result);
 
     // 'from' is max normal and 'to' is infinity.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_normal);
-    result = func(x, inf);
-    ASSERT_FP_EQ_WITH_OVERFLOW(result, inf);
-
-    result = func(-x, -inf);
-    ASSERT_FP_EQ_WITH_OVERFLOW(result, -inf);
+    ASSERT_FP_EQ_WITH_OVERFLOW(inf, func(x, inf));
+    ASSERT_FP_EQ_WITH_OVERFLOW(-inf, func(-x, -inf));
 
     // 'from' is infinity.
     x = inf;
     result = func(x, 0);
     expected_bits = max_normal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(result, expected);
-    ASSERT_FP_EQ(func(x, inf), inf);
+    ASSERT_FP_EQ(expected, result);
+    ASSERT_FP_EQ(inf, func(x, inf));
 
     x = neg_inf;
     result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_normal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(result, expected);
-    ASSERT_FP_EQ(func(x, neg_inf), neg_inf);
+    ASSERT_FP_EQ(expected, result);
+    ASSERT_FP_EQ(neg_inf, func(x, neg_inf));
 
     // 'from' is a power of 2.
     x = T(32.0);
     result = func(x, 0);
     FPBits x_bits = FPBits(x);
     FPBits result_bits = FPBits(result);
-    ASSERT_EQ(result_bits.get_biased_exponent(),
-              uint16_t(x_bits.get_biased_exponent() - 1));
-    ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK);
+    ASSERT_EQ(uint16_t(x_bits.get_biased_exponent() - 1),
+              result_bits.get_biased_exponent());
+    ASSERT_EQ(FPBits::FRACTION_MASK, result_bits.get_mantissa());
 
     result = func(x, T(33.0));
     result_bits = FPBits(result);
-    ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent());
-    ASSERT_EQ(result_bits.get_mantissa(),
-              x_bits.get_mantissa() + StorageType(1));
+    ASSERT_EQ(x_bits.get_biased_exponent(), result_bits.get_biased_exponent());
+    ASSERT_EQ(x_bits.get_mantissa() + StorageType(1),
+              result_bits.get_mantissa());
 
     x = -x;
 
     result = func(x, 0);
     result_bits = FPBits(result);
-    ASSERT_EQ(result_bits.get_biased_exponent(),
-              uint16_t(x_bits.get_biased_exponent() - 1));
-    ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK);
+    ASSERT_EQ(uint16_t(x_bits.get_biased_exponent() - 1),
+              result_bits.get_biased_exponent());
+
+    ASSERT_EQ(FPBits::FRACTION_MASK, result_bits.get_mantissa());
 
     result = func(x, T(-33.0));
     result_bits = FPBits(result);
-    ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent());
-    ASSERT_EQ(result_bits.get_mantissa(),
-              x_bits.get_mantissa() + StorageType(1));
+    ASSERT_EQ(x_bits.get_biased_exponent(), result_bits.get_biased_exponent());
+    ASSERT_EQ(x_bits.get_mantissa() + StorageType(1),
+              result_bits.get_mantissa());
   }
 };
 
diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h
index 50bcd4a6a76c0d..578db894118aef 100644
--- a/libc/test/src/math/smoke/RoundToIntegerTest.h
+++ b/libc/test/src/math/smoke/RoundToIntegerTest.h
@@ -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();
@@ -55,9 +48,6 @@ class RoundToIntegerTestTemplate
     if (expectError) {
       ASSERT_FP_EXCEPTION(FE_INVALID);
       ASSERT_MATH_ERRNO(EDOM);
-    } else {
-      ASSERT_FP_EXCEPTION(0);
-      ASSERT_MATH_ERRNO(0);
     }
   }
 
@@ -81,7 +71,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
   }
 
diff --git a/libc/test/src/math/smoke/atan2f_test.cpp b/libc/test/src/math/smoke/atan2f_test.cpp
index f81d140fefc5ea..a5310488c144e1 100644
--- a/libc/test/src/math/smoke/atan2f_test.cpp
+++ b/libc/test/src/math/smoke/atan2f_test.cpp
@@ -16,35 +16,21 @@
 using LlvmLibcAtan2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
 
 TEST_F(LlvmLibcAtan2fTest, SpecialNumbers) {
-  LIBC_NAMESPACE::libc_errno = 0;
-
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
-  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2f(aNaN, zero));
-  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);
-  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);
-  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);
-  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);
-  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);
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
+      aNaN, LIBC_NAMESPACE::atan2f(aNaN, zero));
+
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
+      aNaN, LIBC_NAMESPACE::atan2f(1.0f, aNaN));
+
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
+      0.0f, LIBC_NAMESPACE::atan2f(zero, zero));
+
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
+      -0.0f, LIBC_NAMESPACE::atan2f(-0.0f, zero));
+
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
+      0.0f, LIBC_NAMESPACE::atan2f(1.0f, inf));
+
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
+      -0.0f, LIBC_NAMESPACE::atan2f(-1.0f, inf));
 }
diff --git a/libc/test/src/math/smoke/atanf_test.cpp b/libc/test/src/math/smoke/atanf_test.cpp
index 3800c2334b922a..2ac9f4f41131d2 100644
--- a/libc/test/src/math/smoke/atanf_test.cpp
+++ b/libc/test/src/math/smoke/atanf_test.cpp
@@ -19,20 +19,12 @@
 using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 
 TEST_F(LlvmLibcAtanfTest, SpecialNumbers) {
-  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(aNaN,
+                                               LIBC_NAMESPACE::atanf(aNaN));
 
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
-  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanf(aNaN));
-  EXPECT_FP_EXCEPTION(0);
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(0.0f,
+                                               LIBC_NAMESPACE::atanf(0.0f));
 
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
-  EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanf(0.0f));
-  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);
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(-0.0f,
+                                               LIBC_NAMESPACE::atanf(-0.0f));
 }
diff --git a/libc/test/src/math/smoke/atanhf_test.cpp b/libc/test/src/math/smoke/atanhf_test.cpp
index fc3e2dd9bc54da..fc935643682286 100644
--- a/libc/test/src/math/smoke/atanhf_test.cpp
+++ b/libc/test/src/math/smoke/atanhf_test.cpp
@@ -19,53 +19,41 @@
 using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 
 TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(aNaN,
+                                               LIBC_NAMESPACE::atanhf(aNaN));
 
-  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(0.0f,
+                                               LIBC_NAMESPACE::atanhf(0.0f));
 
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
-  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN));
-  EXPECT_FP_EXCEPTION(0);
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(-0.0f,
+                                               LIBC_NAMESPACE::atanhf(-0.0f));
 
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
-  EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanhf(0.0f));
-  EXPECT_FP_EXCEPTION(0);
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(inf, LIBC_NAMESPACE::atanhf(1.0f), ERANGE,
+                                    FE_DIVBYZERO);
 
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
-  EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanhf(-0.0f));
-  EXPECT_FP_EXCEPTION(0);
-  EXPECT_MATH_ERRNO(0);
-
-  EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::atanhf(1.0f), FE_DIVBYZERO);
-  EXPECT_MATH_ERRNO(ERANGE);
-
-  EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, LIBC_NAMESPACE::atanhf(-1.0f),
-                              FE_DIVBYZERO);
-  EXPECT_MATH_ERRNO(ERANGE);
+  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(neg_inf, LIBC_NAMESPACE::atanhf(-1.0f),
+                                    ERANGE, FE_DIVBYZERO);
 
   auto bt = FPBits(1.0f);
   bt.set_uintval(bt.uintval() + 1);
 
-  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(bt.get_val()),
-                                  FE_INVALID);
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()),
+                                    EDOM, FE_INVALID);
 
   bt.set_sign(Sign::NEG);
-  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(bt.get_val()),
-                                  FE_INVALID);
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()),
+                                    EDOM, FE_INVALID);
 
-  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(2.0f), FE_INVALID);
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(2.0f), EDOM,
+                                    FE_INVALID);
 
-  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(-2.0f), FE_INVALID);
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(-2.0f), EDOM,
+                                    FE_INVALID);
 
-  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(inf), FE_INVALID);
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(inf), EDOM,
+                                    FE_INVALID);
 
   bt.set_sign(Sign::NEG);
-  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(neg_inf), FE_INVALID);
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(neg_inf), EDOM,
+                                    FE_INVALID);
 }

>From 0a523d235ffbf6e9ade545438df8691dc33e1405 Mon Sep 17 00:00:00 2001
From: Michael Flanders <flanders.michaelk at gmail.com>
Date: Tue, 16 Apr 2024 06:38:10 -0700
Subject: [PATCH 2/5] fix buildbot test failure: update non-smoke math tests

---
 libc/test/UnitTest/FPMatcher.h            | 26 ++++++++
 libc/test/src/math/RoundToIntegerTest.h   |  3 -
 libc/test/src/math/atanf_test.cpp         | 19 ++----
 libc/test/src/math/atanhf_test.cpp        | 74 ++++++++---------------
 libc/test/src/math/smoke/NextTowardTest.h | 43 ++++---------
 5 files changed, 69 insertions(+), 96 deletions(-)

diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index 3d496bcaaf804d..7c3f9cd5868469 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -310,4 +310,30 @@ template <typename T> struct FPTest : public Test {
     }                                                                          \
   } while (0)
 
+#define EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(expected, actual,       \
+                                                       errno, exception)       \
+  do {                                                                         \
+    using namespace LIBC_NAMESPACE::fputil::testing;                           \
+    ForceRoundingMode __r1(RoundingMode::Nearest);                             \
+    if (__r1.success) {                                                        \
+      EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION((expected), (actual), (errno),         \
+                                        (exception));                          \
+    }                                                                          \
+    ForceRoundingMode __r2(RoundingMode::Upward);                              \
+    if (__r2.success) {                                                        \
+      EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION((expected), (actual), (errno),         \
+                                        (exception));                          \
+    }                                                                          \
+    ForceRoundingMode __r3(RoundingMode::Downward);                            \
+    if (__r3.success) {                                                        \
+      EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION((expected), (actual), (errno),         \
+                                        (exception));                          \
+    }                                                                          \
+    ForceRoundingMode __r4(RoundingMode::TowardZero);                          \
+    if (__r4.success) {                                                        \
+      EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION((expected), (actual), (errno),         \
+                                        (exception));                          \
+    }                                                                          \
+  } while (0)
+
 #endif // LLVM_LIBC_TEST_UNITTEST_FPMATCHER_H
diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h
index 0f052ba42a46d7..25caf745e8a257 100644
--- a/libc/test/src/math/RoundToIntegerTest.h
+++ b/libc/test/src/math/RoundToIntegerTest.h
@@ -60,9 +60,6 @@ class RoundToIntegerTestTemplate
     if (expectError) {
       ASSERT_FP_EXCEPTION(FE_INVALID);
       ASSERT_MATH_ERRNO(EDOM);
-    } else {
-      ASSERT_FP_EXCEPTION(0);
-      ASSERT_MATH_ERRNO(0);
     }
   }
 
diff --git a/libc/test/src/math/atanf_test.cpp b/libc/test/src/math/atanf_test.cpp
index 4fa7badaf73683..2a94489d352528 100644
--- a/libc/test/src/math/atanf_test.cpp
+++ b/libc/test/src/math/atanf_test.cpp
@@ -22,21 +22,14 @@ using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
 
 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);
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(aNaN,
+                                               LIBC_NAMESPACE::atanf(aNaN));
 
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
-  EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanf(0.0f));
-  EXPECT_FP_EXCEPTION(0);
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(0.0f,
+                                               LIBC_NAMESPACE::atanf(0.0f));
 
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
-  EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanf(-0.0f));
-  EXPECT_FP_EXCEPTION(0);
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(-0.0f,
+                                               LIBC_NAMESPACE::atanf(-0.0f));
 }
 
 TEST_F(LlvmLibcAtanfTest, InFloatRange) {
diff --git a/libc/test/src/math/atanhf_test.cpp b/libc/test/src/math/atanhf_test.cpp
index 7fc8c70d138675..df322e5cd9ebf3 100644
--- a/libc/test/src/math/atanhf_test.cpp
+++ b/libc/test/src/math/atanhf_test.cpp
@@ -23,65 +23,43 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
 
 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);
-  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);
-  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);
-  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);
-  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);
-  EXPECT_MATH_ERRNO(ERANGE);
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(aNaN,
+                                               LIBC_NAMESPACE::atanhf(aNaN));
+
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(0.0f,
+                                               LIBC_NAMESPACE::atanhf(0.0f));
+
+  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(-0.0f,
+                                               LIBC_NAMESPACE::atanhf(-0.0f));
+
+  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
+      inf, LIBC_NAMESPACE::atanhf(1.0f) ERANGE, FE_DIVBYZERO);
+
+  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
+      neg_inf, LIBC_NAMESPACE::atanhf(-1.0f), ERANGE, FE_DIVBYZERO);
 
   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_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
+      aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()), EDOM, FE_INVALID);
 
-  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);
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
+      aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()), EDOM, FE_INVALID);
 
-  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_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
+      aNaN, LIBC_NAMESPACE::atanhf(2.0f), EDOM, FE_INVALID);
 
-  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_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
+      aNaN, LIBC_NAMESPACE::atanhf(-2.0f), EDOM, FE_INVALID);
 
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
-  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(inf));
-  EXPECT_FP_EXCEPTION(FE_INVALID);
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
+      aNaN, LIBC_NAMESPACE::atanhf(inf), EDOM, FE_INVALID);
 
   bt.set_sign(Sign::NEG);
-  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(neg_inf));
-  EXPECT_FP_EXCEPTION(FE_INVALID);
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
+      aNaN, LIBC_NAMESPACE::atanhf(neg_inf), EDOM, FE_INVALID);
 }
 
 TEST_F(LlvmLibcAtanhfTest, InFloatRange) {
diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h
index 1894d324b08546..04839b15009984 100644
--- a/libc/test/src/math/smoke/NextTowardTest.h
+++ b/libc/test/src/math/smoke/NextTowardTest.h
@@ -19,17 +19,6 @@
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
 
-#define ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, expected_exception)      \
-  ASSERT_FP_EQ(result, expected);                                              \
-  ASSERT_FP_EXCEPTION(expected_exception);                                     \
-  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT)
-
-#define ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected)                          \
-  ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_UNDERFLOW)
-
-#define ASSERT_FP_EQ_WITH_OVERFLOW(result, expected)                           \
-  ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_OVERFLOW)
-
 template <typename T>
 class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
@@ -67,37 +56,32 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
     // 'from' is zero|neg_zero.
     T x = zero;
-    T result = func(x, 1);
     StorageType expected_bits = 1;
     T expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 1), expected);
 
-    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, -1), expected);
 
     x = neg_zero;
-    result = func(x, 1);
     expected_bits = 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 1), expected);
 
-    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, -1), expected);
 
     // 'from' is max subnormal value.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_subnormal);
-    result = func(x, 1);
+    T result = func(x, 1);
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
     ASSERT_FP_EQ(result, expected);
 
-    result = func(x, 0);
     expected_bits = max_subnormal - 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), expected);
 
     x = -x;
 
@@ -106,32 +90,28 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
     ASSERT_FP_EQ(result, expected);
 
-    result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_subnormal - 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), expected);
 
     // 'from' is min subnormal value.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_subnormal);
-    result = func(x, 1);
     expected_bits = min_subnormal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 1), expected);
     ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), 0);
 
     x = -x;
-    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + min_subnormal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, -1), expected);
     ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), T(-0.0));
 
     // 'from' is min normal.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
-    result = func(x, 0);
     expected_bits = max_subnormal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), expected);
 
     result = func(x, inf);
     expected_bits = min_normal + 1;
@@ -139,10 +119,9 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     ASSERT_FP_EQ(result, expected);
 
     x = -x;
-    result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_subnormal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), expected);
 
     result = func(x, -inf);
     expected_bits = FPBits::SIGN_MASK + min_normal + 1;

>From 43195ac37cd319ca452f57ad40e48110bc1a926a Mon Sep 17 00:00:00 2001
From: Michael Flanders <flanders.michaelk at gmail.com>
Date: Tue, 16 Apr 2024 08:31:34 -0700
Subject: [PATCH 3/5] missing comma

---
 libc/test/src/math/atanhf_test.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/test/src/math/atanhf_test.cpp b/libc/test/src/math/atanhf_test.cpp
index df322e5cd9ebf3..803af9366c46f2 100644
--- a/libc/test/src/math/atanhf_test.cpp
+++ b/libc/test/src/math/atanhf_test.cpp
@@ -33,7 +33,7 @@ TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {
                                                LIBC_NAMESPACE::atanhf(-0.0f));
 
   EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
-      inf, LIBC_NAMESPACE::atanhf(1.0f) ERANGE, FE_DIVBYZERO);
+      inf, LIBC_NAMESPACE::atanhf(1.0f), ERANGE, FE_DIVBYZERO);
 
   EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
       neg_inf, LIBC_NAMESPACE::atanhf(-1.0f), ERANGE, FE_DIVBYZERO);

>From a486c50e6a5fcfcebdaf431a7ed32f9fc564acd9 Mon Sep 17 00:00:00 2001
From: Michael Flanders <flanders.michaelk at gmail.com>
Date: Tue, 30 Apr 2024 14:20:27 -0500
Subject: [PATCH 4/5] Revert macro adds in FPMatcher.h, comment out problematic
 test lines in atan* tests

Moving towards #89658 style matchers and test fixtures instead of macros
---
 libc/test/UnitTest/FPMatcher.h                | 106 ------------------
 libc/test/src/math/RoundToIntegerTest.h       |   4 +
 libc/test/src/math/atanf_test.cpp             |  27 ++++-
 libc/test/src/math/atanhf_test.cpp            |  78 ++++++++-----
 libc/test/src/math/smoke/NextAfterTest.h      |  97 ++++++++++------
 libc/test/src/math/smoke/NextTowardTest.h     |  45 ++++++--
 libc/test/src/math/smoke/RoundToIntegerTest.h |   4 +
 libc/test/src/math/smoke/atan2f_test.cpp      |  52 ++++++---
 libc/test/src/math/smoke/atanf_test.cpp       |  24 +++-
 libc/test/src/math/smoke/atanhf_test.cpp      |  59 ++++++----
 10 files changed, 266 insertions(+), 230 deletions(-)

diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index 7c3f9cd5868469..26af5cec02b587 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -174,24 +174,6 @@ template <typename T> struct FPTest : public Test {
     }                                                                          \
   } while (0)
 
-#define EXPECT_FP_EQ_NO_ERRNO_EXCEPTION(expected_val, actual_val)              \
-  do {                                                                         \
-    LIBC_NAMESPACE::libc_errno = 0;                                            \
-    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
-    EXPECT_FP_EQ(expected_val, actual_val);                                    \
-    EXPECT_FP_EXCEPTION(0);                                                    \
-    EXPECT_MATH_ERRNO(0);                                                      \
-  } while (0)
-
-#define ASSERT_FP_EQ_NO_ERRNO_EXCEPTION(expected_val, actual_val)              \
-  do {                                                                         \
-    LIBC_NAMESPACE::libc_errno = 0;                                            \
-    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
-    ASSERT_FP_EQ(expected_val, actual_val);                                    \
-    ASSERT_FP_EXCEPTION(0);                                                    \
-    ASSERT_MATH_ERRNO(0);                                                      \
-  } while (0)
-
 #define EXPECT_FP_EQ_WITH_EXCEPTION(expected_val, actual_val, expected_except) \
   do {                                                                         \
     LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
@@ -199,13 +181,6 @@ template <typename T> struct FPTest : public Test {
     EXPECT_FP_EXCEPTION(expected_except);                                      \
   } while (0)
 
-#define ASSERT_FP_EQ_WITH_EXCEPTION(expected_val, actual_val, expected_except) \
-  do {                                                                         \
-    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
-    ASSERT_FP_EQ(expected_val, actual_val);                                    \
-    ASSERT_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);                       \
@@ -213,40 +188,6 @@ template <typename T> struct FPTest : public Test {
     EXPECT_FP_EXCEPTION(expected_except);                                      \
   } while (0)
 
-#define EXPECT_FP_EQ_WITH_ERRNO(expected_val, actual_val, expected_errno)      \
-  do {                                                                         \
-    LIBC_NAMESPACE::libc_errno = 0;                                            \
-    EXPECT_FP_EQ(expected_val, actual_val);                                    \
-    EXPECT_MATH_ERRNO(expected_errno);                                         \
-  } while (0)
-
-#define ASSERT_FP_EQ_WITH_ERRNO(expected_val, actual_val, expected_errno)      \
-  do {                                                                         \
-    LIBC_NAMESPACE::libc_errno = 0;                                            \
-    ASSERT_FP_EQ(expected_val, actual_val);                                    \
-    ASSERT_MATH_ERRNO(expected_errno);                                         \
-  } while (0)
-
-#define EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(expected_val, actual_val,            \
-                                          expected_errno, expected_except)     \
-  do {                                                                         \
-    LIBC_NAMESPACE::libc_errno = 0;                                            \
-    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
-    EXPECT_FP_EQ(expected_val, actual_val);                                    \
-    EXPECT_MATH_ERRNO(expected_errno);                                         \
-    EXPECT_FP_EXCEPTION(expected_except);                                      \
-  } while (0)
-
-#define ASSERT_FP_EQ_WITH_ERRNO_EXCEPTION(expected_val, actual_val,            \
-                                          expected_errno, expected_except)     \
-  do {                                                                         \
-    LIBC_NAMESPACE::libc_errno = 0;                                            \
-    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
-    ASSERT_FP_EQ(expected_val, actual_val);                                    \
-    ASSERT_MATH_ERRNO(expected_errno);                                         \
-    ASSERT_FP_EXCEPTION(expected_except);                                      \
-  } while (0)
-
 #define EXPECT_FP_EQ_ALL_ROUNDING(expected, actual)                            \
   do {                                                                         \
     using namespace LIBC_NAMESPACE::fputil::testing;                           \
@@ -289,51 +230,4 @@ template <typename T> struct FPTest : public Test {
 #define EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(expected, actual)                    \
   EXPECT_FP_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::TowardZero)
 
-#define EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(expected, actual)         \
-  do {                                                                         \
-    using namespace LIBC_NAMESPACE::fputil::testing;                           \
-    ForceRoundingMode __r1(RoundingMode::Nearest);                             \
-    if (__r1.success) {                                                        \
-      EXPECT_FP_EQ_NO_ERRNO_EXCEPTION((expected), (actual));                   \
-    }                                                                          \
-    ForceRoundingMode __r2(RoundingMode::Upward);                              \
-    if (__r2.success) {                                                        \
-      EXPECT_FP_EQ_NO_ERRNO_EXCEPTION((expected), (actual));                   \
-    }                                                                          \
-    ForceRoundingMode __r3(RoundingMode::Downward);                            \
-    if (__r3.success) {                                                        \
-      EXPECT_FP_EQ_NO_ERRNO_EXCEPTION((expected), (actual));                   \
-    }                                                                          \
-    ForceRoundingMode __r4(RoundingMode::TowardZero);                          \
-    if (__r4.success) {                                                        \
-      EXPECT_FP_EQ_NO_ERRNO_EXCEPTION((expected), (actual));                   \
-    }                                                                          \
-  } while (0)
-
-#define EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(expected, actual,       \
-                                                       errno, exception)       \
-  do {                                                                         \
-    using namespace LIBC_NAMESPACE::fputil::testing;                           \
-    ForceRoundingMode __r1(RoundingMode::Nearest);                             \
-    if (__r1.success) {                                                        \
-      EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION((expected), (actual), (errno),         \
-                                        (exception));                          \
-    }                                                                          \
-    ForceRoundingMode __r2(RoundingMode::Upward);                              \
-    if (__r2.success) {                                                        \
-      EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION((expected), (actual), (errno),         \
-                                        (exception));                          \
-    }                                                                          \
-    ForceRoundingMode __r3(RoundingMode::Downward);                            \
-    if (__r3.success) {                                                        \
-      EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION((expected), (actual), (errno),         \
-                                        (exception));                          \
-    }                                                                          \
-    ForceRoundingMode __r4(RoundingMode::TowardZero);                          \
-    if (__r4.success) {                                                        \
-      EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION((expected), (actual), (errno),         \
-                                        (exception));                          \
-    }                                                                          \
-  } while (0)
-
 #endif // LLVM_LIBC_TEST_UNITTEST_FPMATCHER_H
diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h
index 25caf745e8a257..d40e15080087c0 100644
--- a/libc/test/src/math/RoundToIntegerTest.h
+++ b/libc/test/src/math/RoundToIntegerTest.h
@@ -57,6 +57,10 @@ 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);
diff --git a/libc/test/src/math/atanf_test.cpp b/libc/test/src/math/atanf_test.cpp
index 2a94489d352528..fd051655a03364 100644
--- a/libc/test/src/math/atanf_test.cpp
+++ b/libc/test/src/math/atanf_test.cpp
@@ -21,15 +21,30 @@ 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) {
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(aNaN,
-                                               LIBC_NAMESPACE::atanf(aNaN));
+  LIBC_NAMESPACE::libc_errno = 0;
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanf(aNaN));
+  // TODO: Uncomment these checks later, RoundingMode affects running
+  // tests in this way.
+  // EXPECT_FP_EXCEPTION(0);
+  EXPECT_MATH_ERRNO(0);
 
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(0.0f,
-                                               LIBC_NAMESPACE::atanf(0.0f));
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanf(0.0f));
+  // TODO: Uncomment these checks later, RoundingMode affects running
+  // tests in this way.
+  // EXPECT_FP_EXCEPTION(0);
+  EXPECT_MATH_ERRNO(0);
 
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(-0.0f,
-                                               LIBC_NAMESPACE::atanf(-0.0f));
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanf(-0.0f));
+  // TODO: Uncomment these checks later, RoundingMode affects running
+  // tests in this way.
+  // EXPECT_FP_EXCEPTION(0);
+  EXPECT_MATH_ERRNO(0);
 }
 
 TEST_F(LlvmLibcAtanfTest, InFloatRange) {
diff --git a/libc/test/src/math/atanhf_test.cpp b/libc/test/src/math/atanhf_test.cpp
index 803af9366c46f2..4ca3f19823e7b8 100644
--- a/libc/test/src/math/atanhf_test.cpp
+++ b/libc/test/src/math/atanhf_test.cpp
@@ -21,45 +21,71 @@ 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
 TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {
 
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(aNaN,
-                                               LIBC_NAMESPACE::atanhf(aNaN));
-
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(0.0f,
-                                               LIBC_NAMESPACE::atanhf(0.0f));
-
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(-0.0f,
-                                               LIBC_NAMESPACE::atanhf(-0.0f));
-
-  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
-      inf, LIBC_NAMESPACE::atanhf(1.0f), ERANGE, FE_DIVBYZERO);
-
-  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
-      neg_inf, LIBC_NAMESPACE::atanhf(-1.0f), ERANGE, FE_DIVBYZERO);
+  LIBC_NAMESPACE::libc_errno = 0;
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN));
+  // TODO: Uncomment these checks later, RoundingMode affects running
+  // tests in this way.
+  // 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);
+  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);
+  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);
+  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);
+  EXPECT_MATH_ERRNO(ERANGE);
 
   auto bt = FPBits(1.0f);
   bt.set_uintval(bt.uintval() + 1);
 
-  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
-      aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()), EDOM, FE_INVALID);
+  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_MATH_ERRNO(EDOM);
 
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
   bt.set_sign(Sign::NEG);
-  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
-      aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()), EDOM, FE_INVALID);
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()));
+  // EXPECT_FP_EXCEPTION(FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
 
-  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
-      aNaN, LIBC_NAMESPACE::atanhf(2.0f), EDOM, FE_INVALID);
+  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_MATH_ERRNO(EDOM);
 
-  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
-      aNaN, LIBC_NAMESPACE::atanhf(-2.0f), EDOM, FE_INVALID);
+  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_MATH_ERRNO(EDOM);
 
-  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
-      aNaN, LIBC_NAMESPACE::atanhf(inf), EDOM, FE_INVALID);
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(inf));
+  // EXPECT_FP_EXCEPTION(FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
 
   bt.set_sign(Sign::NEG);
-  EXPECT_FP_EQ_ALL_ROUNDING_WITH_ERRNO_EXCEPTION(
-      aNaN, LIBC_NAMESPACE::atanhf(neg_inf), EDOM, FE_INVALID);
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(neg_inf));
+  // EXPECT_FP_EXCEPTION(FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
 }
 
 TEST_F(LlvmLibcAtanhfTest, InFloatRange) {
diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h
index 6b450941f11f62..d65ccdf8e70c3a 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -18,6 +18,19 @@
 #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);                                     \
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT)
+
+#define ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected)                          \
+  ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_UNDERFLOW)
+
+#define ASSERT_FP_EQ_WITH_OVERFLOW(result, expected)                           \
+  ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_OVERFLOW)
+
 template <typename T>
 class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
@@ -50,127 +63,139 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
     // 'from' is zero|neg_zero.
     T x = zero;
+    T result = func(x, T(1));
     StorageType expected_bits = 1;
     T expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, T(1)));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
+    result = func(x, T(-1));
     expected_bits = FPBits::SIGN_MASK + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, T(-1)));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     x = neg_zero;
+    result = func(x, 1);
     expected_bits = 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 1));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
+    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, -1));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     // 'from' is max subnormal value.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_subnormal);
-    T result = func(x, 1);
+    result = func(x, 1);
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
-    ASSERT_FP_EQ(expected, result);
+    ASSERT_FP_EQ(result, expected);
 
+    result = func(x, 0);
     expected_bits = max_subnormal - 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 0));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     x = -x;
 
     result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + min_normal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(expected, result);
+    ASSERT_FP_EQ(result, expected);
 
+    result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_subnormal - 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 0));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     // 'from' is min subnormal value.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_subnormal);
+    result = func(x, 1);
     expected_bits = min_subnormal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 1));
-    ASSERT_FP_EQ_WITH_UNDERFLOW(0.0, func(x, 0));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), 0);
 
     x = -x;
+    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + min_subnormal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, -1));
-    ASSERT_FP_EQ_WITH_UNDERFLOW(T(-0.0), func(x, 0));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), T(-0.0));
 
     // 'from' is min normal.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
+    result = func(x, 0);
     expected_bits = max_subnormal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 0));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     result = func(x, inf);
     expected_bits = min_normal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(expected, result);
+    ASSERT_FP_EQ(result, expected);
 
     x = -x;
+    result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_subnormal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(expected, func(x, 0));
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     result = func(x, -inf);
     expected_bits = FPBits::SIGN_MASK + min_normal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(expected, result);
+    ASSERT_FP_EQ(result, expected);
 
     // 'from' is max normal and 'to' is infinity.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_normal);
-    ASSERT_FP_EQ_WITH_OVERFLOW(inf, func(x, inf));
-    ASSERT_FP_EQ_WITH_OVERFLOW(-inf, func(-x, -inf));
+    result = func(x, inf);
+    ASSERT_FP_EQ_WITH_OVERFLOW(result, inf);
+
+    result = func(-x, -inf);
+    ASSERT_FP_EQ_WITH_OVERFLOW(result, -inf);
 
     // 'from' is infinity.
     x = inf;
     result = func(x, 0);
     expected_bits = max_normal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(expected, result);
-    ASSERT_FP_EQ(inf, func(x, inf));
+    ASSERT_FP_EQ(result, expected);
+    ASSERT_FP_EQ(func(x, inf), inf);
 
     x = neg_inf;
     result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_normal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ(expected, result);
-    ASSERT_FP_EQ(neg_inf, func(x, neg_inf));
+    ASSERT_FP_EQ(result, expected);
+    ASSERT_FP_EQ(func(x, neg_inf), neg_inf);
 
     // 'from' is a power of 2.
     x = T(32.0);
     result = func(x, 0);
     FPBits x_bits = FPBits(x);
     FPBits result_bits = FPBits(result);
-    ASSERT_EQ(uint16_t(x_bits.get_biased_exponent() - 1),
-              result_bits.get_biased_exponent());
-    ASSERT_EQ(FPBits::FRACTION_MASK, result_bits.get_mantissa());
+    ASSERT_EQ(result_bits.get_biased_exponent(),
+              uint16_t(x_bits.get_biased_exponent() - 1));
+    ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK);
 
     result = func(x, T(33.0));
     result_bits = FPBits(result);
-    ASSERT_EQ(x_bits.get_biased_exponent(), result_bits.get_biased_exponent());
-    ASSERT_EQ(x_bits.get_mantissa() + StorageType(1),
-              result_bits.get_mantissa());
+    ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent());
+    ASSERT_EQ(result_bits.get_mantissa(),
+              x_bits.get_mantissa() + StorageType(1));
 
     x = -x;
 
     result = func(x, 0);
     result_bits = FPBits(result);
-    ASSERT_EQ(uint16_t(x_bits.get_biased_exponent() - 1),
-              result_bits.get_biased_exponent());
-
-    ASSERT_EQ(FPBits::FRACTION_MASK, result_bits.get_mantissa());
+    ASSERT_EQ(result_bits.get_biased_exponent(),
+              uint16_t(x_bits.get_biased_exponent() - 1));
+    ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK);
 
     result = func(x, T(-33.0));
     result_bits = FPBits(result);
-    ASSERT_EQ(x_bits.get_biased_exponent(), result_bits.get_biased_exponent());
-    ASSERT_EQ(x_bits.get_mantissa() + StorageType(1),
-              result_bits.get_mantissa());
+    ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent());
+    ASSERT_EQ(result_bits.get_mantissa(),
+              x_bits.get_mantissa() + StorageType(1));
   }
 };
 
diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h
index 04839b15009984..a24ec9ff6bd816 100644
--- a/libc/test/src/math/smoke/NextTowardTest.h
+++ b/libc/test/src/math/smoke/NextTowardTest.h
@@ -19,6 +19,19 @@
 #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);                                     \
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT)
+
+#define ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected)                          \
+  ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_UNDERFLOW)
+
+#define ASSERT_FP_EQ_WITH_OVERFLOW(result, expected)                           \
+  ASSERT_FP_EQ_WITH_EXCEPTION(result, expected, FE_INEXACT | FE_OVERFLOW)
+
 template <typename T>
 class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
@@ -56,32 +69,37 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
     // 'from' is zero|neg_zero.
     T x = zero;
+    T result = func(x, 1);
     StorageType expected_bits = 1;
     T expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 1), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
+    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, -1), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     x = neg_zero;
+    result = func(x, 1);
     expected_bits = 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 1), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
+    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, -1), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     // 'from' is max subnormal value.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_subnormal);
-    T result = func(x, 1);
+    result = func(x, 1);
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
     ASSERT_FP_EQ(result, expected);
 
+    result = func(x, 0);
     expected_bits = max_subnormal - 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     x = -x;
 
@@ -90,28 +108,32 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
     ASSERT_FP_EQ(result, expected);
 
+    result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_subnormal - 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     // 'from' is min subnormal value.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_subnormal);
+    result = func(x, 1);
     expected_bits = min_subnormal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 1), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
     ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), 0);
 
     x = -x;
+    result = func(x, -1);
     expected_bits = FPBits::SIGN_MASK + min_subnormal + 1;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, -1), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
     ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), T(-0.0));
 
     // 'from' is min normal.
     x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
+    result = func(x, 0);
     expected_bits = max_subnormal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     result = func(x, inf);
     expected_bits = min_normal + 1;
@@ -119,9 +141,10 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     ASSERT_FP_EQ(result, expected);
 
     x = -x;
+    result = func(x, 0);
     expected_bits = FPBits::SIGN_MASK + max_subnormal;
     expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
-    ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), expected);
+    ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
 
     result = func(x, -inf);
     expected_bits = FPBits::SIGN_MASK + min_normal + 1;
diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h
index 578db894118aef..3ff311f46b056c 100644
--- a/libc/test/src/math/smoke/RoundToIntegerTest.h
+++ b/libc/test/src/math/smoke/RoundToIntegerTest.h
@@ -45,6 +45,10 @@ 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);
diff --git a/libc/test/src/math/smoke/atan2f_test.cpp b/libc/test/src/math/smoke/atan2f_test.cpp
index a5310488c144e1..553526511ccfa6 100644
--- a/libc/test/src/math/smoke/atan2f_test.cpp
+++ b/libc/test/src/math/smoke/atan2f_test.cpp
@@ -16,21 +16,39 @@
 using LlvmLibcAtan2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
 
 TEST_F(LlvmLibcAtan2fTest, SpecialNumbers) {
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
-      aNaN, LIBC_NAMESPACE::atan2f(aNaN, zero));
-
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
-      aNaN, LIBC_NAMESPACE::atan2f(1.0f, aNaN));
-
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
-      0.0f, LIBC_NAMESPACE::atan2f(zero, zero));
-
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
-      -0.0f, LIBC_NAMESPACE::atan2f(-0.0f, zero));
-
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
-      0.0f, LIBC_NAMESPACE::atan2f(1.0f, inf));
-
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(
-      -0.0f, LIBC_NAMESPACE::atan2f(-1.0f, inf));
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  // TODO: Strengthen errno,exception checks and remove these assert macros
+  // after new matchers/test fixtures are added
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2f(aNaN, zero));
+  // TODO: Uncomment these checks later, RoundingMode affects running
+  // tests in this way.
+  // 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);
+  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);
+  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);
+  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);
+  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);
+  EXPECT_MATH_ERRNO(0);
 }
diff --git a/libc/test/src/math/smoke/atanf_test.cpp b/libc/test/src/math/smoke/atanf_test.cpp
index 2ac9f4f41131d2..4d8dcfcadfd274 100644
--- a/libc/test/src/math/smoke/atanf_test.cpp
+++ b/libc/test/src/math/smoke/atanf_test.cpp
@@ -19,12 +19,24 @@
 using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 
 TEST_F(LlvmLibcAtanfTest, SpecialNumbers) {
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(aNaN,
-                                               LIBC_NAMESPACE::atanf(aNaN));
+  LIBC_NAMESPACE::libc_errno = 0;
 
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(0.0f,
-                                               LIBC_NAMESPACE::atanf(0.0f));
+  // TODO: Strengthen errno,exception checks and remove these assert macros
+  // after new matchers/test fixtures are added
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanf(aNaN));
+  // TODO: Uncomment these checks later, RoundingMode affects running
+  // tests in this way.
+  // EXPECT_FP_EXCEPTION(0);
+  EXPECT_MATH_ERRNO(0);
 
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(-0.0f,
-                                               LIBC_NAMESPACE::atanf(-0.0f));
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanf(0.0f));
+  // 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);
+  EXPECT_MATH_ERRNO(0);
 }
diff --git a/libc/test/src/math/smoke/atanhf_test.cpp b/libc/test/src/math/smoke/atanhf_test.cpp
index fc935643682286..2220c7beecc976 100644
--- a/libc/test/src/math/smoke/atanhf_test.cpp
+++ b/libc/test/src/math/smoke/atanhf_test.cpp
@@ -19,41 +19,56 @@
 using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 
 TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(aNaN,
-                                               LIBC_NAMESPACE::atanhf(aNaN));
+  LIBC_NAMESPACE::libc_errno = 0;
 
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(0.0f,
-                                               LIBC_NAMESPACE::atanhf(0.0f));
+  // TODO: Strengthen errno,exception checks and remove these assert macros
+  // after new matchers/test fixtures are added
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN));
+  // TODO: Uncomment these checks later, RoundingMode affects running
+  // tests in this way.
+  // EXPECT_FP_EXCEPTION(0); 
+  EXPECT_MATH_ERRNO(0);
 
-  EXPECT_FP_EQ_ALL_ROUNDING_NO_ERRNO_EXCEPTION(-0.0f,
-                                               LIBC_NAMESPACE::atanhf(-0.0f));
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanhf(0.0f));
+  // EXPECT_FP_EXCEPTION(0);
+  EXPECT_MATH_ERRNO(0);
 
-  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(inf, LIBC_NAMESPACE::atanhf(1.0f), ERANGE,
-                                    FE_DIVBYZERO);
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanhf(-0.0f));
+  // EXPECT_FP_EXCEPTION(0);
+  EXPECT_MATH_ERRNO(0);
 
-  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(neg_inf, LIBC_NAMESPACE::atanhf(-1.0f),
-                                    ERANGE, FE_DIVBYZERO);
+  EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::atanhf(1.0f), FE_DIVBYZERO);
+  EXPECT_MATH_ERRNO(ERANGE);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, LIBC_NAMESPACE::atanhf(-1.0f),
+                              FE_DIVBYZERO);
+  EXPECT_MATH_ERRNO(ERANGE);
 
   auto bt = FPBits(1.0f);
   bt.set_uintval(bt.uintval() + 1);
 
-  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()),
-                                    EDOM, FE_INVALID);
+  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(bt.get_val()),
+                                  FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
 
   bt.set_sign(Sign::NEG);
-  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()),
-                                    EDOM, FE_INVALID);
+  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(bt.get_val()),
+                                  FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
 
-  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(2.0f), EDOM,
-                                    FE_INVALID);
+  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(2.0f), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
 
-  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(-2.0f), EDOM,
-                                    FE_INVALID);
+  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(-2.0f), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
 
-  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(inf), EDOM,
-                                    FE_INVALID);
+  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(inf), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
 
   bt.set_sign(Sign::NEG);
-  EXPECT_FP_EQ_WITH_ERRNO_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(neg_inf), EDOM,
-                                    FE_INVALID);
+  EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(neg_inf), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
 }

>From 3778fc371d0b65c5bdfb1e4d0949a34c159a399f Mon Sep 17 00:00:00 2001
From: Michael Flanders <flanders.michaelk at gmail.com>
Date: Tue, 30 Apr 2024 14:22:28 -0500
Subject: [PATCH 5/5] formatting

---
 libc/test/src/math/smoke/atanhf_test.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/test/src/math/smoke/atanhf_test.cpp b/libc/test/src/math/smoke/atanhf_test.cpp
index 2220c7beecc976..f832d47b8a2613 100644
--- a/libc/test/src/math/smoke/atanhf_test.cpp
+++ b/libc/test/src/math/smoke/atanhf_test.cpp
@@ -27,7 +27,7 @@ TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {
   EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN));
   // TODO: Uncomment these checks later, RoundingMode affects running
   // tests in this way.
-  // EXPECT_FP_EXCEPTION(0); 
+  // EXPECT_FP_EXCEPTION(0);
   EXPECT_MATH_ERRNO(0);
 
   LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);



More information about the libc-commits mailing list