[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
This commit is contained in:
Tue Ly 2023-06-14 10:52:23 -04:00
parent a734de6d37
commit 055be3c30c
41 changed files with 230 additions and 188 deletions

View File

@ -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)

View File

@ -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; }

View File

@ -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(

View File

@ -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

View File

@ -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

View File

@ -23,6 +23,7 @@ struct ForceRoundingMode {
int old_rounding_mode;
int rounding_mode;
bool success;
};
template <RoundingMode R> struct ForceRoundingModeTest : ForceRoundingMode {

View File

@ -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}"

View File

@ -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
)

View File

@ -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);
}
}

View File

@ -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

View File

@ -41,15 +41,15 @@ public:
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 @@ public:
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) \

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -24,6 +24,9 @@ protected:
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");

View File

@ -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

View File

@ -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",
],
)