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

Michael Flanders via libc-commits libc-commits at lists.llvm.org
Tue Apr 16 08:34:14 PDT 2024


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

>From ffa982c6fe71fed9073c94bd9ca295abe3ddf3b4 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/3] adds more FPMatchers for checking errno and exceptions

update tests that break after FPMatcher changes
---
 libc/test/UnitTest/FPMatcher.h                | 119 +++++++++++++++---
 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, 184 insertions(+), 168 deletions(-)

diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index a76e0b8ef6f6f0..aab10d8a540c21 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)                            \
@@ -219,4 +268,38 @@ template <typename T> struct FPTest : public Test {
     }                                                                          \
   } while (0)
 
+#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)
+
+// Instantiations of the above macros to specific cases
+
+#define ASSERT_FP_EQ_WITH_UNDERFLOW(expected_val, actual_val)                  \
+  ASSERT_FP_EQ_WITH_EXCEPTION(expected_val, actual_val,                        \
+                              FE_INEXACT | FE_UNDERFLOW)
+
+#define ASSERT_FP_EQ_WITH_OVERFLOW(expected_val, actual_val)                   \
+  ASSERT_FP_EQ_WITH_EXCEPTION(expected_val, actual_val,                        \
+                              FE_INEXACT | FE_OVERFLOW)
+
+#define ASSERT_FP_EQ_WITH_INEXACT(expected_val, actual_val)                    \
+  ASSERT_FP_EQ_WITH_EXCEPTION(expected_val, actual_val, FE_INEXACT)
+
 #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 d9c50c8109d803..37edceffd8182c 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -17,17 +17,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::Test {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
@@ -60,139 +49,127 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
 
     // '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 863cf75f05ff6b..a738a3f7eb314a 100644
--- a/libc/test/src/math/smoke/RoundToIntegerTest.h
+++ b/libc/test/src/math/smoke/RoundToIntegerTest.h
@@ -26,14 +26,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
   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();
@@ -53,9 +46,6 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
     if (expectError) {
       ASSERT_FP_EXCEPTION(FE_INVALID);
       ASSERT_MATH_ERRNO(EDOM);
-    } else {
-      ASSERT_FP_EXCEPTION(0);
-      ASSERT_MATH_ERRNO(0);
     }
   }
 
@@ -77,7 +67,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
     // 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 90ea939191d66c79639eaa68ff6bff47aa24de28 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/3] 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 aab10d8a540c21..691cec44b77b40 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -289,6 +289,32 @@ 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)
+
 // Instantiations of the above macros to specific cases
 
 #define ASSERT_FP_EQ_WITH_UNDERFLOW(expected_val, actual_val)                  \
diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h
index 7c93451235f296..9e9d409f8854b1 100644
--- a/libc/test/src/math/RoundToIntegerTest.h
+++ b/libc/test/src/math/RoundToIntegerTest.h
@@ -58,9 +58,6 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
     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 b6c1c8d1797da6..f86d165cb23386 100644
--- a/libc/test/src/math/smoke/NextTowardTest.h
+++ b/libc/test/src/math/smoke/NextTowardTest.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 NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
@@ -66,37 +55,32 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test {
 
     // '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;
 
@@ -105,32 +89,28 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test {
     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;
@@ -138,10 +118,9 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test {
     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 c583c434d67efc63d530f91f0d4a8488ff32e223 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/3] 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);



More information about the libc-commits mailing list