[libc-commits] [libc] 055be3c - [libc] Enable hermetic floating point tests again.

Tue Ly via libc-commits libc-commits at lists.llvm.org
Wed Jun 14 07:53:53 PDT 2023


Author: Tue Ly
Date: 2023-06-14T10:53:35-04:00
New Revision: 055be3c30c78e6ed1e219f8007fbe8302bcbea43

URL: https://github.com/llvm/llvm-project/commit/055be3c30c78e6ed1e219f8007fbe8302bcbea43
DIFF: https://github.com/llvm/llvm-project/commit/055be3c30c78e6ed1e219f8007fbe8302bcbea43.diff

LOG: [libc] Enable hermetic floating point tests again.

Fixing an issue with LLVM libc's fenv.h defined rounding mode macros
differently from system libc, making get_round() return different values from
fegetround().  Also letting math tests to skip rounding modes that cannot be
set.  This should allow math tests to be run on platforms in which fenv.h is not
implemented yet.

This allows us to re-enable hermatic floating point tests in
https://reviews.llvm.org/D151123 and reverting https://reviews.llvm.org/D152742.

Reviewed By: jhuber6

Differential Revision: https://reviews.llvm.org/D152873

Added: 
    

Modified: 
    libc/include/llvm-libc-macros/fenv-macros.h
    libc/src/__support/FPUtil/FEnvImpl.h
    libc/test/UnitTest/CMakeLists.txt
    libc/test/UnitTest/FPMatcher.h
    libc/test/UnitTest/RoundingModeUtils.cpp
    libc/test/UnitTest/RoundingModeUtils.h
    libc/test/src/CMakeLists.txt
    libc/test/src/__support/FPUtil/CMakeLists.txt
    libc/test/src/__support/FPUtil/rounding_mode_test.cpp
    libc/test/src/fenv/CMakeLists.txt
    libc/test/src/math/SqrtTest.h
    libc/test/src/math/exhaustive/acosf_test.cpp
    libc/test/src/math/exhaustive/acoshf_test.cpp
    libc/test/src/math/exhaustive/asinf_test.cpp
    libc/test/src/math/exhaustive/asinhf_test.cpp
    libc/test/src/math/exhaustive/atanf_test.cpp
    libc/test/src/math/exhaustive/atanhf_test.cpp
    libc/test/src/math/exhaustive/cosf_test.cpp
    libc/test/src/math/exhaustive/coshf_test.cpp
    libc/test/src/math/exhaustive/exp10f_test.cpp
    libc/test/src/math/exhaustive/exp2f_test.cpp
    libc/test/src/math/exhaustive/expf_test.cpp
    libc/test/src/math/exhaustive/expm1f_test.cpp
    libc/test/src/math/exhaustive/hypotf_test.cpp
    libc/test/src/math/exhaustive/log10f_test.cpp
    libc/test/src/math/exhaustive/log1pf_test.cpp
    libc/test/src/math/exhaustive/log2f_test.cpp
    libc/test/src/math/exhaustive/logf_test.cpp
    libc/test/src/math/exhaustive/sincosf_test.cpp
    libc/test/src/math/exhaustive/sinf_test.cpp
    libc/test/src/math/exhaustive/sinhf_test.cpp
    libc/test/src/math/exhaustive/tanf_test.cpp
    libc/test/src/math/exhaustive/tanhf_test.cpp
    libc/test/src/math/log10_test.cpp
    libc/test/src/math/log1p_test.cpp
    libc/test/src/math/log2_test.cpp
    libc/test/src/math/log_test.cpp
    libc/test/src/math/sincosf_test.cpp
    libc/test/src/stdio/sprintf_test.cpp
    libc/utils/MPFRWrapper/MPFRUtils.h
    utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel

Removed: 
    


