[libc-commits] [libc] [libc][test] adds errno clearer test fixture, gtest-style errno and fp except assertions (PR #91608)

Michael Flanders via libc-commits libc-commits at lists.llvm.org
Thu May 9 08:58:22 PDT 2024


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

>From b78e0a6ce216d2a0ad94d64e8ea16fa915cb16b1 Mon Sep 17 00:00:00 2001
From: Michael Flanders <flanders.michaelk at gmail.com>
Date: Thu, 2 May 2024 17:08:41 -0500
Subject: [PATCH 1/4] Adds errno fixture and errno, fp exception matchers
 similar to gtest's `EXPECT_THROW`.

---
 libc/test/UnitTest/CMakeLists.txt             |  63 ++++++----
 libc/test/UnitTest/ErrnoSafeTest.h            |  26 +++++
 libc/test/UnitTest/ErrnoSetterMatcher.h       |  34 ++++++
 libc/test/UnitTest/FEnvSafeTest.h             |   2 +-
 libc/test/UnitTest/FPExceptMatcher.cpp        |   3 +-
 libc/test/UnitTest/FPExceptMatcher.h          | 100 +++++++++++++++-
 libc/test/UnitTest/FPMatcher.h                |  87 +++-----------
 libc/test/UnitTest/FPTest.h                   | 109 ++++++++++++++++++
 libc/test/UnitTest/LibcTest.h                 |  15 ++-
 .../__support/FPUtil/dyadic_float_test.cpp    |   2 +-
 libc/test/src/math/CeilTest.h                 |   2 +-
 libc/test/src/math/CopySignTest.h             |   2 +-
 libc/test/src/math/FAbsTest.h                 |   2 +-
 libc/test/src/math/FDimTest.h                 |   2 +-
 libc/test/src/math/FMaxTest.h                 |   2 +-
 libc/test/src/math/FMinTest.h                 |   2 +-
 libc/test/src/math/FModTest.h                 |   2 +-
 libc/test/src/math/FloorTest.h                |   2 +-
 libc/test/src/math/FmaTest.h                  |   2 +-
 libc/test/src/math/FrexpTest.h                |   2 +-
 libc/test/src/math/HypotTest.h                |   2 +-
 libc/test/src/math/LdExpTest.h                |   2 +-
 libc/test/src/math/LogbTest.h                 |   2 +-
 libc/test/src/math/ModfTest.h                 |   2 +-
 libc/test/src/math/NextAfterTest.h            |   2 +-
 libc/test/src/math/RIntTest.h                 |   2 +-
 libc/test/src/math/RemQuoTest.h               |   2 +-
 libc/test/src/math/RoundEvenTest.h            |   2 +-
 libc/test/src/math/RoundTest.h                |   2 +-
 libc/test/src/math/RoundToIntegerTest.h       |   2 +-
 libc/test/src/math/SqrtTest.h                 |   2 +-
 libc/test/src/math/TruncTest.h                |   2 +-
 libc/test/src/math/acosf_test.cpp             |   2 +-
 libc/test/src/math/acoshf_test.cpp            |   2 +-
 libc/test/src/math/asinf_test.cpp             |   2 +-
 libc/test/src/math/asinhf_test.cpp            |   2 +-
 libc/test/src/math/atan2f_test.cpp            |   2 +-
 libc/test/src/math/atanf_test.cpp             |   2 +-
 libc/test/src/math/atanhf_test.cpp            |   2 +-
 libc/test/src/math/cos_test.cpp               |   2 +-
 libc/test/src/math/cosf_test.cpp              |  21 ++--
 libc/test/src/math/coshf_test.cpp             |   2 +-
 libc/test/src/math/erff_test.cpp              |   2 +-
 .../src/math/exhaustive/exhaustive_test.h     |   2 +-
 .../exhaustive/fmod_generic_impl_test.cpp     |   2 +-
 libc/test/src/math/exhaustive/hypotf_test.cpp |   2 +-
 libc/test/src/math/exp10_test.cpp             |   2 +-
 libc/test/src/math/exp10f_test.cpp            |   2 +-
 libc/test/src/math/exp2_test.cpp              |   2 +-
 libc/test/src/math/exp2f_test.cpp             |   2 +-
 libc/test/src/math/exp2m1f_test.cpp           |   2 +-
 libc/test/src/math/exp_test.cpp               |   2 +-
 libc/test/src/math/expf_test.cpp              |   2 +-
 libc/test/src/math/explogxf_test.cpp          |   2 +-
 libc/test/src/math/expm1_test.cpp             |   2 +-
 libc/test/src/math/expm1f_test.cpp            |   2 +-
 libc/test/src/math/fdim_test.cpp              |   2 +-
 libc/test/src/math/fdimf_test.cpp             |   2 +-
 libc/test/src/math/fdiml_test.cpp             |   2 +-
 libc/test/src/math/ilogb_test.cpp             |   2 +-
 libc/test/src/math/ilogbf_test.cpp            |   2 +-
 libc/test/src/math/ilogbl_test.cpp            |   2 +-
 libc/test/src/math/log10_test.cpp             |   2 +-
 libc/test/src/math/log10f_test.cpp            |   2 +-
 libc/test/src/math/log1p_test.cpp             |   2 +-
 libc/test/src/math/log1pf_test.cpp            |   2 +-
 libc/test/src/math/log2_test.cpp              |   2 +-
 libc/test/src/math/log2f_test.cpp             |   2 +-
 libc/test/src/math/log_test.cpp               |   2 +-
 libc/test/src/math/logf_test.cpp              |   2 +-
 libc/test/src/math/powf_test.cpp              |   2 +-
 libc/test/src/math/sin_test.cpp               |   2 +-
 libc/test/src/math/sincosf_test.cpp           |   2 +-
 libc/test/src/math/sinf_test.cpp              |   2 +-
 libc/test/src/math/sinhf_test.cpp             |   2 +-
 libc/test/src/math/smoke/CanonicalizeTest.h   |   2 +-
 libc/test/src/math/smoke/CeilTest.h           |   2 +-
 libc/test/src/math/smoke/CopySignTest.h       |   2 +-
 libc/test/src/math/smoke/FAbsTest.h           |   2 +-
 libc/test/src/math/smoke/FDimTest.h           |   2 +-
 libc/test/src/math/smoke/FMaxTest.h           |   2 +-
 libc/test/src/math/smoke/FMaximumMagNumTest.h |   2 +-
 libc/test/src/math/smoke/FMaximumMagTest.h    |   2 +-
 libc/test/src/math/smoke/FMaximumNumTest.h    |   2 +-
 libc/test/src/math/smoke/FMaximumTest.h       |   2 +-
 libc/test/src/math/smoke/FMinTest.h           |   2 +-
 libc/test/src/math/smoke/FMinimumMagNumTest.h |   2 +-
 libc/test/src/math/smoke/FMinimumMagTest.h    |   2 +-
 libc/test/src/math/smoke/FMinimumNumTest.h    |   2 +-
 libc/test/src/math/smoke/FMinimumTest.h       |   2 +-
 libc/test/src/math/smoke/FModTest.h           |   2 +-
 libc/test/src/math/smoke/FloorTest.h          |   2 +-
 libc/test/src/math/smoke/FmaTest.h            |   2 +-
 libc/test/src/math/smoke/FrexpTest.h          |   2 +-
 libc/test/src/math/smoke/FromfpTest.h         |   2 +-
 libc/test/src/math/smoke/FromfpxTest.h        |   2 +-
 libc/test/src/math/smoke/HypotTest.h          |   2 +-
 libc/test/src/math/smoke/LdExpTest.h          |   2 +-
 libc/test/src/math/smoke/LogbTest.h           |   2 +-
 libc/test/src/math/smoke/ModfTest.h           |   2 +-
 libc/test/src/math/smoke/NearbyIntTest.h      |   2 +-
 libc/test/src/math/smoke/NextAfterTest.h      |   2 +-
 libc/test/src/math/smoke/NextDownTest.h       |   2 +-
 libc/test/src/math/smoke/NextTowardTest.h     |   2 +-
 libc/test/src/math/smoke/NextUpTest.h         |   2 +-
 libc/test/src/math/smoke/RIntTest.h           |   2 +-
 libc/test/src/math/smoke/RemQuoTest.h         |   2 +-
 libc/test/src/math/smoke/RoundEvenTest.h      |   2 +-
 libc/test/src/math/smoke/RoundTest.h          |   2 +-
 libc/test/src/math/smoke/RoundToIntegerTest.h |   2 +-
 libc/test/src/math/smoke/SqrtTest.h           |   2 +-
 libc/test/src/math/smoke/TruncTest.h          |   2 +-
 libc/test/src/math/smoke/UfromfpTest.h        |   2 +-
 libc/test/src/math/smoke/UfromfpxTest.h       |   2 +-
 libc/test/src/math/smoke/acosf_test.cpp       |   2 +-
 libc/test/src/math/smoke/acoshf_test.cpp      |   2 +-
 libc/test/src/math/smoke/asinf_test.cpp       |   2 +-
 libc/test/src/math/smoke/asinhf_test.cpp      |   2 +-
 libc/test/src/math/smoke/atan2f_test.cpp      |   2 +-
 libc/test/src/math/smoke/atanf_test.cpp       |   2 +-
 libc/test/src/math/smoke/atanhf_test.cpp      |   2 +-
 libc/test/src/math/smoke/cosf_test.cpp        |  27 ++---
 libc/test/src/math/smoke/coshf_test.cpp       |   2 +-
 libc/test/src/math/smoke/erff_test.cpp        |   2 +-
 libc/test/src/math/smoke/exp10_test.cpp       |   2 +-
 libc/test/src/math/smoke/exp10f_test.cpp      |   2 +-
 libc/test/src/math/smoke/exp2_test.cpp        |   2 +-
 libc/test/src/math/smoke/exp2f_test.cpp       |   2 +-
 libc/test/src/math/smoke/exp2m1f_test.cpp     |   2 +-
 libc/test/src/math/smoke/exp_test.cpp         |   2 +-
 libc/test/src/math/smoke/expf_test.cpp        |   2 +-
 libc/test/src/math/smoke/expm1_test.cpp       |   2 +-
 libc/test/src/math/smoke/expm1f_test.cpp      |   2 +-
 libc/test/src/math/smoke/log10_test.cpp       |   2 +-
 libc/test/src/math/smoke/log10f_test.cpp      |   2 +-
 libc/test/src/math/smoke/log1p_test.cpp       |   2 +-
 libc/test/src/math/smoke/log1pf_test.cpp      |   2 +-
 libc/test/src/math/smoke/log2_test.cpp        |   2 +-
 libc/test/src/math/smoke/log2f_test.cpp       |   2 +-
 libc/test/src/math/smoke/log_test.cpp         |   2 +-
 libc/test/src/math/smoke/logf_test.cpp        |   2 +-
 libc/test/src/math/smoke/nan_test.cpp         |   2 +-
 libc/test/src/math/smoke/nanf128_test.cpp     |   2 +-
 libc/test/src/math/smoke/nanf_test.cpp        |   2 +-
 libc/test/src/math/smoke/nanl_test.cpp        |   2 +-
 libc/test/src/math/smoke/powf_test.cpp        |   2 +-
 libc/test/src/math/smoke/sincosf_test.cpp     |  23 ++--
 libc/test/src/math/smoke/sinf_test.cpp        |   2 +-
 libc/test/src/math/smoke/sinhf_test.cpp       |   2 +-
 libc/test/src/math/smoke/tanf_test.cpp        |   2 +-
 libc/test/src/math/smoke/tanhf_test.cpp       |   2 +-
 libc/test/src/math/tan_test.cpp               |   2 +-
 libc/test/src/math/tanf_test.cpp              |   2 +-
 libc/test/src/math/tanhf_test.cpp             |   2 +-
 libc/test/src/stdfix/ExpTest.h                |   2 +-
 libc/test/src/stdfix/ISqrtTest.h              |   2 +-
 libc/test/src/stdio/sscanf_test.cpp           |   2 +-
 libc/test/src/stdlib/strtof_test.cpp          |   2 +-
 158 files changed, 508 insertions(+), 294 deletions(-)
 create mode 100644 libc/test/UnitTest/ErrnoSafeTest.h
 create mode 100644 libc/test/UnitTest/FPTest.h

diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt
index 302af3044ca3d..bc7fb88c8ff36 100644
--- a/libc/test/UnitTest/CMakeLists.txt
+++ b/libc/test/UnitTest/CMakeLists.txt
@@ -108,6 +108,40 @@ add_header_library(
     libc.src.__support.CPP.type_traits
 )
 
+add_unittest_framework_library(
+  LibcFPExceptionHelpers
+  SRCS
+    FPExceptMatcher.cpp
+  HDRS
+    FPExceptMatcher.h
+  DEPENDS
+    LibcTest
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fenv_impl
+    libc.hdr.types.fenv_t
+    libc.hdr.fenv_macros
+)
+
+add_header_library(
+  ErrnoSetterMatcher
+  HDRS
+    ErrnoSetterMatcher.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.StringUtil.error_to_string
+    libc.src.errno.errno
+)
+
+add_header_library(
+  ErrnoSafeTest
+  HDRS
+    ErrnoSafeTest.h
+  DEPENDS
+    libc.src.__support.CPP.utility
+    libc.src.errno.errno
+)
+
 add_unittest_framework_library(
   LibcFPTestHelpers
   SRCS
@@ -116,30 +150,22 @@ add_unittest_framework_library(
   HDRS
     FEnvSafeTest.h
     FPMatcher.h
+    FPTest.h
     RoundingModeUtils.h
   DEPENDS
     LibcTest
+    ErrnoSafeTest
+    ErrnoSetterMatcher
+    LibcFPExceptionHelpers
     libc.test.UnitTest.string_utils
     libc.src.__support.CPP.array
+    libc.src.__support.CPP.utility
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.fpbits_str
     libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.rounding_mode
 )
 
-add_unittest_framework_library(
-  LibcFPExceptionHelpers
-  SRCS
-    FPExceptMatcher.cpp
-  HDRS
-    FPExceptMatcher.h
-  DEPENDS
-    LibcTest
-    libc.src.__support.FPUtil.fp_bits
-    libc.src.__support.FPUtil.fenv_impl
-    libc.hdr.types.fenv_t
-)
-
 add_unittest_framework_library(
   LibcMemoryHelpers
   SRCS
@@ -176,14 +202,3 @@ add_unittest_framework_library(
     libc.src.stdio.scanf_core.core_structs
     libc.test.UnitTest.string_utils
 )
-
-add_header_library(
-  ErrnoSetterMatcher
-  HDRS
-    ErrnoSetterMatcher.h
-  DEPENDS
-    libc.src.__support.common
-    libc.src.__support.FPUtil.fp_bits
-    libc.src.__support.StringUtil.error_to_string
-    libc.src.errno.errno
-)
diff --git a/libc/test/UnitTest/ErrnoSafeTest.h b/libc/test/UnitTest/ErrnoSafeTest.h
new file mode 100644
index 0000000000000..bad4ab764ac0b
--- /dev/null
+++ b/libc/test/UnitTest/ErrnoSafeTest.h
@@ -0,0 +1,26 @@
+//===-- ErrnoSafeTestFixture.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TEST_UNITTEST_ERRNOSAFETEST_H
+#define LLVM_LIBC_TEST_UNITTEST_ERRNOSAFETEST_H
+
+#include "src/__support/CPP/utility.h"
+#include "src/errno/libc_errno.h"
+#include "test/UnitTest/Test.h"
+
+namespace LIBC_NAMESPACE::testing {
+
+// This is a test fixture for clearing errno before the start of a test case.
+class ErrnoSafeTest : virtual public Test {
+public:
+  void SetUp() override { LIBC_NAMESPACE::libc_errno = 0; }
+};
+
+} // namespace LIBC_NAMESPACE::testing
+
+#endif // LLVM_LIBC_TEST_UNITTEST_ERRNOSAFETEST_H
diff --git a/libc/test/UnitTest/ErrnoSetterMatcher.h b/libc/test/UnitTest/ErrnoSetterMatcher.h
index 745ba4182023e..a83003cbd137d 100644
--- a/libc/test/UnitTest/ErrnoSetterMatcher.h
+++ b/libc/test/UnitTest/ErrnoSetterMatcher.h
@@ -58,6 +58,9 @@ template <typename T> struct Comparator {
 #endif
 };
 
+// TODO: this should check errno and not always need a return value to
+// also compare against. The FP and non-FP matching is redundant with
+// the other matchers pulled in through Test.h and FPMatcher.h.
 template <typename T> class ErrnoSetterMatcher : public Matcher<T> {
   Comparator<T> return_cmp;
   Comparator<int> errno_cmp;
@@ -184,4 +187,35 @@ static ErrnoSetterMatcherBuilder<RetT> returns(internal::Comparator<RetT> cmp) {
 } // namespace testing
 } // namespace LIBC_NAMESPACE
 
+// Used to check that `LIBC_NAMESPACE::libc_errno` was 0 or a specific
+// errno after executing `expr_or_statement` from a state where
+// `LIBC_NAMESPACE::libc_errno` was 0.
+//
+// Expects `expected` to be convertible to int type.
+//
+// Does not return the value of expr_or_statement, i.e., intended usage
+// is: `EXPECT_ERRNO(EDOM, EXPECT_EQ(..., ...));` or
+// ```
+// EXPECT_ERRNO(EDOM, {
+//   stmt;
+//   ...
+// });
+// ```
+//
+// TODO: this currently uses `ErrnoSetterMatcher` for the nice explanation on
+// failed errno matching. `ErrnoSetterMatcher` requires a return value to also
+// always check, so this code always checks 0 against 0 for the return value--
+// it is not actually checking the value of `expr_or_statement` per above doc
+// comments. When `ErrnoSetterMatcher` is changed to not always check return
+// values, change this also.
+#define EXPECT_ERRNO(expected, expr_or_statement)                              \
+  do {                                                                         \
+    LIBC_NAMESPACE::libc_errno = 0;                                            \
+    expr_or_statement;                                                         \
+    EXPECT_THAT(                                                               \
+        0, LIBC_NAMESPACE::testing::internal::ErrnoSetterMatcher<int>(         \
+               LIBC_NAMESPACE::testing::ErrnoSetterMatcher::EQ(0),             \
+               LIBC_NAMESPACE::testing::ErrnoSetterMatcher::EQ((expected))));  \
+  } while (0)
+
 #endif // LLVM_LIBC_TEST_ERRNOSETTERMATCHER_H
diff --git a/libc/test/UnitTest/FEnvSafeTest.h b/libc/test/UnitTest/FEnvSafeTest.h
index d5a8bb7ee667c..6ac9fcf89ffd2 100644
--- a/libc/test/UnitTest/FEnvSafeTest.h
+++ b/libc/test/UnitTest/FEnvSafeTest.h
@@ -18,7 +18,7 @@ namespace LIBC_NAMESPACE::testing {
 // This provides a test fixture (or base class for other test fixtures) that
 // asserts that each test does not leave the FPU state represented by `fenv_t`
 // (aka `FPState`) perturbed from its initial state.
-class FEnvSafeTest : public Test {
+class FEnvSafeTest : virtual public Test {
 public:
   void TearDown() override;
 
diff --git a/libc/test/UnitTest/FPExceptMatcher.cpp b/libc/test/UnitTest/FPExceptMatcher.cpp
index c1dfc53924662..c10da56e07d92 100644
--- a/libc/test/UnitTest/FPExceptMatcher.cpp
+++ b/libc/test/UnitTest/FPExceptMatcher.cpp
@@ -10,6 +10,7 @@
 
 #include "test/UnitTest/Test.h"
 
+#include "hdr/fenv_macros.h"
 #include "hdr/types/fenv_t.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include <memory>
@@ -35,7 +36,7 @@ static void sigfpeHandler(int sig) {
   siglongjmp(jumpBuffer, -1);
 }
 
-FPExceptMatcher::FPExceptMatcher(FunctionCaller *func) {
+FPExceptCallableMatcher::FPExceptCallableMatcher(FunctionCaller *func) {
   auto oldSIGFPEHandler = signal(SIGFPE, &sigfpeHandler);
   std::unique_ptr<FunctionCaller> funcUP(func);
 
diff --git a/libc/test/UnitTest/FPExceptMatcher.h b/libc/test/UnitTest/FPExceptMatcher.h
index 5136e381081ee..ce635348e904a 100644
--- a/libc/test/UnitTest/FPExceptMatcher.h
+++ b/libc/test/UnitTest/FPExceptMatcher.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_LIBC_TEST_UNITTEST_FPEXCEPTMATCHER_H
 #define LLVM_LIBC_TEST_UNITTEST_FPEXCEPTMATCHER_H
 
+#include "hdr/fenv_macros.h"
 #include "test/UnitTest/Test.h"
 #include "test/UnitTest/TestLogger.h"
 
@@ -17,9 +18,71 @@
 namespace LIBC_NAMESPACE {
 namespace testing {
 
+// Used to compare FP exception flag states with nice error printing
+class FPExceptMatcher : public Matcher<int> {
+  const int expected;
+  int actual;
+
+public:
+  explicit FPExceptMatcher(int expected) : expected(expected) {}
+
+  void explainError() override {
+    tlog << "Expected floating point exceptions: " << expected << ' ';
+    printExcepts(expected);
+    tlog << '\n';
+
+    tlog << "Actual floating point exceptions: " << actual << ' ';
+    printExcepts(actual);
+    tlog << '\n';
+  }
+
+  bool match(int got) {
+    actual = got;
+    return got == expected;
+  }
+
+private:
+  void printExcepts(int excepts) {
+    if (!excepts) {
+      tlog << "(no exceptions)";
+      return;
+    }
+
+    bool firstPrinted = false;
+    auto printWithPipe = [&](const char *name) {
+      if (firstPrinted)
+        tlog << "| ";
+
+      tlog << name;
+
+      firstPrinted = true;
+    };
+
+    tlog << '(';
+
+    if (FE_DIVBYZERO & excepts)
+      printWithPipe("FE_DIVBYZERO");
+
+    if (FE_INEXACT & excepts)
+      printWithPipe("FE_INEXACT");
+
+    if (FE_INVALID & excepts)
+      printWithPipe("FE_INVALID");
+
+    if (FE_OVERFLOW & excepts)
+      printWithPipe("FE_OVERFLOW");
+
+    if (FE_UNDERFLOW & excepts)
+      printWithPipe("FE_UNDERFLOW");
+
+    tlog << ')';
+  }
+};
+
 // TODO: Make the matcher match specific exceptions instead of just identifying
 // that an exception was raised.
-class FPExceptMatcher : public Matcher<bool> {
+// Used in death tests for fenv
+class FPExceptCallableMatcher : public Matcher<bool> {
   bool exceptionRaised;
 
 public:
@@ -40,7 +103,7 @@ class FPExceptMatcher : public Matcher<bool> {
   }
 
   // Takes ownership of func.
-  explicit FPExceptMatcher(FunctionCaller *func);
+  explicit FPExceptCallableMatcher(FunctionCaller *func);
 
   bool match(bool unused) { return exceptionRaised; }
 
@@ -53,11 +116,40 @@ class FPExceptMatcher : public Matcher<bool> {
 } // namespace testing
 } // namespace LIBC_NAMESPACE
 
+// Matches on the FP exception flag `expected` being *equal* to FP exception
+// flag `actual`
+#define EXPECT_FP_EXCEPT_EQUAL(expected, actual)                               \
+  EXPECT_THAT((actual), LIBC_NAMESPACE::testing::FPExceptMatcher((expected)))
+
+#define ASSERT_FP_EXCEPT_EQUAL(expected, actual)                               \
+  ASSERT_THAT((actual), LIBC_NAMESPACE::testing::FPExceptMatcher((expected)))
+
 #define ASSERT_RAISES_FP_EXCEPT(func)                                          \
   ASSERT_THAT(                                                                 \
       true,                                                                    \
-      LIBC_NAMESPACE::testing::FPExceptMatcher(                                \
-          LIBC_NAMESPACE::testing::FPExceptMatcher::getFunctionCaller(func)))
+      LIBC_NAMESPACE::testing::FPExceptCallableMatcher(                        \
+          LIBC_NAMESPACE::testing::FPExceptCallableMatcher::getFunctionCaller( \
+              func)))
+
+// Does not return the value of `expr_or_statement`, i.e., intended usage
+// is: `EXPECT_FP_EXCEPT(FE_INVALID, EXPECT_FP_EQ(..., ...));` or
+// ```
+// EXPECT_FP_EXCEPT(FE_ALL_EXCEPT, {
+//   stmt;
+//   ...
+// });
+// ```
+// Ensures that fp excepts are cleared before executing `expr_or_statement`
+// Checking (expected = 0) should ensure that no exceptions were set
+#define EXPECT_FP_EXCEPT(expected, expr_or_statement)                          \
+  do {                                                                         \
+    LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);                       \
+    expr_or_statement;                                                         \
+    int expected_ = (expected);                                                \
+    int mask_ = expected_ ? expected_ : FE_ALL_EXCEPT;                         \
+    EXPECT_FP_EXCEPT_EQUAL(expected_,                                          \
+                           LIBC_NAMESPACE::fputil::test_except(mask_));        \
+  } while (0)
 
 #else // !LIBC_TEST_HAS_MATCHERS()
 
diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index 26af5cec02b58..8a803a8c4ddcf 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -61,60 +61,9 @@ template <TestCond C, typename T> FPMatcher<T, C> getMatcher(T expectedValue) {
   return FPMatcher<T, C>(expectedValue);
 }
 
-template <typename T> struct FPTest : public Test {
-  using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
-  using StorageType = typename FPBits::StorageType;
-  static constexpr StorageType STORAGE_MAX =
-      LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max();
-  static constexpr T zero = FPBits::zero(Sign::POS).get_val();
-  static constexpr T neg_zero = FPBits::zero(Sign::NEG).get_val();
-  static constexpr T aNaN = FPBits::quiet_nan().get_val();
-  static constexpr T sNaN = FPBits::signaling_nan().get_val();
-  static constexpr T inf = FPBits::inf(Sign::POS).get_val();
-  static constexpr T neg_inf = FPBits::inf(Sign::NEG).get_val();
-  static constexpr T min_normal = FPBits::min_normal().get_val();
-  static constexpr T max_normal = FPBits::max_normal().get_val();
-  static constexpr T min_denormal = FPBits::min_subnormal().get_val();
-  static constexpr T max_denormal = FPBits::max_subnormal().get_val();
-
-  static constexpr int N_ROUNDING_MODES = 4;
-  static constexpr fputil::testing::RoundingMode ROUNDING_MODES[4] = {
-      fputil::testing::RoundingMode::Nearest,
-      fputil::testing::RoundingMode::Upward,
-      fputil::testing::RoundingMode::Downward,
-      fputil::testing::RoundingMode::TowardZero,
-  };
-};
-
 } // namespace testing
 } // namespace LIBC_NAMESPACE
 
-#define DECLARE_SPECIAL_CONSTANTS(T)                                           \
-  using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;                            \
-  using StorageType = typename FPBits::StorageType;                            \
-                                                                               \
-  static constexpr StorageType STORAGE_MAX =                                   \
-      LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max();                 \
-  const T zero = FPBits::zero(Sign::POS).get_val();                            \
-  const T neg_zero = FPBits::zero(Sign::NEG).get_val();                        \
-  const T aNaN = FPBits::quiet_nan().get_val();                                \
-  const T sNaN = FPBits::signaling_nan().get_val();                            \
-  const T inf = FPBits::inf(Sign::POS).get_val();                              \
-  const T neg_inf = FPBits::inf(Sign::NEG).get_val();                          \
-  const T min_normal = FPBits::min_normal().get_val();                         \
-  const T max_normal = FPBits::max_normal(Sign::POS).get_val();                \
-  const T neg_max_normal = FPBits::max_normal(Sign::NEG).get_val();            \
-  const T min_denormal = FPBits::min_subnormal(Sign::POS).get_val();           \
-  const T neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val();       \
-  const T max_denormal = FPBits::max_subnormal().get_val();                    \
-  static constexpr int UNKNOWN_MATH_ROUNDING_DIRECTION = 99;                   \
-  static constexpr LIBC_NAMESPACE::cpp::array<int, 6>                          \
-      MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN = {                           \
-          FP_INT_UPWARD,     FP_INT_DOWNWARD,                                  \
-          FP_INT_TOWARDZERO, FP_INT_TONEARESTFROMZERO,                         \
-          FP_INT_TONEAREST,  UNKNOWN_MATH_ROUNDING_DIRECTION,                  \
-  };
-
 #define EXPECT_FP_EQ(expected, actual)                                         \
   EXPECT_THAT(actual, LIBC_NAMESPACE::testing::getMatcher<                     \
                           LIBC_NAMESPACE::testing::TestCond::EQ>(expected))
@@ -188,36 +137,30 @@ template <typename T> struct FPTest : public Test {
     EXPECT_FP_EXCEPTION(expected_except);                                      \
   } while (0)
 
-#define EXPECT_FP_EQ_ALL_ROUNDING(expected, actual)                            \
+#define FOR_ROUNDING_(rounding_mode, expr_or_statement)                        \
   do {                                                                         \
     using namespace LIBC_NAMESPACE::fputil::testing;                           \
-    ForceRoundingMode __r1(RoundingMode::Nearest);                             \
-    if (__r1.success) {                                                        \
-      EXPECT_FP_EQ((expected), (actual));                                      \
-    }                                                                          \
-    ForceRoundingMode __r2(RoundingMode::Upward);                              \
-    if (__r2.success) {                                                        \
-      EXPECT_FP_EQ((expected), (actual));                                      \
-    }                                                                          \
-    ForceRoundingMode __r3(RoundingMode::Downward);                            \
-    if (__r3.success) {                                                        \
-      EXPECT_FP_EQ((expected), (actual));                                      \
-    }                                                                          \
-    ForceRoundingMode __r4(RoundingMode::TowardZero);                          \
-    if (__r4.success) {                                                        \
-      EXPECT_FP_EQ((expected), (actual));                                      \
+    ForceRoundingMode __r((rounding_mode));                                    \
+    if (__r.success) {                                                         \
+      expr_or_statement;                                                       \
     }                                                                          \
   } while (0)
 
-#define EXPECT_FP_EQ_ROUNDING_MODE(expected, actual, rounding_mode)            \
+#define FOR_ALL_ROUNDING_(expr_or_statement)                                   \
   do {                                                                         \
     using namespace LIBC_NAMESPACE::fputil::testing;                           \
-    ForceRoundingMode __r((rounding_mode));                                    \
-    if (__r.success) {                                                         \
-      EXPECT_FP_EQ((expected), (actual));                                      \
-    }                                                                          \
+    FOR_ROUNDING_(RoundingMode::Nearest, expr_or_statement);                   \
+    FOR_ROUNDING_(RoundingMode::Upward, expr_or_statement);                    \
+    FOR_ROUNDING_(RoundingMode::Downward, expr_or_statement);                  \
+    FOR_ROUNDING_(RoundingMode::TowardZero, expr_or_statement);                \
   } while (0)
 
+#define EXPECT_FP_EQ_ALL_ROUNDING(expected, actual)                            \
+  FOR_ALL_ROUNDING_(EXPECT_FP_EQ((expected), (actual)))
+
+#define EXPECT_FP_EQ_ROUNDING_MODE(expected, actual, rounding_mode)            \
+  FOR_ROUNDING_(rounding_mode, EXPECT_FP_EQ((expected), (actual)))
+
 #define EXPECT_FP_EQ_ROUNDING_NEAREST(expected, actual)                        \
   EXPECT_FP_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::Nearest)
 
diff --git a/libc/test/UnitTest/FPTest.h b/libc/test/UnitTest/FPTest.h
new file mode 100644
index 0000000000000..2176721fac743
--- /dev/null
+++ b/libc/test/UnitTest/FPTest.h
@@ -0,0 +1,109 @@
+//===-- FPTest.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TEST_UNITTEST_FPTEST_H
+#define LLVM_LIBC_TEST_UNITTEST_FPTEST_H
+
+#include "src/__support/CPP/utility.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/ErrnoSafeTest.h" // Test fixture for clearing errno
+#include "test/UnitTest/ErrnoSetterMatcher.h" // Per-assertion clear/check errno
+#include "test/UnitTest/FEnvSafeTest.h" // Test fixture for resetting fenv
+#include "test/UnitTest/FPExceptMatcher.h" // Per-assertion clear/check fp exns
+#include "test/UnitTest/FPMatcher.h" // Matchers/assertions for fp values
+#include "test/UnitTest/Test.h"
+
+#define DECLARE_SPECIAL_CONSTANTS(T)                                           \
+  using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;                            \
+  using StorageType = typename FPBits::StorageType;                            \
+                                                                               \
+  static constexpr StorageType STORAGE_MAX =                                   \
+      LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max();                 \
+  const T zero = FPBits::zero(Sign::POS).get_val();                            \
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();                        \
+  const T aNaN = FPBits::quiet_nan().get_val();                                \
+  const T sNaN = FPBits::signaling_nan().get_val();                            \
+  const T inf = FPBits::inf(Sign::POS).get_val();                              \
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();                          \
+  const T min_normal = FPBits::min_normal().get_val();                         \
+  const T max_normal = FPBits::max_normal(Sign::POS).get_val();                \
+  const T neg_max_normal = FPBits::max_normal(Sign::NEG).get_val();            \
+  const T min_denormal = FPBits::min_subnormal(Sign::POS).get_val();           \
+  const T neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val();       \
+  const T max_denormal = FPBits::max_subnormal().get_val();                    \
+  static constexpr int UNKNOWN_MATH_ROUNDING_DIRECTION = 99;                   \
+  static constexpr LIBC_NAMESPACE::cpp::array<int, 6>                          \
+      MATH_ROUNDING_DIRECTIONS_INCLUDING_UNKNOWN = {                           \
+          FP_INT_UPWARD,     FP_INT_DOWNWARD,                                  \
+          FP_INT_TOWARDZERO, FP_INT_TONEARESTFROMZERO,                         \
+          FP_INT_TONEAREST,  UNKNOWN_MATH_ROUNDING_DIRECTION,                  \
+  };
+
+namespace LIBC_NAMESPACE::testing {
+
+template <typename T>
+struct FPTest : public ErrnoSafeTest, public FEnvSafeTest {
+  using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
+  using StorageType = typename FPBits::StorageType;
+  static constexpr StorageType STORAGE_MAX =
+      LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max();
+  static constexpr T zero = FPBits::zero(Sign::POS).get_val();
+  static constexpr T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  static constexpr T aNaN = FPBits::quiet_nan().get_val();
+  static constexpr T sNaN = FPBits::signaling_nan().get_val();
+  static constexpr T inf = FPBits::inf(Sign::POS).get_val();
+  static constexpr T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  static constexpr T min_normal = FPBits::min_normal().get_val();
+  static constexpr T max_normal = FPBits::max_normal().get_val();
+  static constexpr T min_denormal = FPBits::min_subnormal().get_val();
+  static constexpr T max_denormal = FPBits::max_subnormal().get_val();
+
+  static constexpr int N_ROUNDING_MODES = 4;
+  static constexpr fputil::testing::RoundingMode ROUNDING_MODES[4] = {
+      fputil::testing::RoundingMode::Nearest,
+      fputil::testing::RoundingMode::Upward,
+      fputil::testing::RoundingMode::Downward,
+      fputil::testing::RoundingMode::TowardZero,
+  };
+
+  void TearDown() override { FEnvSafeTest::TearDown(); }
+
+  void SetUp() override { ErrnoSafeTest::SetUp(); }
+};
+
+} // namespace LIBC_NAMESPACE::testing
+
+// Does not return the value of `expr_or_statement`, i.e., intended usage
+// is: `EXPECT_ERRNO_FPEXC(EDOM, FE_INVALID, EXPECT_FP_EQ(..., ...));` or
+// ```
+// EXPECT_ERRNO_FPEXC(EDOM, FE_INVALID, {
+//   stmt;
+//   ...
+// });
+// ```
+// Ensures that fp excepts and errno are cleared before executing
+// `expr_or_statement` Checking (expected_fexn = 0) ensures that no exceptions
+// were set
+#define EXPECT_ERRNO_FP_EXCEPT(expected_errno, expected_fexn,                  \
+                               expr_or_statement)                              \
+  EXPECT_FP_EXCEPT((expected_fexn),                                            \
+                   EXPECT_ERRNO((expected_errno), expr_or_statement))
+
+#define EXPECT_NO_ERRNO_FP_EXCEPT(expr_or_statement)                           \
+  EXPECT_ERRNO_FP_EXCEPT(0, 0, expr_or_statement)
+
+#define EXPECT_ERRNO_FP_EXCEPT_ALL_ROUNDING(expected_errno, expected_fexn,     \
+                                            expr_or_statement)                 \
+  FOR_ALL_ROUNDING_(EXPECT_ERRNO_FP_EXCEPT((expected_errno), (expected_fexn),  \
+                                           expr_or_statement))
+
+#define EXPECT_NO_ERRNO_FP_EXCEPT_ALL_ROUNDING(expr_or_statement)              \
+  FOR_ALL_ROUNDING_(EXPECT_NO_ERRNO_FP_EXCEPT(expr_or_statement))
+
+#endif // LLVM_LIBC_TEST_UNITTEST_FPTEST_H
diff --git a/libc/test/UnitTest/LibcTest.h b/libc/test/UnitTest/LibcTest.h
index bba3c6d743bec..d2372f6d57b3d 100644
--- a/libc/test/UnitTest/LibcTest.h
+++ b/libc/test/UnitTest/LibcTest.h
@@ -192,7 +192,8 @@ class Test {
                          const char *LHSStr, const char *RHSStr,
                          internal::Location Loc);
 
-  template <typename Func> testutils::FunctionCaller *createCallable(Func f) {
+  template <typename Func>
+  testutils::FunctionCaller *createCallable(Func f) {
     struct Callable : public testutils::FunctionCaller {
       Func f;
       Callable(Func f) : f(f) {}
@@ -399,8 +400,9 @@ CString libc_make_test_file_path_func(const char *file_name);
         LIBC_NAMESPACE::testing::internal::Message()
 
 #define LIBC_TEST_BINOP_(COND, LHS, RHS, RET_OR_EMPTY)                         \
-  LIBC_TEST_SCAFFOLDING_(test(LIBC_NAMESPACE::testing::TestCond::COND, LHS,    \
-                              RHS, #LHS, #RHS, LIBC_TEST_LOC_()),              \
+  LIBC_TEST_SCAFFOLDING_(LIBC_NAMESPACE::testing::Test::test(                  \
+                             LIBC_NAMESPACE::testing::TestCond::COND, LHS,     \
+                             RHS, #LHS, #RHS, LIBC_TEST_LOC_()),               \
                          RET_OR_EMPTY)
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -473,9 +475,10 @@ CString libc_make_test_file_path_func(const char *file_name);
 // Custom matcher checks.
 
 #define LIBC_TEST_MATCH_(MATCHER, MATCH, MATCHER_STR, MATCH_STR, RET_OR_EMPTY) \
-  LIBC_TEST_SCAFFOLDING_(matchAndExplain(MATCHER, MATCH, MATCHER_STR,          \
-                                         MATCH_STR, LIBC_TEST_LOC_()),         \
-                         RET_OR_EMPTY)
+  LIBC_TEST_SCAFFOLDING_(                                                      \
+      LIBC_NAMESPACE::testing::Test::matchAndExplain(                          \
+          MATCHER, MATCH, MATCHER_STR, MATCH_STR, LIBC_TEST_LOC_()),           \
+      RET_OR_EMPTY)
 
 #define EXPECT_THAT(MATCH, MATCHER)                                            \
   LIBC_TEST_MATCH_(MATCHER, MATCH, #MATCHER, #MATCH, )
diff --git a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp
index 809381ed47b59..32e2aabdadc9a 100644
--- a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp
+++ b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp
@@ -8,7 +8,7 @@
 
 #include "src/__support/FPUtil/dyadic_float.h"
 #include "src/__support/big_int.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/CeilTest.h b/libc/test/src/math/CeilTest.h
index b4c3752cc5c4b..6f2d883cb00e0 100644
--- a/libc/test/src/math/CeilTest.h
+++ b/libc/test/src/math/CeilTest.h
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/CopySignTest.h b/libc/test/src/math/CopySignTest.h
index c66f91477480b..773b60c482d6b 100644
--- a/libc/test/src/math/CopySignTest.h
+++ b/libc/test/src/math/CopySignTest.h
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/FAbsTest.h b/libc/test/src/math/FAbsTest.h
index 92b589beeb675..bc41782720854 100644
--- a/libc/test/src/math/FAbsTest.h
+++ b/libc/test/src/math/FAbsTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_FABSTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/FDimTest.h b/libc/test/src/math/FDimTest.h
index fefcefe5052a9..6693a0e4d006b 100644
--- a/libc/test/src/math/FDimTest.h
+++ b/libc/test/src/math/FDimTest.h
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/FMaxTest.h b/libc/test/src/math/FMaxTest.h
index 405642c6b9684..12edd8717c382 100644
--- a/libc/test/src/math/FMaxTest.h
+++ b/libc/test/src/math/FMaxTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_FMAXTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/FMinTest.h b/libc/test/src/math/FMinTest.h
index eae0008ddfe39..27a9b17bb7490 100644
--- a/libc/test/src/math/FMinTest.h
+++ b/libc/test/src/math/FMinTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_FMINTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/FModTest.h b/libc/test/src/math/FModTest.h
index 32c009ab88286..5ce31e01b6ee4 100644
--- a/libc/test/src/math/FModTest.h
+++ b/libc/test/src/math/FModTest.h
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/NearestIntegerOperations.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/FloorTest.h b/libc/test/src/math/FloorTest.h
index 9103a5b05eb5a..fe797fc70cb6c 100644
--- a/libc/test/src/math/FloorTest.h
+++ b/libc/test/src/math/FloorTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_FLOORTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h
index 5a40f694ebd10..436cfe93bd511 100644
--- a/libc/test/src/math/FmaTest.h
+++ b/libc/test/src/math/FmaTest.h
@@ -13,7 +13,7 @@
 #include "src/stdlib/rand.h"
 #include "src/stdlib/srand.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/FrexpTest.h b/libc/test/src/math/FrexpTest.h
index 3ba64afa3c620..075abd6e4b29f 100644
--- a/libc/test/src/math/FrexpTest.h
+++ b/libc/test/src/math/FrexpTest.h
@@ -8,7 +8,7 @@
 
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/HypotTest.h b/libc/test/src/math/HypotTest.h
index 58b5338318245..69dbc01e521ae 100644
--- a/libc/test/src/math/HypotTest.h
+++ b/libc/test/src/math/HypotTest.h
@@ -11,7 +11,7 @@
 
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h
index 34466a526d60f..a9743c4691bff 100644
--- a/libc/test/src/math/LdExpTest.h
+++ b/libc/test/src/math/LdExpTest.h
@@ -13,7 +13,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/NormalFloat.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/LogbTest.h b/libc/test/src/math/LogbTest.h
index d6042e3c200c7..83c3463951031 100644
--- a/libc/test/src/math/LogbTest.h
+++ b/libc/test/src/math/LogbTest.h
@@ -8,7 +8,7 @@
 
 #include "src/__support/FPUtil/ManipulationFunctions.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/ModfTest.h b/libc/test/src/math/ModfTest.h
index d6c6f27a5edf6..15a3ebdb386f9 100644
--- a/libc/test/src/math/ModfTest.h
+++ b/libc/test/src/math/ModfTest.h
@@ -9,7 +9,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/NearestIntegerOperations.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/NextAfterTest.h b/libc/test/src/math/NextAfterTest.h
index b3b03f763992a..c8038dd55c3bb 100644
--- a/libc/test/src/math/NextAfterTest.h
+++ b/libc/test/src/math/NextAfterTest.h
@@ -15,7 +15,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h
index 007b50427ba34..b1cfad4c18ceb 100644
--- a/libc/test/src/math/RIntTest.h
+++ b/libc/test/src/math/RIntTest.h
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/RemQuoTest.h b/libc/test/src/math/RemQuoTest.h
index c39f2394555ea..a485e3434baa1 100644
--- a/libc/test/src/math/RemQuoTest.h
+++ b/libc/test/src/math/RemQuoTest.h
@@ -13,7 +13,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/RoundEvenTest.h b/libc/test/src/math/RoundEvenTest.h
index d70555d347659..891c72fe436d1 100644
--- a/libc/test/src/math/RoundEvenTest.h
+++ b/libc/test/src/math/RoundEvenTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_ROUNDEVENTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/RoundTest.h b/libc/test/src/math/RoundTest.h
index 2a31df305ac38..44e3ea21dfa40 100644
--- a/libc/test/src/math/RoundTest.h
+++ b/libc/test/src/math/RoundTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_ROUNDTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h
index d40e15080087c..5cba38b6cb7c7 100644
--- a/libc/test/src/math/RoundToIntegerTest.h
+++ b/libc/test/src/math/RoundToIntegerTest.h
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/SqrtTest.h b/libc/test/src/math/SqrtTest.h
index 1c422e201bb23..0cfa70d57a6ef 100644
--- a/libc/test/src/math/SqrtTest.h
+++ b/libc/test/src/math/SqrtTest.h
@@ -8,7 +8,7 @@
 
 #include "src/__support/CPP/bit.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/TruncTest.h b/libc/test/src/math/TruncTest.h
index bc5b76131291b..cc0fd2065f2b9 100644
--- a/libc/test/src/math/TruncTest.h
+++ b/libc/test/src/math/TruncTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_TRUNCTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/acosf_test.cpp b/libc/test/src/math/acosf_test.cpp
index 0d25a808e0bf3..a7c59709b91ec 100644
--- a/libc/test/src/math/acosf_test.cpp
+++ b/libc/test/src/math/acosf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/acosf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/acoshf_test.cpp b/libc/test/src/math/acoshf_test.cpp
index 32761e25b5ce5..1bb3f1ba7e935 100644
--- a/libc/test/src/math/acoshf_test.cpp
+++ b/libc/test/src/math/acoshf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/acoshf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/asinf_test.cpp b/libc/test/src/math/asinf_test.cpp
index 91e61085e91b8..84e9d2ea50609 100644
--- a/libc/test/src/math/asinf_test.cpp
+++ b/libc/test/src/math/asinf_test.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/asinf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/asinhf_test.cpp b/libc/test/src/math/asinhf_test.cpp
index b19e26efd07bf..0780cafe8cc54 100644
--- a/libc/test/src/math/asinhf_test.cpp
+++ b/libc/test/src/math/asinhf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/asinhf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/atan2f_test.cpp b/libc/test/src/math/atan2f_test.cpp
index 1242b7e66528f..28de5b9cacaa1 100644
--- a/libc/test/src/math/atan2f_test.cpp
+++ b/libc/test/src/math/atan2f_test.cpp
@@ -9,7 +9,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/atan2f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/atanf_test.cpp b/libc/test/src/math/atanf_test.cpp
index 376b4724b5a3a..1474b86f0bf66 100644
--- a/libc/test/src/math/atanf_test.cpp
+++ b/libc/test/src/math/atanf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/atanf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/atanhf_test.cpp b/libc/test/src/math/atanhf_test.cpp
index b0505e4c1182a..3ed8390b3bcf1 100644
--- a/libc/test/src/math/atanhf_test.cpp
+++ b/libc/test/src/math/atanhf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/atanhf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/cos_test.cpp b/libc/test/src/math/cos_test.cpp
index 9a39616ed16f8..58f80b16f7310 100644
--- a/libc/test/src/math/cos_test.cpp
+++ b/libc/test/src/math/cos_test.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/cos.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/cosf_test.cpp b/libc/test/src/math/cosf_test.cpp
index dab35fa1a9fe7..58ba4d870257d 100644
--- a/libc/test/src/math/cosf_test.cpp
+++ b/libc/test/src/math/cosf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/cosf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "test/src/math/sdcomp26094.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
@@ -24,22 +24,17 @@ using LlvmLibcCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
 
 TEST_F(LlvmLibcCosfTest, SpecialNumbers) {
-  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_NO_ERRNO_FP_EXCEPT(EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(aNaN)));
 
-  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(aNaN));
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_NO_ERRNO_FP_EXCEPT(EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::cosf(0.0f)));
 
-  EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::cosf(0.0f));
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_NO_ERRNO_FP_EXCEPT(EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::cosf(-0.0f)));
 
-  EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::cosf(-0.0f));
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_ERRNO_FP_EXCEPT(EDOM, FE_INVALID,
+                         EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(inf)));
 
-  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(inf));
-  EXPECT_MATH_ERRNO(EDOM);
-
-  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(neg_inf));
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_ERRNO_FP_EXCEPT(EDOM, FE_INVALID,
+                         EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(neg_inf)));
 }
 
 TEST_F(LlvmLibcCosfTest, InFloatRange) {
diff --git a/libc/test/src/math/coshf_test.cpp b/libc/test/src/math/coshf_test.cpp
index 7c5d6630e1093..711596fb5c380 100644
--- a/libc/test/src/math/coshf_test.cpp
+++ b/libc/test/src/math/coshf_test.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/coshf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/erff_test.cpp b/libc/test/src/math/erff_test.cpp
index 5c848d7d5bf7d..405e1be395092 100644
--- a/libc/test/src/math/erff_test.cpp
+++ b/libc/test/src/math/erff_test.cpp
@@ -9,7 +9,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/erff.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/exhaustive/exhaustive_test.h b/libc/test/src/math/exhaustive/exhaustive_test.h
index c4ae382688a03..0bbf79c93dd6a 100644
--- a/libc/test/src/math/exhaustive/exhaustive_test.h
+++ b/libc/test/src/math/exhaustive/exhaustive_test.h
@@ -8,7 +8,7 @@
 
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/FPUtil/FPBits.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/exhaustive/fmod_generic_impl_test.cpp b/libc/test/src/math/exhaustive/fmod_generic_impl_test.cpp
index b064b7e37f428..06f5c904ac243 100644
--- a/libc/test/src/math/exhaustive/fmod_generic_impl_test.cpp
+++ b/libc/test/src/math/exhaustive/fmod_generic_impl_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/ManipulationFunctions.h" // ldexp
 #include "src/__support/FPUtil/generic/FMod.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/exhaustive/hypotf_test.cpp b/libc/test/src/math/exhaustive/hypotf_test.cpp
index 04da55d4d3a9f..05b1b305b688a 100644
--- a/libc/test/src/math/exhaustive/hypotf_test.cpp
+++ b/libc/test/src/math/exhaustive/hypotf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/Hypot.h"
 #include "src/math/hypotf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
 namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/libc/test/src/math/exp10_test.cpp b/libc/test/src/math/exp10_test.cpp
index 4cbdd169d8032..01fec31ef075c 100644
--- a/libc/test/src/math/exp10_test.cpp
+++ b/libc/test/src/math/exp10_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/exp10.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/exp10f_test.cpp b/libc/test/src/math/exp10f_test.cpp
index e9b2786681042..602f52f8b8597 100644
--- a/libc/test/src/math/exp10f_test.cpp
+++ b/libc/test/src/math/exp10f_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/exp10f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/exp2_test.cpp b/libc/test/src/math/exp2_test.cpp
index 73232ed36077b..aeeab350e1201 100644
--- a/libc/test/src/math/exp2_test.cpp
+++ b/libc/test/src/math/exp2_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/exp2.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/exp2f_test.cpp b/libc/test/src/math/exp2f_test.cpp
index 8ff0ce6a6e724..10a122fb5399a 100644
--- a/libc/test/src/math/exp2f_test.cpp
+++ b/libc/test/src/math/exp2f_test.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
 #include "src/errno/libc_errno.h"
 #include "src/math/exp2f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/exp2m1f_test.cpp b/libc/test/src/math/exp2m1f_test.cpp
index cb948289b6179..1b5ac8a8a6970 100644
--- a/libc/test/src/math/exp2m1f_test.cpp
+++ b/libc/test/src/math/exp2m1f_test.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/exp2m1f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/exp_test.cpp b/libc/test/src/math/exp_test.cpp
index 64d8198e64f2d..07a2de9f127ac 100644
--- a/libc/test/src/math/exp_test.cpp
+++ b/libc/test/src/math/exp_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/exp.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/expf_test.cpp b/libc/test/src/math/expf_test.cpp
index 1dce381918eb6..e24a830ba87fb 100644
--- a/libc/test/src/math/expf_test.cpp
+++ b/libc/test/src/math/expf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/expf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/explogxf_test.cpp b/libc/test/src/math/explogxf_test.cpp
index bcca87f590d75..918eedccce448 100644
--- a/libc/test/src/math/explogxf_test.cpp
+++ b/libc/test/src/math/explogxf_test.cpp
@@ -12,7 +12,7 @@
 #include "src/math/fabs.h"
 #include "src/math/fabsf.h"
 #include "src/math/generic/explogxf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/expm1_test.cpp b/libc/test/src/math/expm1_test.cpp
index 1bf07f19f3a7c..a0693cf65f8af 100644
--- a/libc/test/src/math/expm1_test.cpp
+++ b/libc/test/src/math/expm1_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/expm1.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/expm1f_test.cpp b/libc/test/src/math/expm1f_test.cpp
index 515f988b62649..292bdd36cfc2e 100644
--- a/libc/test/src/math/expm1f_test.cpp
+++ b/libc/test/src/math/expm1f_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/expm1f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/fdim_test.cpp b/libc/test/src/math/fdim_test.cpp
index 1e8adf036ddea..fafb4906cdfc7 100644
--- a/libc/test/src/math/fdim_test.cpp
+++ b/libc/test/src/math/fdim_test.cpp
@@ -11,7 +11,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/fdim.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 using LlvmLibcFDimTest = FDimTestTemplate<double>;
diff --git a/libc/test/src/math/fdimf_test.cpp b/libc/test/src/math/fdimf_test.cpp
index 13e61d9082da4..a59801e952abf 100644
--- a/libc/test/src/math/fdimf_test.cpp
+++ b/libc/test/src/math/fdimf_test.cpp
@@ -11,7 +11,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/fdimf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 using LlvmLibcFDimTest = FDimTestTemplate<float>;
diff --git a/libc/test/src/math/fdiml_test.cpp b/libc/test/src/math/fdiml_test.cpp
index 2d99d2134c1c0..ce296d509d30c 100644
--- a/libc/test/src/math/fdiml_test.cpp
+++ b/libc/test/src/math/fdiml_test.cpp
@@ -11,7 +11,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/fdiml.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 using LlvmLibcFDimTest = FDimTestTemplate<long double>;
diff --git a/libc/test/src/math/ilogb_test.cpp b/libc/test/src/math/ilogb_test.cpp
index c8daf2e0adafe..2c11efb7cb2a3 100644
--- a/libc/test/src/math/ilogb_test.cpp
+++ b/libc/test/src/math/ilogb_test.cpp
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/ManipulationFunctions.h"
 #include "src/math/ilogb.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogb) {
diff --git a/libc/test/src/math/ilogbf_test.cpp b/libc/test/src/math/ilogbf_test.cpp
index 87a2789f6c110..c1227a438365c 100644
--- a/libc/test/src/math/ilogbf_test.cpp
+++ b/libc/test/src/math/ilogbf_test.cpp
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/ManipulationFunctions.h"
 #include "src/math/ilogbf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogbf) {
diff --git a/libc/test/src/math/ilogbl_test.cpp b/libc/test/src/math/ilogbl_test.cpp
index 042a803b024a7..b021471572196 100644
--- a/libc/test/src/math/ilogbl_test.cpp
+++ b/libc/test/src/math/ilogbl_test.cpp
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/ManipulationFunctions.h"
 #include "src/math/ilogbl.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogbl) {
diff --git a/libc/test/src/math/log10_test.cpp b/libc/test/src/math/log10_test.cpp
index fd9a615ca87f7..90db3bc932508 100644
--- a/libc/test/src/math/log10_test.cpp
+++ b/libc/test/src/math/log10_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log10.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/log10f_test.cpp b/libc/test/src/math/log10f_test.cpp
index 4ba118455df4d..1c99c9408eb70 100644
--- a/libc/test/src/math/log10f_test.cpp
+++ b/libc/test/src/math/log10f_test.cpp
@@ -9,7 +9,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/log10f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/log1p_test.cpp b/libc/test/src/math/log1p_test.cpp
index 47dfa406ec257..7e8e7dfb6eace 100644
--- a/libc/test/src/math/log1p_test.cpp
+++ b/libc/test/src/math/log1p_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log1p.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/log1pf_test.cpp b/libc/test/src/math/log1pf_test.cpp
index db0772d3c8b87..7e854029d3207 100644
--- a/libc/test/src/math/log1pf_test.cpp
+++ b/libc/test/src/math/log1pf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log1pf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/log2_test.cpp b/libc/test/src/math/log2_test.cpp
index 9992c1340e99d..7121cd3d4cf71 100644
--- a/libc/test/src/math/log2_test.cpp
+++ b/libc/test/src/math/log2_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log2.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/log2f_test.cpp b/libc/test/src/math/log2f_test.cpp
index 24b51adac94d1..8b1f1b69e0d12 100644
--- a/libc/test/src/math/log2f_test.cpp
+++ b/libc/test/src/math/log2f_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log2f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/log_test.cpp b/libc/test/src/math/log_test.cpp
index de1e59579419e..7e8a1088e83e5 100644
--- a/libc/test/src/math/log_test.cpp
+++ b/libc/test/src/math/log_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/logf_test.cpp b/libc/test/src/math/logf_test.cpp
index 28a171d540665..659665902bb23 100644
--- a/libc/test/src/math/logf_test.cpp
+++ b/libc/test/src/math/logf_test.cpp
@@ -9,7 +9,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/logf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/powf_test.cpp b/libc/test/src/math/powf_test.cpp
index 69135593cd32c..acd850e493948 100644
--- a/libc/test/src/math/powf_test.cpp
+++ b/libc/test/src/math/powf_test.cpp
@@ -9,7 +9,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/powf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/sin_test.cpp b/libc/test/src/math/sin_test.cpp
index 0171b79810d4e..54f6bcd6cd28d 100644
--- a/libc/test/src/math/sin_test.cpp
+++ b/libc/test/src/math/sin_test.cpp
@@ -8,7 +8,7 @@
 
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/sin.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/sincosf_test.cpp b/libc/test/src/math/sincosf_test.cpp
index 7c359b345f4c3..8c988a7e41517 100644
--- a/libc/test/src/math/sincosf_test.cpp
+++ b/libc/test/src/math/sincosf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/sincosf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "test/src/math/sdcomp26094.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
diff --git a/libc/test/src/math/sinf_test.cpp b/libc/test/src/math/sinf_test.cpp
index 6a8f8f4ee4288..fb7e8730a875d 100644
--- a/libc/test/src/math/sinf_test.cpp
+++ b/libc/test/src/math/sinf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/sinf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "test/src/math/sdcomp26094.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
diff --git a/libc/test/src/math/sinhf_test.cpp b/libc/test/src/math/sinhf_test.cpp
index cc0552f728947..05df910df2b06 100644
--- a/libc/test/src/math/sinhf_test.cpp
+++ b/libc/test/src/math/sinhf_test.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/sinhf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/smoke/CanonicalizeTest.h b/libc/test/src/math/smoke/CanonicalizeTest.h
index 7e2456f84705c..e668fd0b6bfa9 100644
--- a/libc/test/src/math/smoke/CanonicalizeTest.h
+++ b/libc/test/src/math/smoke/CanonicalizeTest.h
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/integer_literals.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/CeilTest.h b/libc/test/src/math/smoke/CeilTest.h
index 5e108c0e0feea..7ae4587fc665d 100644
--- a/libc/test/src/math/smoke/CeilTest.h
+++ b/libc/test/src/math/smoke/CeilTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CEILTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/CopySignTest.h b/libc/test/src/math/smoke/CopySignTest.h
index 1810560bf1bb8..7af9a91de13b5 100644
--- a/libc/test/src/math/smoke/CopySignTest.h
+++ b/libc/test/src/math/smoke/CopySignTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_COPYSIGNTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/FAbsTest.h b/libc/test/src/math/smoke/FAbsTest.h
index 048023b414299..359869a3d0884 100644
--- a/libc/test/src/math/smoke/FAbsTest.h
+++ b/libc/test/src/math/smoke/FAbsTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FABSTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/FDimTest.h b/libc/test/src/math/smoke/FDimTest.h
index cff88f29a8efa..76d0c09953991 100644
--- a/libc/test/src/math/smoke/FDimTest.h
+++ b/libc/test/src/math/smoke/FDimTest.h
@@ -9,7 +9,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMaxTest.h b/libc/test/src/math/smoke/FMaxTest.h
index df8e35e0bd162..51fab4f8ed9c4 100644
--- a/libc/test/src/math/smoke/FMaxTest.h
+++ b/libc/test/src/math/smoke/FMaxTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMaximumMagNumTest.h b/libc/test/src/math/smoke/FMaximumMagNumTest.h
index aafb6d2b0d5ea..78005bda34312 100644
--- a/libc/test/src/math/smoke/FMaximumMagNumTest.h
+++ b/libc/test/src/math/smoke/FMaximumMagNumTest.h
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMaximumMagTest.h b/libc/test/src/math/smoke/FMaximumMagTest.h
index 7bb79a69be580..1587864e2c9b0 100644
--- a/libc/test/src/math/smoke/FMaximumMagTest.h
+++ b/libc/test/src/math/smoke/FMaximumMagTest.h
@@ -11,7 +11,7 @@
 
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMaximumNumTest.h b/libc/test/src/math/smoke/FMaximumNumTest.h
index da0ea2c247a9e..b7de3490bf980 100644
--- a/libc/test/src/math/smoke/FMaximumNumTest.h
+++ b/libc/test/src/math/smoke/FMaximumNumTest.h
@@ -11,7 +11,7 @@
 
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMaximumTest.h b/libc/test/src/math/smoke/FMaximumTest.h
index 1bd15163ed752..e9792cdebf4fc 100644
--- a/libc/test/src/math/smoke/FMaximumTest.h
+++ b/libc/test/src/math/smoke/FMaximumTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMAXIMUMTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMinTest.h b/libc/test/src/math/smoke/FMinTest.h
index f71b558cd3da2..72e942457698d 100644
--- a/libc/test/src/math/smoke/FMinTest.h
+++ b/libc/test/src/math/smoke/FMinTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMinimumMagNumTest.h b/libc/test/src/math/smoke/FMinimumMagNumTest.h
index e4b8fd9e33531..c89c8b7e496f1 100644
--- a/libc/test/src/math/smoke/FMinimumMagNumTest.h
+++ b/libc/test/src/math/smoke/FMinimumMagNumTest.h
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMinimumMagTest.h b/libc/test/src/math/smoke/FMinimumMagTest.h
index 3e16622fe3fa4..febebf2a0fded 100644
--- a/libc/test/src/math/smoke/FMinimumMagTest.h
+++ b/libc/test/src/math/smoke/FMinimumMagTest.h
@@ -11,7 +11,7 @@
 
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMinimumNumTest.h b/libc/test/src/math/smoke/FMinimumNumTest.h
index 6186ea0df17cc..ea7cfe7ab3ee0 100644
--- a/libc/test/src/math/smoke/FMinimumNumTest.h
+++ b/libc/test/src/math/smoke/FMinimumNumTest.h
@@ -11,7 +11,7 @@
 
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FMinimumTest.h b/libc/test/src/math/smoke/FMinimumTest.h
index a267f6c783214..736079d1228a2 100644
--- a/libc/test/src/math/smoke/FMinimumTest.h
+++ b/libc/test/src/math/smoke/FMinimumTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMINIMUMTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FModTest.h b/libc/test/src/math/smoke/FModTest.h
index f1015d6497fcd..4acc07a7222dd 100644
--- a/libc/test/src/math/smoke/FModTest.h
+++ b/libc/test/src/math/smoke/FModTest.h
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/NearestIntegerOperations.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/FloorTest.h b/libc/test/src/math/smoke/FloorTest.h
index b2102459bc3de..986a465e3ee80 100644
--- a/libc/test/src/math/smoke/FloorTest.h
+++ b/libc/test/src/math/smoke/FloorTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FLOORTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/FmaTest.h b/libc/test/src/math/smoke/FmaTest.h
index 7063ecf199837..4aadaf0f5e677 100644
--- a/libc/test/src/math/smoke/FmaTest.h
+++ b/libc/test/src/math/smoke/FmaTest.h
@@ -11,7 +11,7 @@
 
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FrexpTest.h b/libc/test/src/math/smoke/FrexpTest.h
index e9e496422f732..d690fed1d2183 100644
--- a/libc/test/src/math/smoke/FrexpTest.h
+++ b/libc/test/src/math/smoke/FrexpTest.h
@@ -8,7 +8,7 @@
 
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FromfpTest.h b/libc/test/src/math/smoke/FromfpTest.h
index f19f21ce47e7f..066d64ff11bf2 100644
--- a/libc/test/src/math/smoke/FromfpTest.h
+++ b/libc/test/src/math/smoke/FromfpTest.h
@@ -10,7 +10,7 @@
 #define LIBC_TEST_SRC_MATH_SMOKE_FROMFPTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/FromfpxTest.h b/libc/test/src/math/smoke/FromfpxTest.h
index 4aa47a68bb178..a605f494af4b6 100644
--- a/libc/test/src/math/smoke/FromfpxTest.h
+++ b/libc/test/src/math/smoke/FromfpxTest.h
@@ -10,7 +10,7 @@
 #define LIBC_TEST_SRC_MATH_SMOKE_FROMFPXTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/HypotTest.h b/libc/test/src/math/smoke/HypotTest.h
index 80e9bb7366dfe..b33cf3c6acdc9 100644
--- a/libc/test/src/math/smoke/HypotTest.h
+++ b/libc/test/src/math/smoke/HypotTest.h
@@ -11,7 +11,7 @@
 
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h
index 713d305c47494..e82d11959c900 100644
--- a/libc/test/src/math/smoke/LdExpTest.h
+++ b/libc/test/src/math/smoke/LdExpTest.h
@@ -13,7 +13,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/NormalFloat.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <stdint.h>
diff --git a/libc/test/src/math/smoke/LogbTest.h b/libc/test/src/math/smoke/LogbTest.h
index 4938fcf8f6f16..b775deaca56a3 100644
--- a/libc/test/src/math/smoke/LogbTest.h
+++ b/libc/test/src/math/smoke/LogbTest.h
@@ -8,7 +8,7 @@
 
 #include "src/__support/FPUtil/ManipulationFunctions.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/ModfTest.h b/libc/test/src/math/smoke/ModfTest.h
index 85db2d6d967b2..cff956f7a3019 100644
--- a/libc/test/src/math/smoke/ModfTest.h
+++ b/libc/test/src/math/smoke/ModfTest.h
@@ -9,7 +9,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/NearestIntegerOperations.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/NearbyIntTest.h b/libc/test/src/math/smoke/NearbyIntTest.h
index 0051ff9447a7e..4e253a1c2d35f 100644
--- a/libc/test/src/math/smoke/NearbyIntTest.h
+++ b/libc/test/src/math/smoke/NearbyIntTest.h
@@ -12,7 +12,7 @@
 #include "hdr/fenv_macros.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO,
diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h
index d65ccdf8e70c3..319cb42491d1a 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -15,7 +15,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 // TODO: Strengthen errno,exception checks and remove these assert macros
diff --git a/libc/test/src/math/smoke/NextDownTest.h b/libc/test/src/math/smoke/NextDownTest.h
index b54c6d5763222..b1335372b0179 100644
--- a/libc/test/src/math/smoke/NextDownTest.h
+++ b/libc/test/src/math/smoke/NextDownTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_NEXTDOWNTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h
index a24ec9ff6bd81..d77a142bdf8ea 100644
--- a/libc/test/src/math/smoke/NextTowardTest.h
+++ b/libc/test/src/math/smoke/NextTowardTest.h
@@ -16,7 +16,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 // TODO: Strengthen errno,exception checks and remove these assert macros
diff --git a/libc/test/src/math/smoke/NextUpTest.h b/libc/test/src/math/smoke/NextUpTest.h
index 7f66c115dfc2d..7097988ab765b 100644
--- a/libc/test/src/math/smoke/NextUpTest.h
+++ b/libc/test/src/math/smoke/NextUpTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_NEXTUPTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/RIntTest.h b/libc/test/src/math/smoke/RIntTest.h
index 1412c3f27a2d5..b3fea9a5866a7 100644
--- a/libc/test/src/math/smoke/RIntTest.h
+++ b/libc/test/src/math/smoke/RIntTest.h
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/fenv_macros.h"
diff --git a/libc/test/src/math/smoke/RemQuoTest.h b/libc/test/src/math/smoke/RemQuoTest.h
index 43eee3d38e449..76ee6ccb16aa0 100644
--- a/libc/test/src/math/smoke/RemQuoTest.h
+++ b/libc/test/src/math/smoke/RemQuoTest.h
@@ -13,7 +13,7 @@
 #include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/RoundEvenTest.h b/libc/test/src/math/smoke/RoundEvenTest.h
index 479b70912fedc..20dced8e5d5f4 100644
--- a/libc/test/src/math/smoke/RoundEvenTest.h
+++ b/libc/test/src/math/smoke/RoundEvenTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDEVENTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/RoundTest.h b/libc/test/src/math/smoke/RoundTest.h
index 36994f27eb4c0..89cdeb974f078 100644
--- a/libc/test/src/math/smoke/RoundTest.h
+++ b/libc/test/src/math/smoke/RoundTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h
index 3ff311f46b056..5ba9f2315fc6c 100644
--- a/libc/test/src/math/smoke/RoundToIntegerTest.h
+++ b/libc/test/src/math/smoke/RoundToIntegerTest.h
@@ -12,7 +12,7 @@
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/SqrtTest.h b/libc/test/src/math/smoke/SqrtTest.h
index 8afacaf01ae42..b6ae9b4ef4f05 100644
--- a/libc/test/src/math/smoke/SqrtTest.h
+++ b/libc/test/src/math/smoke/SqrtTest.h
@@ -8,7 +8,7 @@
 
 #include "src/__support/CPP/bit.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/TruncTest.h b/libc/test/src/math/smoke/TruncTest.h
index 1d9c44dfb3748..03f8af88c6d60 100644
--- a/libc/test/src/math/smoke/TruncTest.h
+++ b/libc/test/src/math/smoke/TruncTest.h
@@ -10,7 +10,7 @@
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_TRUNCTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "hdr/math_macros.h"
diff --git a/libc/test/src/math/smoke/UfromfpTest.h b/libc/test/src/math/smoke/UfromfpTest.h
index 1c04049ebb4fa..94309c70bdddf 100644
--- a/libc/test/src/math/smoke/UfromfpTest.h
+++ b/libc/test/src/math/smoke/UfromfpTest.h
@@ -10,7 +10,7 @@
 #define LIBC_TEST_SRC_MATH_SMOKE_UFROMFPTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/UfromfpxTest.h b/libc/test/src/math/smoke/UfromfpxTest.h
index 973bc8a4d1be7..61489b5957b85 100644
--- a/libc/test/src/math/smoke/UfromfpxTest.h
+++ b/libc/test/src/math/smoke/UfromfpxTest.h
@@ -10,7 +10,7 @@
 #define LIBC_TEST_SRC_MATH_SMOKE_UFROMFPXTEST_H
 
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 template <typename T>
diff --git a/libc/test/src/math/smoke/acosf_test.cpp b/libc/test/src/math/smoke/acosf_test.cpp
index 732c29548c60d..cc61f7f38878e 100644
--- a/libc/test/src/math/smoke/acosf_test.cpp
+++ b/libc/test/src/math/smoke/acosf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/acosf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/acoshf_test.cpp b/libc/test/src/math/smoke/acoshf_test.cpp
index 2e94216ede364..8574eae57d8fe 100644
--- a/libc/test/src/math/smoke/acoshf_test.cpp
+++ b/libc/test/src/math/smoke/acoshf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/acoshf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/asinf_test.cpp b/libc/test/src/math/smoke/asinf_test.cpp
index c67d07711cd13..6ef53cd689319 100644
--- a/libc/test/src/math/smoke/asinf_test.cpp
+++ b/libc/test/src/math/smoke/asinf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/asinf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/asinhf_test.cpp b/libc/test/src/math/smoke/asinhf_test.cpp
index f95184676303d..b1acaa03b3b79 100644
--- a/libc/test/src/math/smoke/asinhf_test.cpp
+++ b/libc/test/src/math/smoke/asinhf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/asinhf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/atan2f_test.cpp b/libc/test/src/math/smoke/atan2f_test.cpp
index 32a28cfdfeaa6..8f64abe72c2fd 100644
--- a/libc/test/src/math/smoke/atan2f_test.cpp
+++ b/libc/test/src/math/smoke/atan2f_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/atan2f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 using LlvmLibcAtan2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/smoke/atanf_test.cpp b/libc/test/src/math/smoke/atanf_test.cpp
index 56bf2f951b336..17e1c4e0db37a 100644
--- a/libc/test/src/math/smoke/atanf_test.cpp
+++ b/libc/test/src/math/smoke/atanf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/atanf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/atanhf_test.cpp b/libc/test/src/math/smoke/atanhf_test.cpp
index 2d2acfeeab4e5..cbd01b468092f 100644
--- a/libc/test/src/math/smoke/atanhf_test.cpp
+++ b/libc/test/src/math/smoke/atanhf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/atanhf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/cosf_test.cpp b/libc/test/src/math/smoke/cosf_test.cpp
index 7000fe2f2b07d..82589b1263eec 100644
--- a/libc/test/src/math/smoke/cosf_test.cpp
+++ b/libc/test/src/math/smoke/cosf_test.cpp
@@ -10,29 +10,26 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/cosf.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
+#include "test/UnitTest/FPTest.h"
 
 #include <errno.h>
 #include <stdint.h>
 
 using LlvmLibcCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 
-TEST_F(LlvmLibcCosfTest, SpecialNumbers) {
-  LIBC_NAMESPACE::libc_errno = 0;
+TEST_F(LlvmLibcCosfTest, SpecialNumbers) {  
+  EXPECT_NO_ERRNO_FP_EXCEPT(
+      EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(aNaN)));
 
-  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cosf(aNaN));
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_NO_ERRNO_FP_EXCEPT_ALL_ROUNDING(
+      EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::cosf(0.0f)));
 
-  EXPECT_FP_EQ_ALL_ROUNDING(1.0f, LIBC_NAMESPACE::cosf(0.0f));
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_NO_ERRNO_FP_EXCEPT_ALL_ROUNDING(
+      EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::cosf(-0.0f)));
 
-  EXPECT_FP_EQ_ALL_ROUNDING(1.0f, LIBC_NAMESPACE::cosf(-0.0f));
-  EXPECT_MATH_ERRNO(0);
+  EXPECT_ERRNO_FP_EXCEPT_ALL_ROUNDING(
+      EDOM, FE_INVALID, EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(inf)));
 
