Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libc / test / src / math / RemQuoTest.h
blob6da0756c3a1b3de2859970bbe100a6e666cb9c8e
1 //===-- Utility class to test different flavors of remquo -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H
10 #define LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H
12 #include "src/__support/FPUtil/BasicOperations.h"
13 #include "src/__support/FPUtil/FPBits.h"
14 #include "test/UnitTest/FPMatcher.h"
15 #include "test/UnitTest/Test.h"
16 #include "utils/MPFRWrapper/MPFRUtils.h"
17 #include <math.h>
19 namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
21 template <typename T>
22 class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
23 using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
24 using UIntType = typename FPBits::UIntType;
26 const T zero = T(LIBC_NAMESPACE::fputil::FPBits<T>::zero());
27 const T neg_zero = T(LIBC_NAMESPACE::fputil::FPBits<T>::neg_zero());
28 const T inf = T(LIBC_NAMESPACE::fputil::FPBits<T>::inf());
29 const T neg_inf = T(LIBC_NAMESPACE::fputil::FPBits<T>::neg_inf());
30 const T nan = T(LIBC_NAMESPACE::fputil::FPBits<T>::build_quiet_nan(1));
32 public:
33 typedef T (*RemQuoFunc)(T, T, int *);
35 void testSpecialNumbers(RemQuoFunc func) {
36 int quotient;
37 T x, y;
39 y = T(1.0);
40 x = inf;
41 EXPECT_FP_EQ(nan, func(x, y, &quotient));
42 x = neg_inf;
43 EXPECT_FP_EQ(nan, func(x, y, &quotient));
45 x = T(1.0);
46 y = zero;
47 EXPECT_FP_EQ(nan, func(x, y, &quotient));
48 y = neg_zero;
49 EXPECT_FP_EQ(nan, func(x, y, &quotient));
51 y = nan;
52 x = T(1.0);
53 EXPECT_FP_EQ(nan, func(x, y, &quotient));
55 y = T(1.0);
56 x = nan;
57 EXPECT_FP_EQ(nan, func(x, y, &quotient));
59 x = nan;
60 y = nan;
61 EXPECT_FP_EQ(nan, func(x, y, &quotient));
63 x = zero;
64 y = T(1.0);
65 EXPECT_FP_EQ(func(x, y, &quotient), zero);
67 x = neg_zero;
68 y = T(1.0);
69 EXPECT_FP_EQ(func(x, y, &quotient), neg_zero);
71 x = T(1.125);
72 y = inf;
73 EXPECT_FP_EQ(func(x, y, &quotient), x);
74 EXPECT_EQ(quotient, 0);
77 void testEqualNumeratorAndDenominator(RemQuoFunc func) {
78 T x = T(1.125), y = T(1.125);
79 int q;
81 // When the remainder is zero, the standard requires it to
82 // have the same sign as x.
84 EXPECT_FP_EQ(func(x, y, &q), zero);
85 EXPECT_EQ(q, 1);
87 EXPECT_FP_EQ(func(x, -y, &q), zero);
88 EXPECT_EQ(q, -1);
90 EXPECT_FP_EQ(func(-x, y, &q), neg_zero);
91 EXPECT_EQ(q, -1);
93 EXPECT_FP_EQ(func(-x, -y, &q), neg_zero);
94 EXPECT_EQ(q, 1);
97 void testSubnormalRange(RemQuoFunc func) {
98 constexpr UIntType COUNT = 100'001;
99 constexpr UIntType STEP =
100 (UIntType(FPBits::MAX_SUBNORMAL) - UIntType(FPBits::MIN_SUBNORMAL)) /
101 COUNT;
102 for (UIntType v = FPBits::MIN_SUBNORMAL, w = FPBits::MAX_SUBNORMAL;
103 v <= FPBits::MAX_SUBNORMAL && w >= FPBits::MIN_SUBNORMAL;
104 v += STEP, w -= STEP) {
105 T x = T(FPBits(v)), y = T(FPBits(w));
106 mpfr::BinaryOutput<T> result;
107 mpfr::BinaryInput<T> input{x, y};
108 result.f = func(x, y, &result.i);
109 ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
113 void testNormalRange(RemQuoFunc func) {
114 constexpr UIntType COUNT = 1'001;
115 constexpr UIntType STEP =
116 (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT;
117 for (UIntType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL;
118 v <= FPBits::MAX_NORMAL && w >= FPBits::MIN_NORMAL;
119 v += STEP, w -= STEP) {
120 T x = T(FPBits(v)), y = T(FPBits(w));
121 mpfr::BinaryOutput<T> result;
122 mpfr::BinaryInput<T> input{x, y};
123 result.f = func(x, y, &result.i);
125 // In normal range on x86 platforms, the long double implicit 1 bit can be
126 // zero making the numbers NaN. Hence we test for them separately.
127 if (isnan(x) || isnan(y)) {
128 ASSERT_FP_EQ(result.f, nan);
129 continue;
132 ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
137 #define LIST_REMQUO_TESTS(T, func) \
138 using LlvmLibcRemQuoTest = RemQuoTestTemplate<T>; \
139 TEST_F(LlvmLibcRemQuoTest, SpecialNumbers) { testSpecialNumbers(&func); } \
140 TEST_F(LlvmLibcRemQuoTest, EqualNumeratorAndDenominator) { \
141 testEqualNumeratorAndDenominator(&func); \
143 TEST_F(LlvmLibcRemQuoTest, SubnormalRange) { testSubnormalRange(&func); } \
144 TEST_F(LlvmLibcRemQuoTest, NormalRange) { testNormalRange(&func); }
146 #endif // LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H