################################################################################
diff  --git a/libc/include/llvm-libc-macros/fenv-macros.h b/libc/include/llvm-libc-macros/fenv-macros.h
index a73ebf41cbb36..cc0ea344b1702 100644
--- a/libc/include/llvm-libc-macros/fenv-macros.h
+++ b/libc/include/llvm-libc-macros/fenv-macros.h
@@ -17,10 +17,10 @@
 #define FE_ALL_EXCEPT                                                          \
   (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
 
-#define FE_DOWNWARD 1
-#define FE_TONEAREST 2
-#define FE_TOWARDZERO 4
-#define FE_UPWARD 8
+#define FE_DOWNWARD 0x400
+#define FE_TONEAREST 0
+#define FE_TOWARDZERO 0xC00
+#define FE_UPWARD 0x800
 
 #define FE_DFL_ENV ((fenv_t *)-1)
 

diff  --git a/libc/src/__support/FPUtil/FEnvImpl.h b/libc/src/__support/FPUtil/FEnvImpl.h
index ee2bd16e821d9..2556f432b02cc 100644
--- a/libc/src/__support/FPUtil/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/FEnvImpl.h
@@ -42,6 +42,8 @@ LIBC_INLINE int clear_except(int) { return 0; }
 
 LIBC_INLINE int test_except(int) { return 0; }
 
+LIBC_INLINE int get_except() { return 0; }
+
 LIBC_INLINE int set_except(int) { return 0; }
 
 LIBC_INLINE int raise_except(int) { return 0; }
@@ -52,7 +54,9 @@ LIBC_INLINE int disable_except(int) { return 0; }
 
 LIBC_INLINE int get_round() { return FE_TONEAREST; }
 
-LIBC_INLINE int set_round(int) { return 0; }
+LIBC_INLINE int set_round(int rounding_mode) {
+  return (rounding_mode == FE_TONEAREST) ? 0 : 1;
+}
 
 LIBC_INLINE int get_env(fenv_t *) { return 0; }
 

diff  --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt
index ec8182d88165a..aa081706f5022 100644
--- a/libc/test/UnitTest/CMakeLists.txt
+++ b/libc/test/UnitTest/CMakeLists.txt
@@ -110,6 +110,7 @@ add_unittest_framework_library(
     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(

diff  --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index 549892e8275b5..d8d032b3ef530 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -164,13 +164,17 @@ template <TestCond C, typename T> FPMatcher<T, C> getMatcher(T expectedValue) {
   do {                                                                         \
     using namespace __llvm_libc::fputil::testing;                              \
     ForceRoundingMode __r1(RoundingMode::Nearest);                             \
-    EXPECT_FP_EQ((expected), (actual));                                        \
+    if (__r1.success)                                                          \
+      EXPECT_FP_EQ((expected), (actual));                                      \
     ForceRoundingMode __r2(RoundingMode::Upward);                              \
-    EXPECT_FP_EQ((expected), (actual));                                        \
+    if (__r2.success)                                                          \
+      EXPECT_FP_EQ((expected), (actual));                                      \
     ForceRoundingMode __r3(RoundingMode::Downward);                            \
-    EXPECT_FP_EQ((expected), (actual));                                        \
+    if (__r3.success)                                                          \
+      EXPECT_FP_EQ((expected), (actual));                                      \
     ForceRoundingMode __r4(RoundingMode::TowardZero);                          \
-    EXPECT_FP_EQ((expected), (actual));                                        \
+    if (__r4.success)                                                          \
+      EXPECT_FP_EQ((expected), (actual));                                      \
   } while (0)
 
 #endif // LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H

diff  --git a/libc/test/UnitTest/RoundingModeUtils.cpp b/libc/test/UnitTest/RoundingModeUtils.cpp
index 8cc6834d89edb..c6a69fc3f16fc 100644
--- a/libc/test/UnitTest/RoundingModeUtils.cpp
+++ b/libc/test/UnitTest/RoundingModeUtils.cpp
@@ -7,6 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "RoundingModeUtils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/rounding_mode.h"
 
 #include <fenv.h>
 
@@ -34,15 +36,19 @@ int get_fe_rounding(RoundingMode mode) {
 }
 
 ForceRoundingMode::ForceRoundingMode(RoundingMode mode) {
-  old_rounding_mode = fegetround();
+  old_rounding_mode = quick_get_round();
   rounding_mode = get_fe_rounding(mode);
-  if (old_rounding_mode != rounding_mode)
-    fesetround(rounding_mode);
+  if (old_rounding_mode != rounding_mode) {
+    int status = set_round(rounding_mode);
+    success = (status == 0);
+  } else {
+    success = true;
+  }
 }
 
 ForceRoundingMode::~ForceRoundingMode() {
   if (old_rounding_mode != rounding_mode)
-    fesetround(old_rounding_mode);
+    set_round(old_rounding_mode);
 }
 
 } // namespace testing

diff  --git a/libc/test/UnitTest/RoundingModeUtils.h b/libc/test/UnitTest/RoundingModeUtils.h
index ac9f310eebe5a..e8611c34b5403 100644
--- a/libc/test/UnitTest/RoundingModeUtils.h
+++ b/libc/test/UnitTest/RoundingModeUtils.h
@@ -23,6 +23,7 @@ struct ForceRoundingMode {
 
   int old_rounding_mode;
   int rounding_mode;
+  bool success;
 };
 
 template <RoundingMode R> struct ForceRoundingModeTest : ForceRoundingMode {

diff  --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 9e6c02c1f9f4b..52452cd1037db 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -1,7 +1,7 @@
 function(add_fp_unittest name)
   cmake_parse_arguments(
     "MATH_UNITTEST"
-    "NEED_MPFR;HERMETIC_TEST_ONLY" # Optional arguments
+    "NEED_MPFR;UNIT_TEST_ONLY;HERMETIC_TEST_ONLY" # Optional arguments
     "" # Single value arguments
     "LINK_LIBRARIES" # Multi-value arguments
     ${ARGN}
@@ -16,6 +16,8 @@ function(add_fp_unittest name)
 
   if(MATH_UNITTEST_HERMETIC_TEST_ONLY)
     set(test_type HERMETIC_TEST_ONLY)
+  elseif(MATH_UNITTEST_UNIT_TEST_ONLY)
+    set(test_type UNIT_TEST_ONLY)
   endif()
   if(MATH_UNITTEST_NEED_MPFR)
     if(MATH_UNITTEST_HERMETIC_TEST_ONLY)
@@ -26,7 +28,7 @@ function(add_fp_unittest name)
   endif()
   list(APPEND MATH_UNITTEST_LINK_LIBRARIES LibcFPTestHelpers)
 
-  add_libc_unittest(
+  add_libc_test(
     ${name}
     ${test_type}
     LINK_LIBRARIES "${MATH_UNITTEST_LINK_LIBRARIES}"

diff  --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt
index 9367e2bb40a7a..411b8281470cf 100644
--- a/libc/test/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/test/src/__support/FPUtil/CMakeLists.txt
@@ -1,17 +1,15 @@
 add_custom_target(libc-fputil-tests)
 
-if(NOT LIBC_TARGET_ARCHITECTURE_IS_GPU)
-  add_fp_unittest(
-    dyadic_float_test
-    NEED_MPFR
-    SUITE
-      libc-fputil-tests
-    SRCS
-      dyadic_float_test.cpp
-    DEPENDS
-      libc.src.__support.FPUtil.dyadic_float
-  )
-endif()
+add_fp_unittest(
+  dyadic_float_test
+  NEED_MPFR
+  SUITE
+    libc-fputil-tests
+  SRCS
+    dyadic_float_test.cpp
+  DEPENDS
+    libc.src.__support.FPUtil.dyadic_float
+)
 
 add_libc_test(
   fpbits_test
@@ -24,14 +22,12 @@ add_libc_test(
     libc.src.__support.FPUtil.fpbits_str
 )
 
-if(NOT LIBC_TARGET_ARCHITECTURE_IS_GPU)
-  add_fp_unittest(
-    rounding_mode_test
-    SUITE
-      libc-fputil-tests
-    SRCS
-      rounding_mode_test.cpp
-    DEPENDS
-      libc.src.__support.FPUtil.rounding_mode
-  )
-endif()
+add_fp_unittest(
+  rounding_mode_test
+  SUITE
+    libc-fputil-tests
+  SRCS
+    rounding_mode_test.cpp
+  DEPENDS
+    libc.src.__support.FPUtil.rounding_mode
+)

diff  --git a/libc/test/src/__support/FPUtil/rounding_mode_test.cpp b/libc/test/src/__support/FPUtil/rounding_mode_test.cpp
index 8d3332f142ccf..01c1b3c2a9ffa 100644
--- a/libc/test/src/__support/FPUtil/rounding_mode_test.cpp
+++ b/libc/test/src/__support/FPUtil/rounding_mode_test.cpp
@@ -19,19 +19,23 @@ TEST(LlvmLibcFEnvImplTest, QuickRoundingUpTest) {
   using __llvm_libc::fputil::fenv_is_round_up;
   {
     ForceRoundingMode __r(RoundingMode::Upward);
-    ASSERT_TRUE(fenv_is_round_up());
+    if (__r.success)
+      ASSERT_TRUE(fenv_is_round_up());
   }
   {
     ForceRoundingMode __r(RoundingMode::Downward);
-    ASSERT_FALSE(fenv_is_round_up());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_up());
   }
   {
     ForceRoundingMode __r(RoundingMode::Nearest);
-    ASSERT_FALSE(fenv_is_round_up());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_up());
   }
   {
     ForceRoundingMode __r(RoundingMode::TowardZero);
-    ASSERT_FALSE(fenv_is_round_up());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_up());
   }
 }
 
@@ -39,19 +43,23 @@ TEST(LlvmLibcFEnvImplTest, QuickRoundingDownTest) {
   using __llvm_libc::fputil::fenv_is_round_down;
   {
     ForceRoundingMode __r(RoundingMode::Upward);
-    ASSERT_FALSE(fenv_is_round_down());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_down());
   }
   {
     ForceRoundingMode __r(RoundingMode::Downward);
-    ASSERT_TRUE(fenv_is_round_down());
+    if (__r.success)
+      ASSERT_TRUE(fenv_is_round_down());
   }
   {
     ForceRoundingMode __r(RoundingMode::Nearest);
-    ASSERT_FALSE(fenv_is_round_down());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_down());
   }
   {
     ForceRoundingMode __r(RoundingMode::TowardZero);
-    ASSERT_FALSE(fenv_is_round_down());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_down());
   }
 }
 
@@ -59,19 +67,23 @@ TEST(LlvmLibcFEnvImplTest, QuickRoundingNearestTest) {
   using __llvm_libc::fputil::fenv_is_round_to_nearest;
   {
     ForceRoundingMode __r(RoundingMode::Upward);
-    ASSERT_FALSE(fenv_is_round_to_nearest());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_to_nearest());
   }
   {
     ForceRoundingMode __r(RoundingMode::Downward);
-    ASSERT_FALSE(fenv_is_round_to_nearest());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_to_nearest());
   }
   {
     ForceRoundingMode __r(RoundingMode::Nearest);
-    ASSERT_TRUE(fenv_is_round_to_nearest());
+    if (__r.success)
+      ASSERT_TRUE(fenv_is_round_to_nearest());
   }
   {
     ForceRoundingMode __r(RoundingMode::TowardZero);
-    ASSERT_FALSE(fenv_is_round_to_nearest());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_to_nearest());
   }
 }
 