-  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cosf(inf));
-  EXPECT_MATH_ERRNO(EDOM);
-
-  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cosf(neg_inf));
-  EXPECT_MATH_ERRNO(EDOM);
+  EXPECT_ERRNO_FP_EXCEPT_ALL_ROUNDING(
+      EDOM, FE_INVALID, EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(neg_inf)));
 }
diff --git a/libc/test/src/math/smoke/coshf_test.cpp b/libc/test/src/math/smoke/coshf_test.cpp
index 4d915b12dee16..fe81541cb3190 100644
--- a/libc/test/src/math/smoke/coshf_test.cpp
+++ b/libc/test/src/math/smoke/coshf_test.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/coshf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/erff_test.cpp b/libc/test/src/math/smoke/erff_test.cpp
index 102126ee4e23f..da87e5d23651c 100644
--- a/libc/test/src/math/smoke/erff_test.cpp
+++ b/libc/test/src/math/smoke/erff_test.cpp
@@ -9,7 +9,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/erff.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/exp10_test.cpp b/libc/test/src/math/smoke/exp10_test.cpp
index 7154cb176038c..12ffe7bb22c60 100644
--- a/libc/test/src/math/smoke/exp10_test.cpp
+++ b/libc/test/src/math/smoke/exp10_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/exp10.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/exp10f_test.cpp b/libc/test/src/math/smoke/exp10f_test.cpp
index 9fb15ae75348b..43fbf6fa8551c 100644
--- a/libc/test/src/math/smoke/exp10f_test.cpp
+++ b/libc/test/src/math/smoke/exp10f_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/exp10f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <stdint.h>
diff --git a/libc/test/src/math/smoke/exp2_test.cpp b/libc/test/src/math/smoke/exp2_test.cpp
index a8ef6cfa7f6a1..1969a578cc700 100644
--- a/libc/test/src/math/smoke/exp2_test.cpp
+++ b/libc/test/src/math/smoke/exp2_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/exp2.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/exp2f_test.cpp b/libc/test/src/math/smoke/exp2f_test.cpp
index 3ef1a4ece4cf6..cba9198a1c996 100644
--- a/libc/test/src/math/smoke/exp2f_test.cpp
+++ b/libc/test/src/math/smoke/exp2f_test.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
 #include "src/errno/libc_errno.h"
 #include "src/math/exp2f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <stdint.h>
