xref: /llvm-project/libc/test/src/math/RoundToIntegerTest.h (revision 111b062f63ba52552f41e425449ba1db048dc51a)
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