@@ -79,19 +91,23 @@ TEST(LlvmLibcFEnvImplTest, QuickRoundingTowardZeroTest) {
   using __llvm_libc::fputil::fenv_is_round_to_zero;
   {
     ForceRoundingMode __r(RoundingMode::Upward);
-    ASSERT_FALSE(fenv_is_round_to_zero());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_to_zero());
   }
   {
     ForceRoundingMode __r(RoundingMode::Downward);
-    ASSERT_FALSE(fenv_is_round_to_zero());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_to_zero());
   }
   {
     ForceRoundingMode __r(RoundingMode::Nearest);
-    ASSERT_FALSE(fenv_is_round_to_zero());
+    if (__r.success)
+      ASSERT_FALSE(fenv_is_round_to_zero());
   }
   {
     ForceRoundingMode __r(RoundingMode::TowardZero);
-    ASSERT_TRUE(fenv_is_round_to_zero());
+    if (__r.success)
+      ASSERT_TRUE(fenv_is_round_to_zero());
   }
 }
 
@@ -99,18 +115,22 @@ TEST(LlvmLibcFEnvImplTest, QuickGetRoundTest) {
   using __llvm_libc::fputil::quick_get_round;
   {
     ForceRoundingMode __r(RoundingMode::Upward);
-    ASSERT_EQ(quick_get_round(), FE_UPWARD);
+    if (__r.success)
+      ASSERT_EQ(quick_get_round(), FE_UPWARD);
   }
   {
     ForceRoundingMode __r(RoundingMode::Downward);
-    ASSERT_EQ(quick_get_round(), FE_DOWNWARD);
+    if (__r.success)
+      ASSERT_EQ(quick_get_round(), FE_DOWNWARD);
   }
   {
     ForceRoundingMode __r(RoundingMode::Nearest);
-    ASSERT_EQ(quick_get_round(), FE_TONEAREST);
+    if (__r.success)
+      ASSERT_EQ(quick_get_round(), FE_TONEAREST);
   }
   {
     ForceRoundingMode __r(RoundingMode::TowardZero);
-    ASSERT_EQ(quick_get_round(), FE_TOWARDZERO);
+    if (__r.success)
+      ASSERT_EQ(quick_get_round(), FE_TOWARDZERO);
   }
 }

