diff --git a/libc/include/llvm-libc-macros/fenv-macros.h b/libc/include/llvm-libc-macros/fenv-macros.h --- 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 --- a/libc/src/__support/FPUtil/FEnvImpl.h +++ b/libc/src/__support/FPUtil/FEnvImpl.h @@ -42,6 +42,8 @@ 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 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 --- a/libc/test/UnitTest/CMakeLists.txt +++ b/libc/test/UnitTest/CMakeLists.txt @@ -110,6 +110,7 @@ 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 --- a/libc/test/UnitTest/FPMatcher.h +++ b/libc/test/UnitTest/FPMatcher.h @@ -164,13 +164,17 @@ 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.h b/libc/test/UnitTest/RoundingModeUtils.h --- a/libc/test/UnitTest/RoundingModeUtils.h +++ b/libc/test/UnitTest/RoundingModeUtils.h @@ -23,6 +23,7 @@ int old_rounding_mode; int rounding_mode; + bool success; }; template struct ForceRoundingModeTest : ForceRoundingMode { diff --git a/libc/test/UnitTest/RoundingModeUtils.cpp b/libc/test/UnitTest/RoundingModeUtils.cpp --- 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 @@ -34,15 +36,19 @@ } 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/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt --- 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 @@ 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 @@ 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 --- 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 @@ 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 --- a/libc/test/src/__support/FPUtil/rounding_mode_test.cpp +++ b/libc/test/src/__support/FPUtil/rounding_mode_test.cpp @@ -19,19 +19,23 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 --- a/libc/test/src/fenv/CMakeLists.txt +++ b/libc/test/src/fenv/CMakeLists.txt @@ -94,6 +94,7 @@ # and MacOS. add_fp_unittest( enabled_exceptions_test + UNIT_TEST_ONLY SUITE libc_fenv_unittests SRCS @@ -110,6 +111,7 @@ 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 --- a/libc/test/src/math/SqrtTest.h +++ b/libc/test/src/math/SqrtTest.h @@ -41,15 +41,15 @@ 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(v); - test_all_rounding_modes(func, x); + EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sqrt, x, func(x), 0.5); } } @@ -61,27 +61,9 @@ 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 --- a/libc/test/src/math/exhaustive/acosf_test.cpp +++ b/libc/test/src/math/exhaustive/acosf_test.cpp @@ -21,6 +21,8 @@ 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 --- a/libc/test/src/math/exhaustive/acoshf_test.cpp +++ b/libc/test/src/math/exhaustive/acoshf_test.cpp @@ -21,6 +21,8 @@ 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 --- a/libc/test/src/math/exhaustive/asinf_test.cpp +++ b/libc/test/src/math/exhaustive/asinf_test.cpp @@ -21,6 +21,8 @@ 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 --- a/libc/test/src/math/exhaustive/asinhf_test.cpp +++ b/libc/test/src/math/exhaustive/asinhf_test.cpp @@ -21,6 +21,8 @@ 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 --- a/libc/test/src/math/exhaustive/atanf_test.cpp +++ b/libc/test/src/math/exhaustive/atanf_test.cpp @@ -21,6 +21,8 @@ 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 --- a/libc/test/src/math/exhaustive/atanhf_test.cpp +++ b/libc/test/src/math/exhaustive/atanhf_test.cpp @@ -21,6 +21,8 @@ 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 --- a/libc/test/src/math/exhaustive/cosf_test.cpp +++ b/libc/test/src/math/exhaustive/cosf_test.cpp @@ -22,6 +22,8 @@ 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 --- a/libc/test/src/math/exhaustive/coshf_test.cpp +++ b/libc/test/src/math/exhaustive/coshf_test.cpp @@ -22,6 +22,8 @@ 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 --- a/libc/test/src/math/exhaustive/exp10f_test.cpp +++ b/libc/test/src/math/exhaustive/exp10f_test.cpp @@ -22,6 +22,8 @@ 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 --- a/libc/test/src/math/exhaustive/exp2f_test.cpp +++ b/libc/test/src/math/exhaustive/exp2f_test.cpp @@ -20,6 +20,8 @@ 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 --- a/libc/test/src/math/exhaustive/expf_test.cpp +++ b/libc/test/src/math/exhaustive/expf_test.cpp @@ -22,6 +22,8 @@ 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 --- a/libc/test/src/math/exhaustive/expm1f_test.cpp +++ b/libc/test/src/math/exhaustive/expm1f_test.cpp @@ -21,6 +21,8 @@ struct LlvmLibcExpm1fExhaustiveTest : public LlvmLibcExhaustiveTest { 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 --- a/libc/test/src/math/exhaustive/hypotf_test.cpp +++ b/libc/test/src/math/exhaustive/hypotf_test.cpp @@ -25,6 +25,8 @@ 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 --- a/libc/test/src/math/exhaustive/log10f_test.cpp +++ b/libc/test/src/math/exhaustive/log10f_test.cpp @@ -20,6 +20,8 @@ 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 --- a/libc/test/src/math/exhaustive/log1pf_test.cpp +++ b/libc/test/src/math/exhaustive/log1pf_test.cpp @@ -20,6 +20,8 @@ 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 --- a/libc/test/src/math/exhaustive/log2f_test.cpp +++ b/libc/test/src/math/exhaustive/log2f_test.cpp @@ -20,6 +20,8 @@ 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 --- a/libc/test/src/math/exhaustive/logf_test.cpp +++ b/libc/test/src/math/exhaustive/logf_test.cpp @@ -20,6 +20,8 @@ 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 --- a/libc/test/src/math/exhaustive/sincosf_test.cpp +++ b/libc/test/src/math/exhaustive/sincosf_test.cpp @@ -22,6 +22,8 @@ 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 --- a/libc/test/src/math/exhaustive/sinf_test.cpp +++ b/libc/test/src/math/exhaustive/sinf_test.cpp @@ -22,6 +22,8 @@ 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 --- a/libc/test/src/math/exhaustive/sinhf_test.cpp +++ b/libc/test/src/math/exhaustive/sinhf_test.cpp @@ -22,6 +22,8 @@ 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 --- a/libc/test/src/math/exhaustive/tanf_test.cpp +++ b/libc/test/src/math/exhaustive/tanf_test.cpp @@ -25,6 +25,8 @@ 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 --- a/libc/test/src/math/exhaustive/tanhf_test.cpp +++ b/libc/test/src/math/exhaustive/tanhf_test.cpp @@ -21,6 +21,8 @@ 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 --- a/libc/test/src/math/log10_test.cpp +++ b/libc/test/src/math/log10_test.cpp @@ -87,6 +87,8 @@ 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 --- a/libc/test/src/math/log1p_test.cpp +++ b/libc/test/src/math/log1p_test.cpp @@ -86,6 +86,9 @@ 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 --- a/libc/test/src/math/log2_test.cpp +++ b/libc/test/src/math/log2_test.cpp @@ -87,6 +87,9 @@ 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 --- a/libc/test/src/math/log_test.cpp +++ b/libc/test/src/math/log_test.cpp @@ -87,6 +87,9 @@ 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 --- a/libc/test/src/math/sincosf_test.cpp +++ b/libc/test/src/math/sincosf_test.cpp @@ -61,32 +61,40 @@ 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 --- a/libc/test/src/stdio/sprintf_test.cpp +++ b/libc/test/src/stdio/sprintf_test.cpp @@ -24,6 +24,9 @@ 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(sizeof(expected_str) - 1)); \ @@ -505,8 +508,7 @@ #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::inf().get_val(); double nan = __llvm_libc::fputil::FPBits::build_nan(1); @@ -705,10 +707,7 @@ // 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 @@ 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 @@ 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 @@ 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, FloatDecimalConv) { - __llvm_libc::fputil::testing::ForceRoundingMode r( - __llvm_libc::fputil::testing::RoundingMode::Nearest); + ForceRoundingMode r(RoundingMode::Nearest); double inf = __llvm_libc::fputil::FPBits::inf().get_val(); double nan = __llvm_libc::fputil::FPBits::build_nan(1); @@ -1340,10 +1329,7 @@ // 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 @@ 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 @@ 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 @@ 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, FloatExponentConv) { - __llvm_libc::fputil::testing::ForceRoundingMode r( - __llvm_libc::fputil::testing::RoundingMode::Nearest); + ForceRoundingMode r(RoundingMode::Nearest); double inf = __llvm_libc::fputil::FPBits::inf().get_val(); double nan = __llvm_libc::fputil::FPBits::build_nan(1); @@ -1926,10 +1902,7 @@ // 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 @@ 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 @@ 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 @@ 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, FloatAutoConv) { - __llvm_libc::fputil::testing::ForceRoundingMode r( - __llvm_libc::fputil::testing::RoundingMode::Nearest); + ForceRoundingMode r(RoundingMode::Nearest); double inf = __llvm_libc::fputil::FPBits::inf().get_val(); double nan = __llvm_libc::fputil::FPBits::build_nan(1); @@ -2545,10 +2508,7 @@ // 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 @@ 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 @@ 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 @@ 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 --- a/libc/utils/MPFRWrapper/MPFRUtils.h +++ b/libc/utils/MPFRWrapper/MPFRUtils.h @@ -354,17 +354,21 @@ { \ 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 @@ { \ 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 --- 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 @@ "//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 @@ "//libc:__support_fputil_fenv_impl", "//libc:__support_fputil_fp_bits", "//libc:__support_fputil_fpbits_str", + "//libc:__support_fputil_rounding_mode", "//libc:libc_root", ], )