17aeb3804SSiva Chandra Reddy //===-- Utility class to test different flavors of [l|ll]round --*- C++ -*-===// 27aeb3804SSiva Chandra Reddy // 37aeb3804SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47aeb3804SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information. 57aeb3804SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67aeb3804SSiva Chandra Reddy // 77aeb3804SSiva Chandra Reddy //===----------------------------------------------------------------------===// 87aeb3804SSiva Chandra Reddy 97aeb3804SSiva Chandra Reddy #ifndef LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H 107aeb3804SSiva Chandra Reddy #define LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H 117aeb3804SSiva Chandra Reddy 12f50656c5SOverMighty #include "src/__support/CPP/algorithm.h" 13ffb410d3STue Ly #include "src/__support/FPUtil/FEnvImpl.h" 14c120edc7SMichael Jones #include "src/__support/FPUtil/FPBits.h" 15afa6bed8SJoseph Huber #include "src/__support/macros/properties/architectures.h" 16837dab96SRoland McGrath #include "test/UnitTest/FEnvSafeTest.h" 17af1315c2SSiva Chandra Reddy #include "test/UnitTest/FPMatcher.h" 18af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h" 197aeb3804SSiva Chandra Reddy #include "utils/MPFRWrapper/MPFRUtils.h" 207aeb3804SSiva Chandra Reddy 215748ad84Slntue #include "hdr/math_macros.h" 227aeb3804SSiva Chandra Reddy 23b6bc9d72SGuillaume Chatelet namespace mpfr = LIBC_NAMESPACE::testing::mpfr; 24f6b2a222SMichael Jones using LIBC_NAMESPACE::Sign; 257aeb3804SSiva Chandra Reddy 2625226f3eSMichael Jones static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO, 27ff6fd385SSiva Chandra Reddy FE_TONEAREST}; 28ff6fd385SSiva Chandra Reddy 29*111b062fSShourya Goel template <typename FloatType, typename IntType, bool TestModes = false> 30837dab96SRoland McGrath class RoundToIntegerTestTemplate 31837dab96SRoland McGrath : public LIBC_NAMESPACE::testing::FEnvSafeTest { 327aeb3804SSiva Chandra Reddy public: 33*111b062fSShourya Goel typedef IntType (*RoundToIntegerFunc)(FloatType); 347aeb3804SSiva Chandra Reddy 357aeb3804SSiva Chandra Reddy private: 36*111b062fSShourya Goel using FPBits = LIBC_NAMESPACE::fputil::FPBits<FloatType>; 373546f4daSGuillaume Chatelet using StorageType = typename FPBits::StorageType; 387aeb3804SSiva Chandra Reddy 39*111b062fSShourya Goel const FloatType zero = FPBits::zero().get_val(); 40*111b062fSShourya Goel const FloatType neg_zero = FPBits::zero(Sign::NEG).get_val(); 41*111b062fSShourya Goel const FloatType inf = FPBits::inf().get_val(); 42*111b062fSShourya Goel const FloatType neg_inf = FPBits::inf(Sign::NEG).get_val(); 43*111b062fSShourya Goel const FloatType nan = FPBits::quiet_nan().get_val(); 446b02d2f8SGuillaume Chatelet 456b02d2f8SGuillaume Chatelet static constexpr StorageType MAX_NORMAL = FPBits::max_normal().uintval(); 466b02d2f8SGuillaume Chatelet static constexpr StorageType MIN_NORMAL = FPBits::min_normal().uintval(); 476b02d2f8SGuillaume Chatelet static constexpr StorageType MAX_SUBNORMAL = 486b02d2f8SGuillaume Chatelet FPBits::max_subnormal().uintval(); 496b02d2f8SGuillaume Chatelet static constexpr StorageType MIN_SUBNORMAL = 506b02d2f8SGuillaume Chatelet FPBits::min_subnormal().uintval(); 516b02d2f8SGuillaume Chatelet 52*111b062fSShourya Goel static constexpr IntType INTEGER_MIN = IntType(1) 53*111b062fSShourya Goel << (sizeof(IntType) * 8 - 1); 54*111b062fSShourya Goel static constexpr IntType INTEGER_MAX = -(INTEGER_MIN + 1); 557aeb3804SSiva Chandra Reddy 56*111b062fSShourya Goel void test_one_input(RoundToIntegerFunc func, FloatType input, 57*111b062fSShourya Goel IntType expected, bool expectError) { 583eb1e6d8Smichaelrj-google LIBC_NAMESPACE::libc_errno = 0; 59b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 607aeb3804SSiva Chandra Reddy 617aeb3804SSiva Chandra Reddy ASSERT_EQ(func(input), expected); 627aeb3804SSiva Chandra Reddy 63ecfb5d99SMichael Flanders // TODO: Handle the !expectError case. It used to expect 64ecfb5d99SMichael Flanders // 0 for errno and exceptions, but this doesn't hold for 65ecfb5d99SMichael Flanders // all math functions using RoundToInteger test: 66ecfb5d99SMichael Flanders // https://github.com/llvm/llvm-project/pull/88816 677aeb3804SSiva Chandra Reddy if (expectError) { 68ffb410d3STue Ly ASSERT_FP_EXCEPTION(FE_INVALID); 69ffb410d3STue Ly ASSERT_MATH_ERRNO(EDOM); 707aeb3804SSiva Chandra Reddy } 717aeb3804SSiva Chandra Reddy } 727aeb3804SSiva Chandra Reddy 7325226f3eSMichael Jones static inline mpfr::RoundingMode to_mpfr_rounding_mode(int mode) { 74ff6fd385SSiva Chandra Reddy switch (mode) { 75ff6fd385SSiva Chandra Reddy case FE_UPWARD: 76ff6fd385SSiva Chandra Reddy return mpfr::RoundingMode::Upward; 77ff6fd385SSiva Chandra Reddy case FE_DOWNWARD: 78ff6fd385SSiva Chandra Reddy return mpfr::RoundingMode::Downward; 79ff6fd385SSiva Chandra Reddy case FE_TOWARDZERO: 80ff6fd385SSiva Chandra Reddy return mpfr::RoundingMode::TowardZero; 81ff6fd385SSiva Chandra Reddy case FE_TONEAREST: 82ff6fd385SSiva Chandra Reddy return mpfr::RoundingMode::Nearest; 83ff6fd385SSiva Chandra Reddy default: 84ff6fd385SSiva Chandra Reddy __builtin_unreachable(); 85ff6fd385SSiva Chandra Reddy } 86ff6fd385SSiva Chandra Reddy } 87ff6fd385SSiva Chandra Reddy 887aeb3804SSiva Chandra Reddy public: 897aeb3804SSiva Chandra Reddy void SetUp() override { 90837dab96SRoland McGrath LIBC_NAMESPACE::testing::FEnvSafeTest::SetUp(); 91837dab96SRoland McGrath 920f031daeSTue Ly if (math_errhandling & MATH_ERREXCEPT) { 937aeb3804SSiva Chandra Reddy // We will disable all exceptions so that the test will not 947aeb3804SSiva Chandra Reddy // crash with SIGFPE. We can still use fetestexcept to check 957aeb3804SSiva Chandra Reddy // if the appropriate flag was raised. 96b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::disable_except(FE_ALL_EXCEPT); 970f031daeSTue Ly } 987aeb3804SSiva Chandra Reddy } 997aeb3804SSiva Chandra Reddy 10025226f3eSMichael Jones void do_infinity_and_na_n_test(RoundToIntegerFunc func) { 10125226f3eSMichael Jones test_one_input(func, inf, INTEGER_MAX, true); 10225226f3eSMichael Jones test_one_input(func, neg_inf, INTEGER_MIN, true); 103c3228714SGuillaume Chatelet // This is currently never enabled, the 104c3228714SGuillaume Chatelet // LLVM_LIBC_IMPLEMENTATION_DEFINED_TEST_BEHAVIOR CMake option in 105c3228714SGuillaume Chatelet // libc/CMakeLists.txt is not forwarded to C++. 106c3228714SGuillaume Chatelet #if LIBC_COPT_IMPLEMENTATION_DEFINED_TEST_BEHAVIOR 10774ec4679SDominic Chen // Result is not well-defined, we always returns INTEGER_MAX 10825226f3eSMichael Jones test_one_input(func, nan, INTEGER_MAX, true); 109c3228714SGuillaume Chatelet #endif // LIBC_COPT_IMPLEMENTATION_DEFINED_TEST_BEHAVIOR 1107aeb3804SSiva Chandra Reddy } 1117aeb3804SSiva Chandra Reddy 112ff6fd385SSiva Chandra Reddy void testInfinityAndNaN(RoundToIntegerFunc func) { 113ff6fd385SSiva Chandra Reddy if (TestModes) { 11425226f3eSMichael Jones for (int mode : ROUNDING_MODES) { 115b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(mode); 11625226f3eSMichael Jones do_infinity_and_na_n_test(func); 117ff6fd385SSiva Chandra Reddy } 118ff6fd385SSiva Chandra Reddy } else { 11925226f3eSMichael Jones do_infinity_and_na_n_test(func); 120ff6fd385SSiva Chandra Reddy } 121ff6fd385SSiva Chandra Reddy } 122ff6fd385SSiva Chandra Reddy 12325226f3eSMichael Jones void do_round_numbers_test(RoundToIntegerFunc func) { 124*111b062fSShourya Goel test_one_input(func, zero, IntType(0), false); 125*111b062fSShourya Goel test_one_input(func, neg_zero, IntType(0), false); 126*111b062fSShourya Goel test_one_input(func, FloatType(1.0), IntType(1), false); 127*111b062fSShourya Goel test_one_input(func, FloatType(-1.0), IntType(-1), false); 128*111b062fSShourya Goel test_one_input(func, FloatType(10.0), IntType(10), false); 129*111b062fSShourya Goel test_one_input(func, FloatType(-10.0), IntType(-10), false); 130*111b062fSShourya Goel test_one_input(func, FloatType(1234.0), IntType(1234), false); 131*111b062fSShourya Goel test_one_input(func, FloatType(-1234.0), IntType(-1234), false); 1327aeb3804SSiva Chandra Reddy 133678e3ee1SFangrui Song // The rest of this function compares with an equivalent MPFR function 1347aeb3804SSiva Chandra Reddy // which rounds floating point numbers to long values. There is no MPFR 1357aeb3804SSiva Chandra Reddy // function to round to long long or wider integer values. So, we will 136*111b062fSShourya Goel // the remaining tests only if the width of IntType less than equal to that 137*111b062fSShourya Goel // of long. 138*111b062fSShourya Goel if (sizeof(IntType) > sizeof(long)) 1397aeb3804SSiva Chandra Reddy return; 1407aeb3804SSiva Chandra Reddy 141*111b062fSShourya Goel constexpr int EXPONENT_LIMIT = sizeof(IntType) * 8 - 1; 142f50656c5SOverMighty constexpr int BIASED_EXPONENT_LIMIT = EXPONENT_LIMIT + FPBits::EXP_BIAS; 143f50656c5SOverMighty if (BIASED_EXPONENT_LIMIT > FPBits::MAX_BIASED_EXPONENT) 144f50656c5SOverMighty return; 1457aeb3804SSiva Chandra Reddy // We start with 1.0 so that the implicit bit for x86 long doubles 1467aeb3804SSiva Chandra Reddy // is set. 147*111b062fSShourya Goel FPBits bits(FloatType(1.0)); 148f50656c5SOverMighty bits.set_biased_exponent(BIASED_EXPONENT_LIMIT); 14911ec512fSGuillaume Chatelet bits.set_sign(Sign::NEG); 1501c92911eSMichael Jones bits.set_mantissa(0); 1517aeb3804SSiva Chandra Reddy 152*111b062fSShourya Goel FloatType x = bits.get_val(); 15325226f3eSMichael Jones long mpfr_result; 15460509623SSiva Chandra Reddy bool erangeflag = mpfr::round_to_long(x, mpfr_result); 1557aeb3804SSiva Chandra Reddy ASSERT_FALSE(erangeflag); 15625226f3eSMichael Jones test_one_input(func, x, mpfr_result, false); 1577aeb3804SSiva Chandra Reddy } 1587aeb3804SSiva Chandra Reddy 159ff6fd385SSiva Chandra Reddy void testRoundNumbers(RoundToIntegerFunc func) { 160ff6fd385SSiva Chandra Reddy if (TestModes) { 16125226f3eSMichael Jones for (int mode : ROUNDING_MODES) { 162b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(mode); 16325226f3eSMichael Jones do_round_numbers_test(func); 164ff6fd385SSiva Chandra Reddy } 165ff6fd385SSiva Chandra Reddy } else { 16625226f3eSMichael Jones do_round_numbers_test(func); 167ff6fd385SSiva Chandra Reddy } 168ff6fd385SSiva Chandra Reddy } 169ff6fd385SSiva Chandra Reddy 17025226f3eSMichael Jones void do_fractions_test(RoundToIntegerFunc func, int mode) { 171*111b062fSShourya Goel constexpr FloatType FRACTIONS[] = { 172*111b062fSShourya Goel FloatType(0.5), FloatType(-0.5), FloatType(0.115), 173*111b062fSShourya Goel FloatType(-0.115), FloatType(0.715), FloatType(-0.715), 17488f0dc48SOverMighty }; 175*111b062fSShourya Goel for (FloatType x : FRACTIONS) { 17625226f3eSMichael Jones long mpfr_long_result; 177ff6fd385SSiva Chandra Reddy bool erangeflag; 178ff6fd385SSiva Chandra Reddy if (TestModes) 17960509623SSiva Chandra Reddy erangeflag = mpfr::round_to_long(x, to_mpfr_rounding_mode(mode), 18060509623SSiva Chandra Reddy mpfr_long_result); 181ff6fd385SSiva Chandra Reddy else 18260509623SSiva Chandra Reddy erangeflag = mpfr::round_to_long(x, mpfr_long_result); 183ff6fd385SSiva Chandra Reddy ASSERT_FALSE(erangeflag); 184*111b062fSShourya Goel IntType mpfr_result = mpfr_long_result; 18525226f3eSMichael Jones test_one_input(func, x, mpfr_result, false); 186ff6fd385SSiva Chandra Reddy } 187ff6fd385SSiva Chandra Reddy } 188ff6fd385SSiva Chandra Reddy 1897aeb3804SSiva Chandra Reddy void testFractions(RoundToIntegerFunc func) { 190ff6fd385SSiva Chandra Reddy if (TestModes) { 19125226f3eSMichael Jones for (int mode : ROUNDING_MODES) { 192b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(mode); 19325226f3eSMichael Jones do_fractions_test(func, mode); 194ff6fd385SSiva Chandra Reddy } 195ff6fd385SSiva Chandra Reddy } else { 196ff6fd385SSiva Chandra Reddy // Passing 0 for mode has no effect as it is not used in doFractionsTest 197ff6fd385SSiva Chandra Reddy // when `TestModes` is false; 19825226f3eSMichael Jones do_fractions_test(func, 0); 199ff6fd385SSiva Chandra Reddy } 2007aeb3804SSiva Chandra Reddy } 2017aeb3804SSiva Chandra Reddy 2027aeb3804SSiva Chandra Reddy void testIntegerOverflow(RoundToIntegerFunc func) { 2037aeb3804SSiva Chandra Reddy // This function compares with an equivalent MPFR function which rounds 2047aeb3804SSiva Chandra Reddy // floating point numbers to long values. There is no MPFR function to 2057aeb3804SSiva Chandra Reddy // round to long long or wider integer values. So, we will peform the 206*111b062fSShourya Goel // comparisons in this function only if the width of IntType less than equal 207*111b062fSShourya Goel // to that of long. 208*111b062fSShourya Goel if (sizeof(IntType) > sizeof(long)) 2097aeb3804SSiva Chandra Reddy return; 2107aeb3804SSiva Chandra Reddy 211*111b062fSShourya Goel constexpr int EXPONENT_LIMIT = sizeof(IntType) * 8 - 1; 212f50656c5SOverMighty constexpr int BIASED_EXPONENT_LIMIT = EXPONENT_LIMIT + FPBits::EXP_BIAS; 213f50656c5SOverMighty if (BIASED_EXPONENT_LIMIT > FPBits::MAX_BIASED_EXPONENT) 214f50656c5SOverMighty return; 2157aeb3804SSiva Chandra Reddy // We start with 1.0 so that the implicit bit for x86 long doubles 2167aeb3804SSiva Chandra Reddy // is set. 217*111b062fSShourya Goel FPBits bits(FloatType(1.0)); 218f50656c5SOverMighty bits.set_biased_exponent(BIASED_EXPONENT_LIMIT); 21911ec512fSGuillaume Chatelet bits.set_sign(Sign::NEG); 2203546f4daSGuillaume Chatelet bits.set_mantissa(FPBits::FRACTION_MASK); 2217aeb3804SSiva Chandra Reddy 222*111b062fSShourya Goel FloatType x = bits.get_val(); 223ff6fd385SSiva Chandra Reddy if (TestModes) { 22425226f3eSMichael Jones for (int m : ROUNDING_MODES) { 225b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(m); 22625226f3eSMichael Jones long mpfr_long_result; 227ff6fd385SSiva Chandra Reddy bool erangeflag = 22860509623SSiva Chandra Reddy mpfr::round_to_long(x, to_mpfr_rounding_mode(m), mpfr_long_result); 2297aeb3804SSiva Chandra Reddy ASSERT_TRUE(erangeflag); 23025226f3eSMichael Jones test_one_input(func, x, INTEGER_MIN, true); 2317aeb3804SSiva Chandra Reddy } 232ff6fd385SSiva Chandra Reddy } else { 23325226f3eSMichael Jones long mpfr_long_result; 23460509623SSiva Chandra Reddy bool erangeflag = mpfr::round_to_long(x, mpfr_long_result); 235ff6fd385SSiva Chandra Reddy ASSERT_TRUE(erangeflag); 23625226f3eSMichael Jones test_one_input(func, x, INTEGER_MIN, true); 237ff6fd385SSiva Chandra Reddy } 238ff6fd385SSiva Chandra Reddy } 2397aeb3804SSiva Chandra Reddy 2407aeb3804SSiva Chandra Reddy void testSubnormalRange(RoundToIntegerFunc func) { 241f50656c5SOverMighty constexpr int COUNT = 1'000'001; 242f50656c5SOverMighty constexpr StorageType STEP = LIBC_NAMESPACE::cpp::max( 243f50656c5SOverMighty static_cast<StorageType>((MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT), 244f50656c5SOverMighty StorageType(1)); 2456b02d2f8SGuillaume Chatelet for (StorageType i = MIN_SUBNORMAL; i <= MAX_SUBNORMAL; i += STEP) { 246*111b062fSShourya Goel FloatType x = FPBits(i).get_val(); 247*111b062fSShourya Goel if (x == FloatType(0.0)) 248ff6fd385SSiva Chandra Reddy continue; 2497aeb3804SSiva Chandra Reddy // All subnormal numbers should round to zero. 250ff6fd385SSiva Chandra Reddy if (TestModes) { 251ff6fd385SSiva Chandra Reddy if (x > 0) { 252b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(FE_UPWARD); 253*111b062fSShourya Goel test_one_input(func, x, IntType(1), false); 254b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(FE_DOWNWARD); 255*111b062fSShourya Goel test_one_input(func, x, IntType(0), false); 256b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(FE_TOWARDZERO); 257*111b062fSShourya Goel test_one_input(func, x, IntType(0), false); 258b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(FE_TONEAREST); 259*111b062fSShourya Goel test_one_input(func, x, IntType(0), false); 260ff6fd385SSiva Chandra Reddy } else { 261b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(FE_UPWARD); 262*111b062fSShourya Goel test_one_input(func, x, IntType(0), false); 263b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(FE_DOWNWARD); 264*111b062fSShourya Goel test_one_input(func, x, IntType(-1), false); 265b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(FE_TOWARDZERO); 266*111b062fSShourya Goel test_one_input(func, x, IntType(0), false); 267b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(FE_TONEAREST); 268*111b062fSShourya Goel test_one_input(func, x, IntType(0), false); 269ff6fd385SSiva Chandra Reddy } 270ff6fd385SSiva Chandra Reddy } else { 27125226f3eSMichael Jones test_one_input(func, x, 0L, false); 2727aeb3804SSiva Chandra Reddy } 2737aeb3804SSiva Chandra Reddy } 274ff6fd385SSiva Chandra Reddy } 2757aeb3804SSiva Chandra Reddy 2767aeb3804SSiva Chandra Reddy void testNormalRange(RoundToIntegerFunc func) { 2777aeb3804SSiva Chandra Reddy // This function compares with an equivalent MPFR function which rounds 2787aeb3804SSiva Chandra Reddy // floating point numbers to long values. There is no MPFR function to 2797aeb3804SSiva Chandra Reddy // round to long long or wider integer values. So, we will peform the 280*111b062fSShourya Goel // comparisons in this function only if the width of IntType less than equal 281*111b062fSShourya Goel // to that of long. 282*111b062fSShourya Goel if (sizeof(IntType) > sizeof(long)) 2837aeb3804SSiva Chandra Reddy return; 2847aeb3804SSiva Chandra Reddy 285f50656c5SOverMighty constexpr int COUNT = 1'000'001; 286f50656c5SOverMighty constexpr StorageType STEP = LIBC_NAMESPACE::cpp::max( 287f50656c5SOverMighty static_cast<StorageType>((MAX_NORMAL - MIN_NORMAL) / COUNT), 288f50656c5SOverMighty StorageType(1)); 2896b02d2f8SGuillaume Chatelet for (StorageType i = MIN_NORMAL; i <= MAX_NORMAL; i += STEP) { 290f50656c5SOverMighty FPBits xbits(i); 291*111b062fSShourya Goel FloatType x = xbits.get_val(); 2927aeb3804SSiva Chandra Reddy // In normal range on x86 platforms, the long double implicit 1 bit can be 2937aeb3804SSiva Chandra Reddy // zero making the numbers NaN. We will skip them. 294f50656c5SOverMighty if (xbits.is_nan()) 2957aeb3804SSiva Chandra Reddy continue; 2967aeb3804SSiva Chandra Reddy 297ff6fd385SSiva Chandra Reddy if (TestModes) { 29825226f3eSMichael Jones for (int m : ROUNDING_MODES) { 29925226f3eSMichael Jones long mpfr_long_result; 30060509623SSiva Chandra Reddy bool erangeflag = mpfr::round_to_long(x, to_mpfr_rounding_mode(m), 30160509623SSiva Chandra Reddy mpfr_long_result); 302*111b062fSShourya Goel IntType mpfr_result = mpfr_long_result; 303b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::fputil::set_round(m); 304ff6fd385SSiva Chandra Reddy if (erangeflag) 30525226f3eSMichael Jones test_one_input(func, x, x > 0 ? INTEGER_MAX : INTEGER_MIN, true); 306ff6fd385SSiva Chandra Reddy else 30725226f3eSMichael Jones test_one_input(func, x, mpfr_result, false); 308ff6fd385SSiva Chandra Reddy } 309ff6fd385SSiva Chandra Reddy } else { 31025226f3eSMichael Jones long mpfr_long_result; 31160509623SSiva Chandra Reddy bool erangeflag = mpfr::round_to_long(x, mpfr_long_result); 312*111b062fSShourya Goel IntType mpfr_result = mpfr_long_result; 3137aeb3804SSiva Chandra Reddy if (erangeflag) 31425226f3eSMichael Jones test_one_input(func, x, x > 0 ? INTEGER_MAX : INTEGER_MIN, true); 3157aeb3804SSiva Chandra Reddy else 31625226f3eSMichael Jones test_one_input(func, x, mpfr_result, false); 3177aeb3804SSiva Chandra Reddy } 3187aeb3804SSiva Chandra Reddy } 319ff6fd385SSiva Chandra Reddy } 3207aeb3804SSiva Chandra Reddy }; 3217aeb3804SSiva Chandra Reddy 322*111b062fSShourya Goel #define LIST_ROUND_TO_INTEGER_TESTS_HELPER(FloatType, IntType, func, \ 323*111b062fSShourya Goel TestModes) \ 324689de584SMichael Jones using LlvmLibcRoundToIntegerTest = \ 325*111b062fSShourya Goel RoundToIntegerTestTemplate<FloatType, IntType, TestModes>; \ 326689de584SMichael Jones TEST_F(LlvmLibcRoundToIntegerTest, InfinityAndNaN) { \ 327689de584SMichael Jones testInfinityAndNaN(&func); \ 328689de584SMichael Jones } \ 329689de584SMichael Jones TEST_F(LlvmLibcRoundToIntegerTest, RoundNumbers) { \ 330689de584SMichael Jones testRoundNumbers(&func); \ 331689de584SMichael Jones } \ 332689de584SMichael Jones TEST_F(LlvmLibcRoundToIntegerTest, Fractions) { testFractions(&func); } \ 333689de584SMichael Jones TEST_F(LlvmLibcRoundToIntegerTest, IntegerOverflow) { \ 334689de584SMichael Jones testIntegerOverflow(&func); \ 335689de584SMichael Jones } \ 336689de584SMichael Jones TEST_F(LlvmLibcRoundToIntegerTest, SubnormalRange) { \ 337689de584SMichael Jones testSubnormalRange(&func); \ 338689de584SMichael Jones } \ 339689de584SMichael Jones TEST_F(LlvmLibcRoundToIntegerTest, NormalRange) { testNormalRange(&func); } 3407aeb3804SSiva Chandra Reddy 341*111b062fSShourya Goel #define LIST_ROUND_TO_INTEGER_TESTS(FloatType, IntType, func) \ 342*111b062fSShourya Goel LIST_ROUND_TO_INTEGER_TESTS_HELPER(FloatType, IntType, func, false) 343ff6fd385SSiva Chandra Reddy 344*111b062fSShourya Goel #define LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(FloatType, IntType, func) \ 345*111b062fSShourya Goel LIST_ROUND_TO_INTEGER_TESTS_HELPER(FloatType, IntType, func, true) 346ff6fd385SSiva Chandra Reddy 3477aeb3804SSiva Chandra Reddy #endif // LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H 348