diff  --git a/libc/test/src/fenv/CMakeLists.txt b/libc/test/src/fenv/CMakeLists.txt
index 11179cc88c380..d7b9104cf8304 100644
--- a/libc/test/src/fenv/CMakeLists.txt
+++ b/libc/test/src/fenv/CMakeLists.txt
@@ -94,6 +94,7 @@ if (NOT (LLVM_USE_SANITIZER OR (${LIBC_TARGET_OS} STREQUAL "windows")
   # and MacOS.
   add_fp_unittest(
     enabled_exceptions_test
+    UNIT_TEST_ONLY
     SUITE
       libc_fenv_unittests
     SRCS
@@ -110,6 +111,7 @@ if (NOT (LLVM_USE_SANITIZER OR (${LIBC_TARGET_OS} STREQUAL "windows")
 
   add_fp_unittest(
     feholdexcept_test
+    UNIT_TEST_ONLY
     SUITE
       libc_fenv_unittests
     SRCS

diff  --git a/libc/test/src/math/SqrtTest.h b/libc/test/src/math/SqrtTest.h
index dbac32581a58b..f73a14ac4c19d 100644
--- a/libc/test/src/math/SqrtTest.h
+++ b/libc/test/src/math/SqrtTest.h
@@ -41,15 +41,15 @@ template <typename T> class SqrtTest : public __llvm_libc::testing::Test {
     for (UIntType mant = 1; mant < HIDDEN_BIT; mant <<= 1) {
       FPBits denormal(T(0.0));
       denormal.set_mantissa(mant);
-
-      test_all_rounding_modes(func, T(denormal));
+      T x = T(denormal);
+      EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sqrt, x, func(x), 0.5);
     }
 
     constexpr UIntType COUNT = 200'001;
     constexpr UIntType STEP = HIDDEN_BIT / COUNT;
     for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
       T x = __llvm_libc::cpp::bit_cast<T>(v);
-      test_all_rounding_modes(func, x);
+      EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sqrt, x, func(x), 0.5);
     }
   }
 
@@ -61,27 +61,9 @@ template <typename T> class SqrtTest : public __llvm_libc::testing::Test {
       if (isnan(x) || (x < 0)) {
         continue;
       }
-      test_all_rounding_modes(func, x);
+      EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sqrt, x, func(x), 0.5);
     }
   }
-
-  void test_all_rounding_modes(SqrtFunc func, T x) {
-    mpfr::ForceRoundingMode r1(mpfr::RoundingMode::Nearest);
-    EXPECT_MPFR_MATCH(mpfr::Operation::Sqrt, x, func(x), 0.5,
-                      mpfr::RoundingMode::Nearest);
-
-    mpfr::ForceRoundingMode r2(mpfr::RoundingMode::Upward);
-    EXPECT_MPFR_MATCH(mpfr::Operation::Sqrt, x, func(x), 0.5,
-                      mpfr::RoundingMode::Upward);
-
-    mpfr::ForceRoundingMode r3(mpfr::RoundingMode::Downward);
-    EXPECT_MPFR_MATCH(mpfr::Operation::Sqrt, x, func(x), 0.5,
-                      mpfr::RoundingMode::Downward);
-
-    mpfr::ForceRoundingMode r4(mpfr::RoundingMode::TowardZero);
-    EXPECT_MPFR_MATCH(mpfr::Operation::Sqrt, x, func(x), 0.5,
-                      mpfr::RoundingMode::TowardZero);
-  }
 };
 
 #define LIST_SQRT_TESTS(T, func)                                               \

diff  --git a/libc/test/src/math/exhaustive/acosf_test.cpp b/libc/test/src/math/exhaustive/acosf_test.cpp
index c6e15841118ef..66970744b5daa 100644
--- a/libc/test/src/math/exhaustive/acosf_test.cpp
+++ b/libc/test/src/math/exhaustive/acosf_test.cpp
@@ -21,6 +21,8 @@ struct LlvmLibcAcosfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/acoshf_test.cpp b/libc/test/src/math/exhaustive/acoshf_test.cpp
index 01f6e2db18671..6f1196292e278 100644
--- a/libc/test/src/math/exhaustive/acoshf_test.cpp
+++ b/libc/test/src/math/exhaustive/acoshf_test.cpp
@@ -21,6 +21,8 @@ struct LlvmLibcAcoshfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/asinf_test.cpp b/libc/test/src/math/exhaustive/asinf_test.cpp
index 6baa03ad33cd9..4296259f08211 100644
--- a/libc/test/src/math/exhaustive/asinf_test.cpp
+++ b/libc/test/src/math/exhaustive/asinf_test.cpp
@@ -21,6 +21,8 @@ struct LlvmLibcAsinfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/asinhf_test.cpp b/libc/test/src/math/exhaustive/asinhf_test.cpp
index 3fe506f1189be..296e42c0d25d5 100644
--- a/libc/test/src/math/exhaustive/asinhf_test.cpp
+++ b/libc/test/src/math/exhaustive/asinhf_test.cpp
@@ -21,6 +21,8 @@ struct LlvmLibcAsinhfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/atanf_test.cpp b/libc/test/src/math/exhaustive/atanf_test.cpp
index b4bb112c12475..c2a1055ac4edf 100644
--- a/libc/test/src/math/exhaustive/atanf_test.cpp
+++ b/libc/test/src/math/exhaustive/atanf_test.cpp
@@ -21,6 +21,8 @@ struct LlvmLibcAtanfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/atanhf_test.cpp b/libc/test/src/math/exhaustive/atanhf_test.cpp
index 9e0f49f66c0a7..b4746a8349c62 100644
--- a/libc/test/src/math/exhaustive/atanhf_test.cpp
+++ b/libc/test/src/math/exhaustive/atanhf_test.cpp
@@ -21,6 +21,8 @@ struct LlvmLibcAtanhfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/cosf_test.cpp b/libc/test/src/math/exhaustive/cosf_test.cpp
index b78c24664bad2..67bd0c5140843 100644
--- a/libc/test/src/math/exhaustive/cosf_test.cpp
+++ b/libc/test/src/math/exhaustive/cosf_test.cpp
@@ -22,6 +22,8 @@ struct LlvmLibcCosfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/coshf_test.cpp b/libc/test/src/math/exhaustive/coshf_test.cpp
index bff971bf5d03d..ce7a000d98477 100644
--- a/libc/test/src/math/exhaustive/coshf_test.cpp
+++ b/libc/test/src/math/exhaustive/coshf_test.cpp
@@ -22,6 +22,8 @@ struct LlvmLibcCoshfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/exp10f_test.cpp b/libc/test/src/math/exhaustive/exp10f_test.cpp
index 4b26dfa256aa5..67f9514b358a9 100644
--- a/libc/test/src/math/exhaustive/exp10f_test.cpp
+++ b/libc/test/src/math/exhaustive/exp10f_test.cpp
@@ -22,6 +22,8 @@ struct LlvmLibcExp10fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/exp2f_test.cpp b/libc/test/src/math/exhaustive/exp2f_test.cpp
index 49156f3388143..de8b230e9f91b 100644
--- a/libc/test/src/math/exhaustive/exp2f_test.cpp
+++ b/libc/test/src/math/exhaustive/exp2f_test.cpp
@@ -20,6 +20,8 @@ struct LlvmLibcExp2fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/expf_test.cpp b/libc/test/src/math/exhaustive/expf_test.cpp
index 36f3044ee0908..64bf814229b39 100644
--- a/libc/test/src/math/exhaustive/expf_test.cpp
+++ b/libc/test/src/math/exhaustive/expf_test.cpp
@@ -22,6 +22,8 @@ struct LlvmLibcExpfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/expm1f_test.cpp b/libc/test/src/math/exhaustive/expm1f_test.cpp
index 0434a08e52903..42225ea804b6a 100644
--- a/libc/test/src/math/exhaustive/expm1f_test.cpp
+++ b/libc/test/src/math/exhaustive/expm1f_test.cpp
@@ -21,6 +21,8 @@ namespace mpfr = __llvm_libc::testing::mpfr;
 struct LlvmLibcExpm1fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