diff --git a/libc/test/src/math/smoke/exp2m1f_test.cpp b/libc/test/src/math/smoke/exp2m1f_test.cpp
index 2df4353852472..994dcd2baa989 100644
--- a/libc/test/src/math/smoke/exp2m1f_test.cpp
+++ b/libc/test/src/math/smoke/exp2m1f_test.cpp
@@ -8,7 +8,7 @@
 
 #include "src/errno/libc_errno.h"
 #include "src/math/exp2m1f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 using LlvmLibcExp2m1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/smoke/exp_test.cpp b/libc/test/src/math/smoke/exp_test.cpp
index 2abaa7230831f..8c6c03efd7280 100644
--- a/libc/test/src/math/smoke/exp_test.cpp
+++ b/libc/test/src/math/smoke/exp_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/exp.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/expf_test.cpp b/libc/test/src/math/smoke/expf_test.cpp
index b954125afd7bb..048cddd0f9245 100644
--- a/libc/test/src/math/smoke/expf_test.cpp
+++ b/libc/test/src/math/smoke/expf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/expf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <stdint.h>
diff --git a/libc/test/src/math/smoke/expm1_test.cpp b/libc/test/src/math/smoke/expm1_test.cpp
index d5f166d53a50e..a5c4d3fff6199 100644
--- a/libc/test/src/math/smoke/expm1_test.cpp
+++ b/libc/test/src/math/smoke/expm1_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/expm1.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/expm1f_test.cpp b/libc/test/src/math/smoke/expm1f_test.cpp
index 03b6e47b7c3bc..51fa15a1653ae 100644
--- a/libc/test/src/math/smoke/expm1f_test.cpp
+++ b/libc/test/src/math/smoke/expm1f_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/expm1f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <stdint.h>
diff --git a/libc/test/src/math/smoke/log10_test.cpp b/libc/test/src/math/smoke/log10_test.cpp
index 37baf89128f2e..e8ce7b76f93ab 100644
--- a/libc/test/src/math/smoke/log10_test.cpp
+++ b/libc/test/src/math/smoke/log10_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log10.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/log10f_test.cpp b/libc/test/src/math/smoke/log10f_test.cpp
index 721045d355da8..babc9a26e923b 100644
--- a/libc/test/src/math/smoke/log10f_test.cpp
+++ b/libc/test/src/math/smoke/log10f_test.cpp
@@ -9,7 +9,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/log10f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/log1p_test.cpp b/libc/test/src/math/smoke/log1p_test.cpp
index 993dbf8001df8..7a99b35551e50 100644
--- a/libc/test/src/math/smoke/log1p_test.cpp
+++ b/libc/test/src/math/smoke/log1p_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log1p.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/log1pf_test.cpp b/libc/test/src/math/smoke/log1pf_test.cpp
index 6127cc89a7421..c139300c948c6 100644
--- a/libc/test/src/math/smoke/log1pf_test.cpp
+++ b/libc/test/src/math/smoke/log1pf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log1pf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/log2_test.cpp b/libc/test/src/math/smoke/log2_test.cpp
index b59767e668eb6..18cc2461fc8b1 100644
--- a/libc/test/src/math/smoke/log2_test.cpp
+++ b/libc/test/src/math/smoke/log2_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log2.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/log2f_test.cpp b/libc/test/src/math/smoke/log2f_test.cpp
index 00bfb7c4abad6..88fb93c11b1e3 100644
--- a/libc/test/src/math/smoke/log2f_test.cpp
+++ b/libc/test/src/math/smoke/log2f_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log2f.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <stdint.h>
diff --git a/libc/test/src/math/smoke/log_test.cpp b/libc/test/src/math/smoke/log_test.cpp
index fd527dee50847..a079fcc625602 100644
--- a/libc/test/src/math/smoke/log_test.cpp
+++ b/libc/test/src/math/smoke/log_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/log.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/logf_test.cpp b/libc/test/src/math/smoke/logf_test.cpp
index a272060276145..0927395a766de 100644
--- a/libc/test/src/math/smoke/logf_test.cpp
+++ b/libc/test/src/math/smoke/logf_test.cpp
@@ -9,7 +9,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/logf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <stdint.h>
diff --git a/libc/test/src/math/smoke/nan_test.cpp b/libc/test/src/math/smoke/nan_test.cpp
index 2ddef58325671..02f7bcac58c62 100644
--- a/libc/test/src/math/smoke/nan_test.cpp
+++ b/libc/test/src/math/smoke/nan_test.cpp
@@ -9,7 +9,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/nan.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include <signal.h>
 
