1 //===-- Utility class to test fmod special numbers ------------------------===//
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 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H
10 #define LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H
11 
12 #include "src/__support/FPUtil/BasicOperations.h"
13 #include "src/__support/FPUtil/NearestIntegerOperations.h"
14 #include "utils/UnitTest/FPMatcher.h"
15 #include "utils/UnitTest/Test.h"
16 
17 #include <limits>
18 #include <math.h>
19 
20 #define TEST_SPECIAL(x, y, expected, dom_err, expected_exception)              \
21   EXPECT_FP_EQ(expected, f(x, y));                                             \
22   EXPECT_MATH_ERRNO((dom_err) ? EDOM : 0);                                     \
23   EXPECT_FP_EXCEPTION(expected_exception);                                     \
24   __llvm_libc::fputil::clear_except(FE_ALL_EXCEPT)
25 
26 #define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, false, 0)
27 
28 template <typename T> class FmodTest : public __llvm_libc::testing::Test {
29 
30   DECLARE_SPECIAL_CONSTANTS(T)
31 
32 public:
33   typedef T (*FModFunc)(T, T);
34 
testSpecialNumbers(FModFunc f)35   void testSpecialNumbers(FModFunc f) {
36     using nl = std::numeric_limits<T>;
37 
38     // fmod (+0, y) == +0 for y != 0.
39     TEST_SPECIAL(0.0, 3.0, 0.0, false, 0);
40     TEST_SPECIAL(0.0, nl::denorm_min(), 0.0, false, 0);
41     TEST_SPECIAL(0.0, -nl::denorm_min(), 0.0, false, 0);
42     TEST_SPECIAL(0.0, nl::min(), 0.0, false, 0);
43     TEST_SPECIAL(0.0, -nl::min(), 0.0, false, 0);
44     TEST_SPECIAL(0.0, nl::max(), 0.0, false, 0);
45     TEST_SPECIAL(0.0, -nl::max(), 0.0, false, 0);
46 
47     // fmod (-0, y) == -0 for y != 0.
48     TEST_SPECIAL(neg_zero, 3.0, neg_zero, false, 0);
49     TEST_SPECIAL(neg_zero, nl::denorm_min(), neg_zero, false, 0);
50     TEST_SPECIAL(neg_zero, -nl::denorm_min(), neg_zero, false, 0);
51     TEST_SPECIAL(neg_zero, nl::min(), neg_zero, false, 0);
52     TEST_SPECIAL(neg_zero, -nl::min(), neg_zero, false, 0);
53     TEST_SPECIAL(neg_zero, nl::max(), neg_zero, false, 0);
54     TEST_SPECIAL(neg_zero, -nl::max(), neg_zero, false, 0);
55 
56     // fmod (+inf, y) == nl::quiet_NaN() plus invalid exception.
57     TEST_SPECIAL(inf, 3.0, nl::quiet_NaN(), true, FE_INVALID);
58     TEST_SPECIAL(inf, -1.1L, nl::quiet_NaN(), true, FE_INVALID);
59     TEST_SPECIAL(inf, 0.0, nl::quiet_NaN(), true, FE_INVALID);
60     TEST_SPECIAL(inf, neg_zero, nl::quiet_NaN(), true, FE_INVALID);
61     TEST_SPECIAL(inf, nl::denorm_min(), nl::quiet_NaN(), true, FE_INVALID);
62     TEST_SPECIAL(inf, nl::min(), nl::quiet_NaN(), true, FE_INVALID);
63     TEST_SPECIAL(inf, nl::max(), nl::quiet_NaN(), true, FE_INVALID);
64     TEST_SPECIAL(inf, inf, nl::quiet_NaN(), true, FE_INVALID);
65     TEST_SPECIAL(inf, neg_inf, nl::quiet_NaN(), true, FE_INVALID);
66 
67     // fmod (-inf, y) == nl::quiet_NaN() plus invalid exception.
68     TEST_SPECIAL(neg_inf, 3.0, nl::quiet_NaN(), true, FE_INVALID);
69     TEST_SPECIAL(neg_inf, -1.1L, nl::quiet_NaN(), true, FE_INVALID);
70     TEST_SPECIAL(neg_inf, 0.0, nl::quiet_NaN(), true, FE_INVALID);
71     TEST_SPECIAL(neg_inf, neg_zero, nl::quiet_NaN(), true, FE_INVALID);
72     TEST_SPECIAL(neg_inf, nl::denorm_min(), nl::quiet_NaN(), true, FE_INVALID);
73     TEST_SPECIAL(neg_inf, nl::min(), nl::quiet_NaN(), true, FE_INVALID);
74     TEST_SPECIAL(neg_inf, nl::max(), nl::quiet_NaN(), true, FE_INVALID);
75     TEST_SPECIAL(neg_inf, inf, nl::quiet_NaN(), true, FE_INVALID);
76     TEST_SPECIAL(neg_inf, neg_inf, nl::quiet_NaN(), true, FE_INVALID);
77 
78     // fmod (x, +0) == nl::quiet_NaN() plus invalid exception.
79     TEST_SPECIAL(3.0, 0.0, nl::quiet_NaN(), true, FE_INVALID);
80     TEST_SPECIAL(-1.1L, 0.0, nl::quiet_NaN(), true, FE_INVALID);
81     TEST_SPECIAL(0.0, 0.0, nl::quiet_NaN(), true, FE_INVALID);
82     TEST_SPECIAL(neg_zero, 0.0, nl::quiet_NaN(), true, FE_INVALID);
83     TEST_SPECIAL(nl::denorm_min(), 0.0, nl::quiet_NaN(), true, FE_INVALID);
84     TEST_SPECIAL(nl::min(), 0.0, nl::quiet_NaN(), true, FE_INVALID);
85     TEST_SPECIAL(nl::max(), 0.0, nl::quiet_NaN(), true, FE_INVALID);
86 
87     // fmod (x, -0) == nl::quiet_NaN() plus invalid exception.
88     TEST_SPECIAL(3.0, neg_zero, nl::quiet_NaN(), true, FE_INVALID);
89     TEST_SPECIAL(-1.1L, neg_zero, nl::quiet_NaN(), true, FE_INVALID);
90     TEST_SPECIAL(0.0, neg_zero, nl::quiet_NaN(), true, FE_INVALID);
91     TEST_SPECIAL(neg_zero, neg_zero, nl::quiet_NaN(), true, FE_INVALID);
92     TEST_SPECIAL(nl::denorm_min(), neg_zero, nl::quiet_NaN(), true, FE_INVALID);
93     TEST_SPECIAL(nl::min(), neg_zero, nl::quiet_NaN(), true, FE_INVALID);
94     TEST_SPECIAL(nl::max(), neg_zero, nl::quiet_NaN(), true, FE_INVALID);
95 
96     // fmod (x, +inf) == x for x not infinite.
97     TEST_SPECIAL(0.0, inf, 0.0, false, 0);
98     TEST_SPECIAL(neg_zero, inf, neg_zero, false, 0);
99     TEST_SPECIAL(nl::denorm_min(), inf, nl::denorm_min(), false, 0);
100     TEST_SPECIAL(nl::min(), inf, nl::min(), false, 0);
101     TEST_SPECIAL(nl::max(), inf, nl::max(), false, 0);
102     TEST_SPECIAL(3.0, inf, 3.0, false, 0);
103     // fmod (x, -inf) == x for x not infinite.
104     TEST_SPECIAL(0.0, neg_inf, 0.0, false, 0);
105     TEST_SPECIAL(neg_zero, neg_inf, neg_zero, false, 0);
106     TEST_SPECIAL(nl::denorm_min(), neg_inf, nl::denorm_min(), false, 0);
107     TEST_SPECIAL(nl::min(), neg_inf, nl::min(), false, 0);
108     TEST_SPECIAL(nl::max(), neg_inf, nl::max(), false, 0);
109     TEST_SPECIAL(3.0, neg_inf, 3.0, false, 0);
110 
111     TEST_SPECIAL(0.0, nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
112     TEST_SPECIAL(0.0, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
113     TEST_SPECIAL(neg_zero, nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
114     TEST_SPECIAL(neg_zero, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
115     TEST_SPECIAL(1.0, nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
116     TEST_SPECIAL(1.0, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
117     TEST_SPECIAL(inf, nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
118     TEST_SPECIAL(inf, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
119     TEST_SPECIAL(neg_inf, nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
120     TEST_SPECIAL(neg_inf, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
121     TEST_SPECIAL(0.0, nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID);
122     TEST_SPECIAL(0.0, -nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID);
123     TEST_SPECIAL(neg_zero, nl::signaling_NaN(), nl::quiet_NaN(), false,
124                  FE_INVALID);
125     TEST_SPECIAL(neg_zero, -nl::signaling_NaN(), nl::quiet_NaN(), false,
126                  FE_INVALID);
127     TEST_SPECIAL(1.0, nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID);
128     TEST_SPECIAL(1.0, -nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID);
129     TEST_SPECIAL(inf, nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID);
130     TEST_SPECIAL(inf, -nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID);
131     TEST_SPECIAL(neg_inf, nl::signaling_NaN(), nl::quiet_NaN(), false,
132                  FE_INVALID);
133     TEST_SPECIAL(neg_inf, -nl::signaling_NaN(), nl::quiet_NaN(), false,
134                  FE_INVALID);
135     TEST_SPECIAL(nl::quiet_NaN(), 0.0, nl::quiet_NaN(), false, 0);
136     TEST_SPECIAL(-nl::quiet_NaN(), 0.0, nl::quiet_NaN(), false, 0);
137     TEST_SPECIAL(nl::quiet_NaN(), neg_zero, nl::quiet_NaN(), false, 0);
138     TEST_SPECIAL(-nl::quiet_NaN(), neg_zero, nl::quiet_NaN(), false, 0);
139     TEST_SPECIAL(nl::quiet_NaN(), 1.0, nl::quiet_NaN(), false, 0);
140     TEST_SPECIAL(-nl::quiet_NaN(), 1.0, nl::quiet_NaN(), false, 0);
141     TEST_SPECIAL(nl::quiet_NaN(), inf, nl::quiet_NaN(), false, 0);
142     TEST_SPECIAL(-nl::quiet_NaN(), inf, nl::quiet_NaN(), false, 0);
143     TEST_SPECIAL(nl::quiet_NaN(), neg_inf, nl::quiet_NaN(), false, 0);
144     TEST_SPECIAL(-nl::quiet_NaN(), neg_inf, nl::quiet_NaN(), false, 0);
145     TEST_SPECIAL(nl::signaling_NaN(), 0.0, nl::quiet_NaN(), false, FE_INVALID);
146     TEST_SPECIAL(-nl::signaling_NaN(), 0.0, nl::quiet_NaN(), false, FE_INVALID);
147     TEST_SPECIAL(nl::signaling_NaN(), neg_zero, nl::quiet_NaN(), false,
148                  FE_INVALID);
149     TEST_SPECIAL(-nl::signaling_NaN(), neg_zero, nl::quiet_NaN(), false,
150                  FE_INVALID);
151     TEST_SPECIAL(nl::signaling_NaN(), 1.0, nl::quiet_NaN(), false, FE_INVALID);
152     TEST_SPECIAL(-nl::signaling_NaN(), 1.0, nl::quiet_NaN(), false, FE_INVALID);
153     TEST_SPECIAL(nl::signaling_NaN(), inf, nl::quiet_NaN(), false, FE_INVALID);
154     TEST_SPECIAL(-nl::signaling_NaN(), inf, nl::quiet_NaN(), false, FE_INVALID);
155     TEST_SPECIAL(nl::signaling_NaN(), neg_inf, nl::quiet_NaN(), false,
156                  FE_INVALID);
157     TEST_SPECIAL(-nl::signaling_NaN(), neg_inf, nl::quiet_NaN(), false,
158                  FE_INVALID);
159     TEST_SPECIAL(nl::quiet_NaN(), nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
160     TEST_SPECIAL(nl::quiet_NaN(), -nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
161     TEST_SPECIAL(-nl::quiet_NaN(), nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
162     TEST_SPECIAL(-nl::quiet_NaN(), -nl::quiet_NaN(), nl::quiet_NaN(), false, 0);
163     TEST_SPECIAL(nl::quiet_NaN(), nl::signaling_NaN(), nl::quiet_NaN(), false,
164                  FE_INVALID);
165     TEST_SPECIAL(nl::quiet_NaN(), -nl::signaling_NaN(), nl::quiet_NaN(), false,
166                  FE_INVALID);
167     TEST_SPECIAL(-nl::quiet_NaN(), nl::signaling_NaN(), nl::quiet_NaN(), false,
168                  FE_INVALID);
169     TEST_SPECIAL(-nl::quiet_NaN(), -nl::signaling_NaN(), nl::quiet_NaN(), false,
170                  FE_INVALID);
171     TEST_SPECIAL(nl::signaling_NaN(), nl::quiet_NaN(), nl::quiet_NaN(), false,
172                  FE_INVALID);
173     TEST_SPECIAL(nl::signaling_NaN(), -nl::quiet_NaN(), nl::quiet_NaN(), false,
174                  FE_INVALID);
175     TEST_SPECIAL(-nl::signaling_NaN(), nl::quiet_NaN(), nl::quiet_NaN(), false,
176                  FE_INVALID);
177     TEST_SPECIAL(-nl::signaling_NaN(), -nl::quiet_NaN(), nl::quiet_NaN(), false,
178                  FE_INVALID);
179     TEST_SPECIAL(nl::signaling_NaN(), nl::signaling_NaN(), nl::quiet_NaN(),
180                  false, FE_INVALID);
181     TEST_SPECIAL(nl::signaling_NaN(), -nl::signaling_NaN(), nl::quiet_NaN(),
182                  false, FE_INVALID);
183     TEST_SPECIAL(-nl::signaling_NaN(), nl::signaling_NaN(), nl::quiet_NaN(),
184                  false, FE_INVALID);
185     TEST_SPECIAL(-nl::signaling_NaN(), -nl::signaling_NaN(), nl::quiet_NaN(),
186                  false, FE_INVALID);
187 
188     TEST_SPECIAL(6.5, 2.25L, 2.0L, false, 0);
189     TEST_SPECIAL(-6.5, 2.25L, -2.0L, false, 0);
190     TEST_SPECIAL(6.5, -2.25L, 2.0L, false, 0);
191     TEST_SPECIAL(-6.5, -2.25L, -2.0L, false, 0);
192 
193     TEST_SPECIAL(nl::max(), nl::max(), 0.0, false, 0);
194     TEST_SPECIAL(nl::max(), -nl::max(), 0.0, false, 0);
195     TEST_SPECIAL(nl::max(), nl::min(), 0.0, false, 0);
196     TEST_SPECIAL(nl::max(), -nl::min(), 0.0, false, 0);
197     TEST_SPECIAL(nl::max(), nl::denorm_min(), 0.0, false, 0);
198     TEST_SPECIAL(nl::max(), -nl::denorm_min(), 0.0, false, 0);
199     TEST_SPECIAL(-nl::max(), nl::max(), neg_zero, false, 0);
200     TEST_SPECIAL(-nl::max(), -nl::max(), neg_zero, false, 0);
201     TEST_SPECIAL(-nl::max(), nl::min(), neg_zero, false, 0);
202     TEST_SPECIAL(-nl::max(), -nl::min(), neg_zero, false, 0);
203     TEST_SPECIAL(-nl::max(), nl::denorm_min(), neg_zero, false, 0);
204     TEST_SPECIAL(-nl::max(), -nl::denorm_min(), neg_zero, false, 0);
205 
206     TEST_SPECIAL(nl::min(), nl::max(), nl::min(), false, 0);
207     TEST_SPECIAL(nl::min(), -nl::max(), nl::min(), false, 0);
208     TEST_SPECIAL(nl::min(), nl::min(), 0.0, false, 0);
209     TEST_SPECIAL(nl::min(), -nl::min(), 0.0, false, 0);
210     TEST_SPECIAL(nl::min(), nl::denorm_min(), 0.0, false, 0);
211     TEST_SPECIAL(nl::min(), -nl::denorm_min(), 0.0, false, 0);
212     TEST_SPECIAL(-nl::min(), nl::max(), -nl::min(), false, 0);
213     TEST_SPECIAL(-nl::min(), -nl::max(), -nl::min(), false, 0);
214     TEST_SPECIAL(-nl::min(), nl::min(), neg_zero, false, 0);
215     TEST_SPECIAL(-nl::min(), -nl::min(), neg_zero, false, 0);
216     TEST_SPECIAL(-nl::min(), nl::denorm_min(), neg_zero, false, 0);
217     TEST_SPECIAL(-nl::min(), -nl::denorm_min(), neg_zero, false, 0);
218 
219     TEST_SPECIAL(nl::denorm_min(), nl::max(), nl::denorm_min(), false, 0);
220     TEST_SPECIAL(nl::denorm_min(), -nl::max(), nl::denorm_min(), false, 0);
221     TEST_SPECIAL(nl::denorm_min(), nl::min(), nl::denorm_min(), false, 0);
222     TEST_SPECIAL(nl::denorm_min(), -nl::min(), nl::denorm_min(), false, 0);
223     TEST_SPECIAL(nl::denorm_min(), nl::denorm_min(), 0.0, false, 0);
224     TEST_SPECIAL(nl::denorm_min(), -nl::denorm_min(), 0.0, false, 0);
225     TEST_SPECIAL(-nl::denorm_min(), nl::max(), -nl::denorm_min(), false, 0);
226     TEST_SPECIAL(-nl::denorm_min(), -nl::max(), -nl::denorm_min(), false, 0);
227     TEST_SPECIAL(-nl::denorm_min(), nl::min(), -nl::denorm_min(), false, 0);
228     TEST_SPECIAL(-nl::denorm_min(), -nl::min(), -nl::denorm_min(), false, 0);
229     TEST_SPECIAL(-nl::denorm_min(), nl::denorm_min(), neg_zero, false, 0);
230     TEST_SPECIAL(-nl::denorm_min(), -nl::denorm_min(), neg_zero, false, 0);
231   }
232 
testRegularExtreme(FModFunc f)233   void testRegularExtreme(FModFunc f) {
234 
235     TEST_REGULAR(0x1p127L, 0x3p-149L, 0x1p-149L);
236     TEST_REGULAR(0x1p127L, -0x3p-149L, 0x1p-149L);
237     TEST_REGULAR(0x1p127L, 0x3p-148L, 0x1p-147L);
238     TEST_REGULAR(0x1p127L, -0x3p-148L, 0x1p-147L);
239     TEST_REGULAR(0x1p127L, 0x3p-126L, 0x1p-125L);
240     TEST_REGULAR(0x1p127L, -0x3p-126L, 0x1p-125L);
241     TEST_REGULAR(-0x1p127L, 0x3p-149L, -0x1p-149L);
242     TEST_REGULAR(-0x1p127L, -0x3p-149L, -0x1p-149L);
243     TEST_REGULAR(-0x1p127L, 0x3p-148L, -0x1p-147L);
244     TEST_REGULAR(-0x1p127L, -0x3p-148L, -0x1p-147L);
245     TEST_REGULAR(-0x1p127L, 0x3p-126L, -0x1p-125L);
246     TEST_REGULAR(-0x1p127L, -0x3p-126L, -0x1p-125L);
247 
248     if constexpr (sizeof(T) >= sizeof(double)) {
249       TEST_REGULAR(0x1p1023L, 0x3p-1074L, 0x1p-1073L);
250       TEST_REGULAR(0x1p1023L, -0x3p-1074L, 0x1p-1073L);
251       TEST_REGULAR(0x1p1023L, 0x3p-1073L, 0x1p-1073L);
252       TEST_REGULAR(0x1p1023L, -0x3p-1073L, 0x1p-1073L);
253       TEST_REGULAR(0x1p1023L, 0x3p-1022L, 0x1p-1021L);
254       TEST_REGULAR(0x1p1023L, -0x3p-1022L, 0x1p-1021L);
255       TEST_REGULAR(-0x1p1023L, 0x3p-1074L, -0x1p-1073L);
256       TEST_REGULAR(-0x1p1023L, -0x3p-1074L, -0x1p-1073L);
257       TEST_REGULAR(-0x1p1023L, 0x3p-1073L, -0x1p-1073L);
258       TEST_REGULAR(-0x1p1023L, -0x3p-1073L, -0x1p-1073L);
259       TEST_REGULAR(-0x1p1023L, 0x3p-1022L, -0x1p-1021L);
260       TEST_REGULAR(-0x1p1023L, -0x3p-1022L, -0x1p-1021L);
261     }
262   }
263 };
264 
265 #define LIST_FMOD_TESTS(T, func)                                               \
266   using LlvmLibcFmodTest = FmodTest<T>;                                        \
267   TEST_F(LlvmLibcFmodTest, SpecialNumbers) { testSpecialNumbers(&func); }      \
268   TEST_F(LlvmLibcFmodTest, RegularExtreme) { testRegularExtreme(&func); }
269 
270 #endif // LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H
271