+    if (!r.success)
+      return true;
     mpfr::ForceRoundingMode r(rounding);
     uint32_t bits = stop;
     bool result = true;

diff  --git a/libc/test/src/math/exhaustive/hypotf_test.cpp b/libc/test/src/math/exhaustive/hypotf_test.cpp
index c8446688dc052..8463f88c7f26c 100644
--- a/libc/test/src/math/exhaustive/hypotf_test.cpp
+++ b/libc/test/src/math/exhaustive/hypotf_test.cpp
@@ -25,6 +25,8 @@ struct LlvmLibcHypotfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
     constexpr uint32_t Y_STOP = (48U + 127U) << 23;
 
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t xbits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/log10f_test.cpp b/libc/test/src/math/exhaustive/log10f_test.cpp
index 0cdfc3e96449a..58f6ecb513a0f 100644
--- a/libc/test/src/math/exhaustive/log10f_test.cpp
+++ b/libc/test/src/math/exhaustive/log10f_test.cpp
@@ -20,6 +20,8 @@ struct LlvmLibcLog10fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/log1pf_test.cpp b/libc/test/src/math/exhaustive/log1pf_test.cpp
index ab3bd27bdd8c3..88944d5c7f499 100644
--- a/libc/test/src/math/exhaustive/log1pf_test.cpp
+++ b/libc/test/src/math/exhaustive/log1pf_test.cpp
@@ -20,6 +20,8 @@ struct LlvmLibcLog1pfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/log2f_test.cpp b/libc/test/src/math/exhaustive/log2f_test.cpp
index c86b9995ef90a..fb674ffa7cb07 100644
--- a/libc/test/src/math/exhaustive/log2f_test.cpp
+++ b/libc/test/src/math/exhaustive/log2f_test.cpp
@@ -20,6 +20,8 @@ struct LlvmLibcLog2fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/logf_test.cpp b/libc/test/src/math/exhaustive/logf_test.cpp
index c9327985e8f15..e67d6ce74ed6f 100644
--- a/libc/test/src/math/exhaustive/logf_test.cpp
+++ b/libc/test/src/math/exhaustive/logf_test.cpp
@@ -20,6 +20,8 @@ struct LlvmLibcLogfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/sincosf_test.cpp b/libc/test/src/math/exhaustive/sincosf_test.cpp
index 6a1006f3d5d54..ecda2cbbf57f8 100644
--- a/libc/test/src/math/exhaustive/sincosf_test.cpp
+++ b/libc/test/src/math/exhaustive/sincosf_test.cpp
@@ -22,6 +22,8 @@ struct LlvmLibcSinCosfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/sinf_test.cpp b/libc/test/src/math/exhaustive/sinf_test.cpp
index 67188034c057b..4749ef68636b8 100644
--- a/libc/test/src/math/exhaustive/sinf_test.cpp
+++ b/libc/test/src/math/exhaustive/sinf_test.cpp
@@ -22,6 +22,8 @@ struct LlvmLibcSinfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/sinhf_test.cpp b/libc/test/src/math/exhaustive/sinhf_test.cpp
index 05328ecf2a7af..a2fa540a98907 100644
--- a/libc/test/src/math/exhaustive/sinhf_test.cpp
+++ b/libc/test/src/math/exhaustive/sinhf_test.cpp
@@ -22,6 +22,8 @@ struct LlvmLibcSinhfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/exhaustive/tanf_test.cpp b/libc/test/src/math/exhaustive/tanf_test.cpp
index a189cb897b74d..3597517de3d9b 100644
--- a/libc/test/src/math/exhaustive/tanf_test.cpp
+++ b/libc/test/src/math/exhaustive/tanf_test.cpp
@@ -25,6 +25,8 @@ struct LlvmLibcTanfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     int tol = TOLERANCE;