diff --git a/libc/test/src/math/smoke/nanf128_test.cpp b/libc/test/src/math/smoke/nanf128_test.cpp
index 8c15c532ebcf4..4c6b3ba6649b9 100644
--- a/libc/test/src/math/smoke/nanf128_test.cpp
+++ b/libc/test/src/math/smoke/nanf128_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/uint128.h"
 #include "src/math/nanf128.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 class LlvmLibcNanf128Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
diff --git a/libc/test/src/math/smoke/nanf_test.cpp b/libc/test/src/math/smoke/nanf_test.cpp
index 71f888c610aaf..a802b2769248d 100644
--- a/libc/test/src/math/smoke/nanf_test.cpp
+++ b/libc/test/src/math/smoke/nanf_test.cpp
@@ -9,7 +9,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/nanf.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include <signal.h>
 
diff --git a/libc/test/src/math/smoke/nanl_test.cpp b/libc/test/src/math/smoke/nanl_test.cpp
index 7fff20b1e7be3..f58348486cf6d 100644
--- a/libc/test/src/math/smoke/nanl_test.cpp
+++ b/libc/test/src/math/smoke/nanl_test.cpp
@@ -9,7 +9,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/nanl.h"
 #include "test/UnitTest/FEnvSafeTest.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include <signal.h>
 