diff  --git a/libc/test/src/math/exhaustive/tanhf_test.cpp b/libc/test/src/math/exhaustive/tanhf_test.cpp
index 0a0607a6a1875..c7bb4e8e112e3 100644
--- a/libc/test/src/math/exhaustive/tanhf_test.cpp
+++ b/libc/test/src/math/exhaustive/tanhf_test.cpp
@@ -21,6 +21,8 @@ struct LlvmLibcTanhfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
   bool check(uint32_t start, uint32_t stop,
              mpfr::RoundingMode rounding) override {
     mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
     uint32_t bits = start;
     bool result = true;
     do {

diff  --git a/libc/test/src/math/log10_test.cpp b/libc/test/src/math/log10_test.cpp
index bd50f57bfcefb..ea9d212b05462 100644
--- a/libc/test/src/math/log10_test.cpp
+++ b/libc/test/src/math/log10_test.cpp
@@ -87,6 +87,8 @@ TEST(LlvmLibcLog10Test, InDoubleRange) {
 
   auto test = [&](mpfr::RoundingMode rounding_mode) {
     mpfr::ForceRoundingMode __r(rounding_mode);
+    if (!__r.success)
+      return;
     uint64_t fails = 0;
     uint64_t count = 0;
     uint64_t cc = 0;

diff  --git a/libc/test/src/math/log1p_test.cpp b/libc/test/src/math/log1p_test.cpp
index f57b4f98c66bb..c128c5e6c918f 100644
--- a/libc/test/src/math/log1p_test.cpp
+++ b/libc/test/src/math/log1p_test.cpp
@@ -86,6 +86,9 @@ TEST(LlvmLibcLog1pTest, InDoubleRange) {
   auto test = [&](uint64_t start, uint64_t stop,
                   mpfr::RoundingMode rounding_mode) {
     mpfr::ForceRoundingMode __r(rounding_mode);
+    if (!__r.success)
+      return;
+
     uint64_t fails = 0;
     uint64_t count = 0;
     uint64_t cc = 0;

diff  --git a/libc/test/src/math/log2_test.cpp b/libc/test/src/math/log2_test.cpp
index dfc56ff2dcf44..c4756875d6a54 100644
--- a/libc/test/src/math/log2_test.cpp
+++ b/libc/test/src/math/log2_test.cpp
@@ -87,6 +87,9 @@ TEST(LlvmLibcLog2Test, InDoubleRange) {
 
   auto test = [&](mpfr::RoundingMode rounding_mode) {
     mpfr::ForceRoundingMode __r(rounding_mode);
+    if (!__r.success)
+      return;
+
     uint64_t fails = 0;
     uint64_t count = 0;
     uint64_t cc = 0;

diff  --git a/libc/test/src/math/log_test.cpp b/libc/test/src/math/log_test.cpp
index 230deffedddb8..5b662534bbf58 100644
--- a/libc/test/src/math/log_test.cpp
+++ b/libc/test/src/math/log_test.cpp
@@ -87,6 +87,9 @@ TEST(LlvmLibcLogTest, InDoubleRange) {
 
   auto test = [&](mpfr::RoundingMode rounding_mode) {
     mpfr::ForceRoundingMode __r(rounding_mode);
+    if (!__r.success)
+      return;
+
     uint64_t fails = 0;
     uint64_t count = 0;
     uint64_t cc = 0;

diff  --git a/libc/test/src/math/sincosf_test.cpp b/libc/test/src/math/sincosf_test.cpp
index 1c1d878c7db07..3a5bdd12fbc38 100644
--- a/libc/test/src/math/sincosf_test.cpp
+++ b/libc/test/src/math/sincosf_test.cpp
@@ -61,32 +61,40 @@ TEST(LlvmLibcSinCosfTest, SpecialNumbers) {
     namespace mpfr = __llvm_libc::testing::mpfr;                               \
                                                                                \
     mpfr::ForceRoundingMode __r1(mpfr::RoundingMode::Nearest);                 \
-    __llvm_libc::sincosf(input, &sin, &cos);                                   \
-    EXPECT_MPFR_MATCH(mpfr::Operation::Sin, input, sin, 0.5,                   \
-                      mpfr::RoundingMode::Nearest);                            \
-    EXPECT_MPFR_MATCH(mpfr::Operation::Cos, input, cos, 0.5,                   \
-                      mpfr::RoundingMode::Nearest);                            \
+    if (__r1.success) {                                                        \
+      __llvm_libc::sincosf(input, &sin, &cos);                                 \
+      EXPECT_MPFR_MATCH(mpfr::Operation::Sin, input, sin, 0.5,                 \
+                        mpfr::RoundingMode::Nearest);                          \
+      EXPECT_MPFR_MATCH(mpfr::Operation::Cos, input, cos, 0.5,                 \
+                        mpfr::RoundingMode::Nearest);                          \
+    }                                                                          \
                                                                                \
     mpfr::ForceRoundingMode __r2(mpfr::RoundingMode::Upward);                  \
-    __llvm_libc::sincosf(input, &sin, &cos);                                   \
-    EXPECT_MPFR_MATCH(mpfr::Operation::Sin, input, sin, 0.5,                   \
-                      mpfr::RoundingMode::Upward);                             \
-    EXPECT_MPFR_MATCH(mpfr::Operation::Cos, input, cos, 0.5,                   \
-                      mpfr::RoundingMode::Upward);                             \
+    if (__r2.success) {                                                        \
+      __llvm_libc::sincosf(input, &sin, &cos);                                 \
+      EXPECT_MPFR_MATCH(mpfr::Operation::Sin, input, sin, 0.5,                 \
+                        mpfr::RoundingMode::Upward);                           \
+      EXPECT_MPFR_MATCH(mpfr::Operation::Cos, input, cos, 0.5,                 \
+                        mpfr::RoundingMode::Upward);                           \
+    }                                                                          \
                                                                                \
     mpfr::ForceRoundingMode __r3(mpfr::RoundingMode::Downward);                \
-    __llvm_libc::sincosf(input, &sin, &cos);                                   \
-    EXPECT_MPFR_MATCH(mpfr::Operation::Sin, input, sin, 0.5,                   \
-                      mpfr::RoundingMode::Downward);                           \
-    EXPECT_MPFR_MATCH(mpfr::Operation::Cos, input, cos, 0.5,                   \
-                      mpfr::RoundingMode::Downward);                           \
+    if (__r3.success) {                                                        \
+      __llvm_libc::sincosf(input, &sin, &cos);                                 \
+      EXPECT_MPFR_MATCH(mpfr::Operation::Sin, input, sin, 0.5,                 \
+                        mpfr::RoundingMode::Downward);                         \
+      EXPECT_MPFR_MATCH(mpfr::Operation::Cos, input, cos, 0.5,                 \
+                        mpfr::RoundingMode::Downward);                         \
+    }                                                                          \
                                                                                \
     mpfr::ForceRoundingMode __r4(mpfr::RoundingMode::TowardZero);              \
-    __llvm_libc::sincosf(input, &sin, &cos);                                   \
-    EXPECT_MPFR_MATCH(mpfr::Operation::Sin, input, sin, 0.5,                   \
-                      mpfr::RoundingMode::TowardZero);                         \
-    EXPECT_MPFR_MATCH(mpfr::Operation::Cos, input, cos, 0.5,                   \
-                      mpfr::RoundingMode::TowardZero);                         \
+    if (__r4.success) {                                                        \
+      __llvm_libc::sincosf(input, &sin, &cos);                                 \
+      EXPECT_MPFR_MATCH(mpfr::Operation::Sin, input, sin, 0.5,                 \
+                        mpfr::RoundingMode::TowardZero);                       \
+      EXPECT_MPFR_MATCH(mpfr::Operation::Cos, input, cos, 0.5,                 \
+                        mpfr::RoundingMode::TowardZero);                       \
+    }                                                                          \
   }
 
 TEST(LlvmLibcSinCosfTest, InFloatRange) {

diff  --git a/libc/test/src/stdio/sprintf_test.cpp b/libc/test/src/stdio/sprintf_test.cpp
index 9fb7705334046..e5552742207e4 100644
--- a/libc/test/src/stdio/sprintf_test.cpp
+++ b/libc/test/src/stdio/sprintf_test.cpp
@@ -24,6 +24,9 @@ class LlvmLibcSPrintfTest : public __llvm_libc::testing::Test {
   int written;
 };
 
+using __llvm_libc::fputil::testing::ForceRoundingMode;
+using __llvm_libc::fputil::testing::RoundingMode;
+
 // Subtract 1 from sizeof(expected_str) to account for the null byte.
 #define ASSERT_STREQ_LEN(actual_written, actual_str, expected_str)             \
   EXPECT_EQ(actual_written, static_cast<int>(sizeof(expected_str) - 1));       \
@@ -505,8 +508,7 @@ TEST(LlvmLibcSPrintfTest, OctConv) {
 #ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
 
 TEST_F(LlvmLibcSPrintfTest, FloatHexExpConv) {
-  __llvm_libc::fputil::testing::ForceRoundingMode r(
-      __llvm_libc::fputil::testing::RoundingMode::Nearest);
+  ForceRoundingMode r(RoundingMode::Nearest);
   double inf = __llvm_libc::fputil::FPBits<double>::inf().get_val();
   double nan = __llvm_libc::fputil::FPBits<double>::build_nan(1);
 
@@ -705,10 +707,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatHexExpConv) {
 
   // Rounding Mode Tests.
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Nearest);
-
+  if (ForceRoundingMode r(RoundingMode::Nearest); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1a", 0x1.08p0);
     ASSERT_STREQ_LEN(written, buff, "0x1.0p+0");
 
@@ -734,10 +733,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatHexExpConv) {
     ASSERT_STREQ_LEN(written, buff, "-0x1.1p+0");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Upward);
-
+  if (ForceRoundingMode r(RoundingMode::Upward); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1a", 0x1.08p0);
     ASSERT_STREQ_LEN(written, buff, "0x1.1p+0");
 
@@ -763,10 +759,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatHexExpConv) {
     ASSERT_STREQ_LEN(written, buff, "-0x1.1p+0");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Downward);
-
+  if (ForceRoundingMode r(RoundingMode::Downward); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1a", 0x1.08p0);
     ASSERT_STREQ_LEN(written, buff, "0x1.0p+0");
 
@@ -792,10 +785,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatHexExpConv) {
     ASSERT_STREQ_LEN(written, buff, "-0x1.2p+0");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::TowardZero);
-
+  if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1a", 0x1.08p0);
     ASSERT_STREQ_LEN(written, buff, "0x1.0p+0");
 
@@ -866,8 +856,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatHexExpConv) {
 }
 
 TEST_F(LlvmLibcSPrintfTest, FloatDecimalConv) {
-  __llvm_libc::fputil::testing::ForceRoundingMode r(
-      __llvm_libc::fputil::testing::RoundingMode::Nearest);
+  ForceRoundingMode r(RoundingMode::Nearest);
   double inf = __llvm_libc::fputil::FPBits<double>::inf().get_val();
   double nan = __llvm_libc::fputil::FPBits<double>::build_nan(1);
 
@@ -1340,10 +1329,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalConv) {
 
   // Rounding Mode Tests.
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Nearest);
-
+  if (ForceRoundingMode r(RoundingMode::Nearest); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1f", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.8");
 
@@ -1381,10 +1367,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalConv) {
     ASSERT_STREQ_LEN(written, buff, "-1.9");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Upward);
-
+  if (ForceRoundingMode r(RoundingMode::Upward); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1f", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.8");
 
@@ -1422,10 +1405,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalConv) {
     ASSERT_STREQ_LEN(written, buff, "-1.8");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Downward);
-
+  if (ForceRoundingMode r(RoundingMode::Downward); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1f", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.7");
 
@@ -1463,10 +1443,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalConv) {
     ASSERT_STREQ_LEN(written, buff, "-1.9");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::TowardZero);
-
+  if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1f", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.7");
 
@@ -1572,8 +1549,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatDecimalConv) {
 }
 
 TEST_F(LlvmLibcSPrintfTest, FloatExponentConv) {
-  __llvm_libc::fputil::testing::ForceRoundingMode r(
-      __llvm_libc::fputil::testing::RoundingMode::Nearest);
+  ForceRoundingMode r(RoundingMode::Nearest);
   double inf = __llvm_libc::fputil::FPBits<double>::inf().get_val();
   double nan = __llvm_libc::fputil::FPBits<double>::build_nan(1);
 
@@ -1926,10 +1902,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatExponentConv) {
 
   // Rounding Mode Tests.
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Nearest);
-
+  if (ForceRoundingMode r(RoundingMode::Nearest); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1e", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.8e+00");
 
@@ -1967,10 +1940,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatExponentConv) {
     ASSERT_STREQ_LEN(written, buff, "-1.9e+00");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Upward);
-
+  if (ForceRoundingMode r(RoundingMode::Upward); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1e", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.8e+00");
 
@@ -2008,10 +1978,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatExponentConv) {
     ASSERT_STREQ_LEN(written, buff, "-1.8e+00");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Downward);
-
+  if (ForceRoundingMode r(RoundingMode::Downward); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1e", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.7e+00");
 
@@ -2049,10 +2016,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatExponentConv) {
     ASSERT_STREQ_LEN(written, buff, "-1.9e+00");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::TowardZero);
-
+  if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) {
     written = __llvm_libc::sprintf(buff, "%.1e", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.7e+00");
 
@@ -2167,8 +2131,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatExponentConv) {
 }
 
 TEST_F(LlvmLibcSPrintfTest, FloatAutoConv) {
-  __llvm_libc::fputil::testing::ForceRoundingMode r(
-      __llvm_libc::fputil::testing::RoundingMode::Nearest);
+  ForceRoundingMode r(RoundingMode::Nearest);
   double inf = __llvm_libc::fputil::FPBits<double>::inf().get_val();
   double nan = __llvm_libc::fputil::FPBits<double>::build_nan(1);
 
@@ -2545,10 +2508,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatAutoConv) {
 
   // Rounding Mode Tests.
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Nearest);
-
+  if (ForceRoundingMode r(RoundingMode::Nearest); r.success) {
     written = __llvm_libc::sprintf(buff, "%.2g", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.8");
 
@@ -2586,10 +2546,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatAutoConv) {
     ASSERT_STREQ_LEN(written, buff, "-1.9");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Upward);
-
+  if (ForceRoundingMode r(RoundingMode::Upward); r.success) {
     written = __llvm_libc::sprintf(buff, "%.2g", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.8");
 
@@ -2627,10 +2584,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatAutoConv) {
     ASSERT_STREQ_LEN(written, buff, "-1.8");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::Downward);
-
+  if (ForceRoundingMode r(RoundingMode::Downward); r.success) {
     written = __llvm_libc::sprintf(buff, "%.2g", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.7");
 
@@ -2668,10 +2622,7 @@ TEST_F(LlvmLibcSPrintfTest, FloatAutoConv) {
     ASSERT_STREQ_LEN(written, buff, "-1.9");
   }
 
-  {
-    __llvm_libc::fputil::testing::ForceRoundingMode r(
-        __llvm_libc::fputil::testing::RoundingMode::TowardZero);
-
+  if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) {
     written = __llvm_libc::sprintf(buff, "%.2g", 1.75);
     ASSERT_STREQ_LEN(written, buff, "1.7");
 

diff  --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h
index 242bc2bcc1a17..968d05d18a9e3 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.h
+++ b/libc/utils/MPFRWrapper/MPFRUtils.h
@@ -354,17 +354,21 @@ template <typename T> bool round_to_long(T x, RoundingMode mode, long &result);
   {                                                                            \
     namespace mpfr = __llvm_libc::testing::mpfr;                               \
     mpfr::ForceRoundingMode __r1(mpfr::RoundingMode::Nearest);                 \
-    EXPECT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                   \
-                      mpfr::RoundingMode::Nearest);                            \
+    if (__r1.success)                                                          \
+      EXPECT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                 \
+                        mpfr::RoundingMode::Nearest);                          \
     mpfr::ForceRoundingMode __r2(mpfr::RoundingMode::Upward);                  \
-    EXPECT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                   \
-                      mpfr::RoundingMode::Upward);                             \
+    if (__r2.success)                                                          \
+      EXPECT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                 \
+                        mpfr::RoundingMode::Upward);                           \
     mpfr::ForceRoundingMode __r3(mpfr::RoundingMode::Downward);                \
-    EXPECT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                   \
-                      mpfr::RoundingMode::Downward);                           \
+    if (__r3.success)                                                          \
+      EXPECT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                 \
+                        mpfr::RoundingMode::Downward);                         \
     mpfr::ForceRoundingMode __r4(mpfr::RoundingMode::TowardZero);              \
-    EXPECT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                   \
-                      mpfr::RoundingMode::TowardZero);                         \
+    if (__r4.success)                                                          \
+      EXPECT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                 \
+                        mpfr::RoundingMode::TowardZero);                       \
   }
 
 #define TEST_MPFR_MATCH_ROUNDING_SILENTLY(op, input, match_value,              \
@@ -393,17 +397,21 @@ template <typename T> bool round_to_long(T x, RoundingMode mode, long &result);
   {                                                                            \
     namespace mpfr = __llvm_libc::testing::mpfr;                               \
     mpfr::ForceRoundingMode __r1(mpfr::RoundingMode::Nearest);                 \
-    ASSERT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                   \
-                      mpfr::RoundingMode::Nearest);                            \
+    if (__r1.success)                                                          \
+      ASSERT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                 \
+                        mpfr::RoundingMode::Nearest);                          \
     mpfr::ForceRoundingMode __r2(mpfr::RoundingMode::Upward);                  \
-    ASSERT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                   \
-                      mpfr::RoundingMode::Upward);                             \
+    if (__r2.success)                                                          \
+      ASSERT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                 \
+                        mpfr::RoundingMode::Upward);                           \
     mpfr::ForceRoundingMode __r3(mpfr::RoundingMode::Downward);                \
-    ASSERT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                   \
-                      mpfr::RoundingMode::Downward);                           \
+    if (__r3.success)                                                          \
+      ASSERT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                 \
+                        mpfr::RoundingMode::Downward);                         \
     mpfr::ForceRoundingMode __r4(mpfr::RoundingMode::TowardZero);              \
-    ASSERT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                   \
-                      mpfr::RoundingMode::TowardZero);                         \
+    if (__r4.success)                                                          \
+      ASSERT_MPFR_MATCH(op, input, match_value, ulp_tolerance,                 \
+                        mpfr::RoundingMode::TowardZero);                       \
   }
 
 #endif // LLVM_LIBC_UTILS_TESTUTILS_MPFRUTILS_H

diff  --git a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel
index 059c988efd1c7..395664eab8f64 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel
@@ -47,6 +47,7 @@ cc_library(
         "//libc:__support_cpp_type_traits",
         "//libc:__support_fputil_fp_bits",
         "//libc:__support_fputil_fpbits_str",
+        "//libc:__support_fputil_rounding_mode",
         "//libc:__support_macros_properties_architectures",
         "//libc:__support_stringutil",
         "//libc:__support_uint128",
@@ -77,6 +78,7 @@ cc_library(
         "//libc:__support_fputil_fenv_impl",
         "//libc:__support_fputil_fp_bits",
         "//libc:__support_fputil_fpbits_str",
+        "//libc:__support_fputil_rounding_mode",
         "//libc:libc_root",
     ],
 )


        


More information about the libc-commits mailing list