diff --git a/libc/test/src/math/smoke/powf_test.cpp b/libc/test/src/math/smoke/powf_test.cpp
index 98a532f3468c7..877af88905e86 100644
--- a/libc/test/src/math/smoke/powf_test.cpp
+++ b/libc/test/src/math/smoke/powf_test.cpp
@@ -9,7 +9,7 @@
 #include "hdr/math_macros.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/powf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/sincosf_test.cpp b/libc/test/src/math/smoke/sincosf_test.cpp
index 8c35953240d8d..81b1400691798 100644
--- a/libc/test/src/math/smoke/sincosf_test.cpp
+++ b/libc/test/src/math/smoke/sincosf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/sincosf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
@@ -19,31 +19,30 @@
 using LlvmLibcSinCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 
 TEST_F(LlvmLibcSinCosfTest, SpecialNumbers) {
-  LIBC_NAMESPACE::libc_errno = 0;
   float sin, cos;
 
-  LIBC_NAMESPACE::sincosf(aNaN, &sin, &cos);
+  EXPECT_NO_ERRNO_FP_EXCEPT_ALL_ROUNDING(
+      LIBC_NAMESPACE::sincosf(aNaN, &sin, &cos));
   EXPECT_FP_EQ(aNaN, cos);
   EXPECT_FP_EQ(aNaN, sin);
-  EXPECT_MATH_ERRNO(0);
 
-  LIBC_NAMESPACE::sincosf(0.0f, &sin, &cos);
+  EXPECT_NO_ERRNO_FP_EXCEPT_ALL_ROUNDING(
+      LIBC_NAMESPACE::sincosf(0.0f, &sin, &cos));
   EXPECT_FP_EQ(1.0f, cos);
   EXPECT_FP_EQ(0.0f, sin);
-  EXPECT_MATH_ERRNO(0);
 
-  LIBC_NAMESPACE::sincosf(-0.0f, &sin, &cos);
+  EXPECT_NO_ERRNO_FP_EXCEPT_ALL_ROUNDING(
+      LIBC_NAMESPACE::sincosf(-0.0f, &sin, &cos));
   EXPECT_FP_EQ(1.0f, cos);
   EXPECT_FP_EQ(-0.0f, sin);
-  EXPECT_MATH_ERRNO(0);
 
-  LIBC_NAMESPACE::sincosf(inf, &sin, &cos);
+  EXPECT_ERRNO_FP_EXCEPT_ALL_ROUNDING(EDOM, FE_INVALID,
+                                      LIBC_NAMESPACE::sincosf(inf, &sin, &cos));
   EXPECT_FP_EQ(aNaN, cos);
   EXPECT_FP_EQ(aNaN, sin);
-  EXPECT_MATH_ERRNO(EDOM);
 
-  LIBC_NAMESPACE::sincosf(neg_inf, &sin, &cos);
+  EXPECT_ERRNO_FP_EXCEPT_ALL_ROUNDING(
+      EDOM, FE_INVALID, LIBC_NAMESPACE::sincosf(neg_inf, &sin, &cos));
   EXPECT_FP_EQ(aNaN, cos);
   EXPECT_FP_EQ(aNaN, sin);
-  EXPECT_MATH_ERRNO(EDOM);
 }
diff --git a/libc/test/src/math/smoke/sinf_test.cpp b/libc/test/src/math/smoke/sinf_test.cpp
index 9fc208dd545b2..acdd9d0225901 100644
--- a/libc/test/src/math/smoke/sinf_test.cpp
+++ b/libc/test/src/math/smoke/sinf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/sinf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/sinhf_test.cpp b/libc/test/src/math/smoke/sinhf_test.cpp
index 1e052988eb286..18e453903e9bb 100644
--- a/libc/test/src/math/smoke/sinhf_test.cpp
+++ b/libc/test/src/math/smoke/sinhf_test.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/sinhf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/tanf_test.cpp b/libc/test/src/math/smoke/tanf_test.cpp
index ab3f7c1aeb7e4..ead9c45272e12 100644
--- a/libc/test/src/math/smoke/tanf_test.cpp
+++ b/libc/test/src/math/smoke/tanf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/tanf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/smoke/tanhf_test.cpp b/libc/test/src/math/smoke/tanhf_test.cpp
index ddae021d2bc42..91f3e00c56f6e 100644
--- a/libc/test/src/math/smoke/tanhf_test.cpp
+++ b/libc/test/src/math/smoke/tanhf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/tanhf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include <errno.h>
diff --git a/libc/test/src/math/tan_test.cpp b/libc/test/src/math/tan_test.cpp
index d813dccc38369..4e33658e24d96 100644
--- a/libc/test/src/math/tan_test.cpp
+++ b/libc/test/src/math/tan_test.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/tan.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/math/tanf_test.cpp b/libc/test/src/math/tanf_test.cpp
index e624d30f1e00f..b87c7474bb692 100644
--- a/libc/test/src/math/tanf_test.cpp
+++ b/libc/test/src/math/tanf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/tanf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "test/src/math/sdcomp26094.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
diff --git a/libc/test/src/math/tanhf_test.cpp b/libc/test/src/math/tanhf_test.cpp
index c34efe8d733be..5596c37a3e26d 100644
--- a/libc/test/src/math/tanhf_test.cpp
+++ b/libc/test/src/math/tanhf_test.cpp
@@ -10,7 +10,7 @@
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/errno/libc_errno.h"
 #include "src/math/tanhf.h"
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 
diff --git a/libc/test/src/stdfix/ExpTest.h b/libc/test/src/stdfix/ExpTest.h
index e588cebf621b9..d7ddc710a5965 100644
--- a/libc/test/src/stdfix/ExpTest.h
+++ b/libc/test/src/stdfix/ExpTest.h
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "src/__support/CPP/bit.h"
diff --git a/libc/test/src/stdfix/ISqrtTest.h b/libc/test/src/stdfix/ISqrtTest.h
index ddf292fdd083f..50356ba8c8639 100644
--- a/libc/test/src/stdfix/ISqrtTest.h
+++ b/libc/test/src/stdfix/ISqrtTest.h
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 #include "src/__support/CPP/bit.h"
diff --git a/libc/test/src/stdio/sscanf_test.cpp b/libc/test/src/stdio/sscanf_test.cpp
index 741815bb15171..0f09159edb654 100644
--- a/libc/test/src/stdio/sscanf_test.cpp
+++ b/libc/test/src/stdio/sscanf_test.cpp
@@ -13,7 +13,7 @@
 
 #include <stdio.h> // For EOF
 
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/Test.h"
 
 TEST(LlvmLibcSScanfTest, SimpleStringConv) {
diff --git a/libc/test/src/stdlib/strtof_test.cpp b/libc/test/src/stdlib/strtof_test.cpp
index d7991745b69e6..d5a5031c48de6 100644
--- a/libc/test/src/stdlib/strtof_test.cpp
+++ b/libc/test/src/stdlib/strtof_test.cpp
@@ -10,7 +10,7 @@
 #include "src/errno/libc_errno.h"
 #include "src/stdlib/strtof.h"
 
-#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/FPTest.h"
 #include "test/UnitTest/RoundingModeUtils.h"
 #include "test/UnitTest/Test.h"
 

>From f058e2fc125685d937eb6e6d1fffd144a6cbbc82 Mon Sep 17 00:00:00 2001
From: Michael Flanders <flanders.michaelk at gmail.com>
Date: Thu, 9 May 2024 10:34:59 -0500
Subject: [PATCH 2/4] guard on math_errhandling & MATH_ERR{NO,EXCEPT} in fp
 assertions

---
 libc/test/UnitTest/ErrnoSetterMatcher.h | 4 +++-
 libc/test/UnitTest/FPExceptMatcher.h    | 6 ++++--
 libc/test/UnitTest/FPTest.h             | 7 +++++--
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/libc/test/UnitTest/ErrnoSetterMatcher.h b/libc/test/UnitTest/ErrnoSetterMatcher.h
index a83003cbd137d..d0f284b733309 100644
--- a/libc/test/UnitTest/ErrnoSetterMatcher.h
+++ b/libc/test/UnitTest/ErrnoSetterMatcher.h
@@ -189,7 +189,9 @@ static ErrnoSetterMatcherBuilder<RetT> returns(internal::Comparator<RetT> cmp) {
 
 // Used to check that `LIBC_NAMESPACE::libc_errno` was 0 or a specific
 // errno after executing `expr_or_statement` from a state where
-// `LIBC_NAMESPACE::libc_errno` was 0.
+// `LIBC_NAMESPACE::libc_errno` was 0. This is generic, so does not check
+// `math_errhandling & MATH_ERRNO` before errno matching, see FPTest.h for
+// assertions that check this.
 //
 // Expects `expected` to be convertible to int type.
 //
diff --git a/libc/test/UnitTest/FPExceptMatcher.h b/libc/test/UnitTest/FPExceptMatcher.h
index ce635348e904a..12adaeb259c5a 100644
--- a/libc/test/UnitTest/FPExceptMatcher.h
+++ b/libc/test/UnitTest/FPExceptMatcher.h
@@ -147,8 +147,10 @@ class FPExceptCallableMatcher : public Matcher<bool> {
     expr_or_statement;                                                         \
     int expected_ = (expected);                                                \
     int mask_ = expected_ ? expected_ : FE_ALL_EXCEPT;                         \
-    EXPECT_FP_EXCEPT_EQUAL(expected_,                                          \
-                           LIBC_NAMESPACE::fputil::test_except(mask_));        \
+    if (math_errhandling & MATH_ERREXCEPT) {                                   \
+      EXPECT_FP_EXCEPT_EQUAL(expected_,                                        \
+                             LIBC_NAMESPACE::fputil::test_except(mask_));      \
+    }                                                                          \
   } while (0)
 
 #else // !LIBC_TEST_HAS_MATCHERS()
diff --git a/libc/test/UnitTest/FPTest.h b/libc/test/UnitTest/FPTest.h
index 2176721fac743..0d530cdff9c39 100644
--- a/libc/test/UnitTest/FPTest.h
+++ b/libc/test/UnitTest/FPTest.h
@@ -92,8 +92,11 @@ struct FPTest : public ErrnoSafeTest, public FEnvSafeTest {
 // were set
 #define EXPECT_ERRNO_FP_EXCEPT(expected_errno, expected_fexn,                  \
                                expr_or_statement)                              \
-  EXPECT_FP_EXCEPT((expected_fexn),                                            \
-                   EXPECT_ERRNO((expected_errno), expr_or_statement))
+  EXPECT_FP_EXCEPT((expected_fexn), EXPECT_ERRNO((expected_errno), {           \
+                     expr_or_statement;                                        \
+                     if (!(math_errhandling & MATH_ERRNO))                     \
+                       break;                                                  \
+                   }))
 
 #define EXPECT_NO_ERRNO_FP_EXCEPT(expr_or_statement)                           \
   EXPECT_ERRNO_FP_EXCEPT(0, 0, expr_or_statement)

>From c3e6484620f1dc4bae83a7781735020c03c60cf5 Mon Sep 17 00:00:00 2001
From: Michael Flanders <flanders.michaelk at gmail.com>
Date: Thu, 9 May 2024 10:39:17 -0500
Subject: [PATCH 3/4] formatting

---
 libc/test/UnitTest/FPTest.h            | 6 +++---
 libc/test/UnitTest/LibcTest.h          | 3 +--
 libc/test/src/math/smoke/cosf_test.cpp | 5 ++---
 3 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/libc/test/UnitTest/FPTest.h b/libc/test/UnitTest/FPTest.h
index 0d530cdff9c39..1dea8678707f9 100644
--- a/libc/test/UnitTest/FPTest.h
+++ b/libc/test/UnitTest/FPTest.h
@@ -12,11 +12,11 @@
 #include "src/__support/CPP/utility.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
-#include "test/UnitTest/ErrnoSafeTest.h" // Test fixture for clearing errno
+#include "test/UnitTest/ErrnoSafeTest.h"      // Test fixture for clearing errno
 #include "test/UnitTest/ErrnoSetterMatcher.h" // Per-assertion clear/check errno
-#include "test/UnitTest/FEnvSafeTest.h" // Test fixture for resetting fenv
+#include "test/UnitTest/FEnvSafeTest.h"       // Test fixture for resetting fenv
 #include "test/UnitTest/FPExceptMatcher.h" // Per-assertion clear/check fp exns
-#include "test/UnitTest/FPMatcher.h" // Matchers/assertions for fp values
+#include "test/UnitTest/FPMatcher.h"       // Matchers/assertions for fp values
 #include "test/UnitTest/Test.h"
 
 #define DECLARE_SPECIAL_CONSTANTS(T)                                           \
diff --git a/libc/test/UnitTest/LibcTest.h b/libc/test/UnitTest/LibcTest.h
index d2372f6d57b3d..0137d41abd0ce 100644
--- a/libc/test/UnitTest/LibcTest.h
+++ b/libc/test/UnitTest/LibcTest.h
@@ -192,8 +192,7 @@ class Test {
                          const char *LHSStr, const char *RHSStr,
                          internal::Location Loc);
 
-  template <typename Func>
-  testutils::FunctionCaller *createCallable(Func f) {
+  template <typename Func> testutils::FunctionCaller *createCallable(Func f) {
     struct Callable : public testutils::FunctionCaller {
       Func f;
       Callable(Func f) : f(f) {}
diff --git a/libc/test/src/math/smoke/cosf_test.cpp b/libc/test/src/math/smoke/cosf_test.cpp
index 82589b1263eec..a738512edd3d5 100644
--- a/libc/test/src/math/smoke/cosf_test.cpp
+++ b/libc/test/src/math/smoke/cosf_test.cpp
@@ -17,9 +17,8 @@
 
 using LlvmLibcCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 
-TEST_F(LlvmLibcCosfTest, SpecialNumbers) {  
-  EXPECT_NO_ERRNO_FP_EXCEPT(
-      EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(aNaN)));
+TEST_F(LlvmLibcCosfTest, SpecialNumbers) {
+  EXPECT_NO_ERRNO_FP_EXCEPT(EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf(aNaN)));
 
   EXPECT_NO_ERRNO_FP_EXCEPT_ALL_ROUNDING(
       EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::cosf(0.0f)));

>From a215bcf6e3cd2cb6f08fd3af8c3c0aa141210dc7 Mon Sep 17 00:00:00 2001
From: Michael Flanders <flanders.michaelk at gmail.com>
Date: Thu, 9 May 2024 10:58:11 -0500
Subject: [PATCH 4/4] space in fpexceptmatcher error message

---
 libc/test/UnitTest/FPExceptMatcher.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/test/UnitTest/FPExceptMatcher.h b/libc/test/UnitTest/FPExceptMatcher.h
index 12adaeb259c5a..c3392eef07728 100644
--- a/libc/test/UnitTest/FPExceptMatcher.h
+++ b/libc/test/UnitTest/FPExceptMatcher.h
@@ -51,7 +51,7 @@ class FPExceptMatcher : public Matcher<int> {
     bool firstPrinted = false;
     auto printWithPipe = [&](const char *name) {
       if (firstPrinted)
-        tlog << "| ";
+        tlog << " | ";
 
       tlog << name;
 



More information about the libc-commits mailing list