1 | //===-- Utility class to test canonicalize[f|l] -----------------*- 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 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H |
10 | #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H |
11 | |
12 | #include "src/__support/FPUtil/FEnvImpl.h" |
13 | #include "src/__support/FPUtil/FPBits.h" |
14 | #include "src/__support/integer_literals.h" |
15 | #include "test/UnitTest/FEnvSafeTest.h" |
16 | #include "test/UnitTest/FPMatcher.h" |
17 | #include "test/UnitTest/Test.h" |
18 | |
19 | #include "hdr/math_macros.h" |
20 | |
21 | #define TEST_SPECIAL(x, y, expected, expected_exception) \ |
22 | LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); \ |
23 | EXPECT_EQ(expected, f(&x, &y)); \ |
24 | EXPECT_FP_EXCEPTION(expected_exception); \ |
25 | LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT) |
26 | |
27 | #define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, 0) |
28 | |
29 | using LIBC_NAMESPACE::operator""_u96 ; |
30 | using LIBC_NAMESPACE::operator""_u128 ; |
31 | |
32 | template <typename T> |
33 | class CanonicalizeTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { |
34 | |
35 | DECLARE_SPECIAL_CONSTANTS(T) |
36 | |
37 | public: |
38 | typedef int (*CanonicalizeFunc)(T *, const T *); |
39 | |
40 | void testSpecialNumbers(CanonicalizeFunc f) { |
41 | T cx; |
42 | |
43 | TEST_SPECIAL(cx, zero, 0, 0); |
44 | EXPECT_FP_EQ(cx, zero); |
45 | |
46 | TEST_SPECIAL(cx, neg_zero, 0, 0); |
47 | EXPECT_FP_EQ(cx, neg_zero); |
48 | |
49 | TEST_SPECIAL(cx, inf, 0, 0); |
50 | EXPECT_FP_EQ(cx, inf); |
51 | |
52 | TEST_SPECIAL(cx, neg_inf, 0, 0); |
53 | EXPECT_FP_EQ(cx, neg_inf); |
54 | |
55 | TEST_SPECIAL(cx, sNaN, 1, FE_INVALID); |
56 | EXPECT_FP_EQ(cx, aNaN); |
57 | } |
58 | |
59 | void testX64_80SpecialNumbers(CanonicalizeFunc f) { |
60 | if constexpr (LIBC_NAMESPACE::fputil::get_fp_type<T>() == |
61 | LIBC_NAMESPACE::fputil::FPType::X86_Binary80) { |
62 | T cx; |
63 | // Exponent | Significand | Meaning |
64 | // | Bits 63-62 | Bits 61-0 | |
65 | // All Ones | 00 | Zero | Pseudo Infinity, Value = SNaN |
66 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
67 | FPBits test1(0x00007FFF'00000000'00000000_u96); |
68 | #else |
69 | FPBits test1(0x00000000'00007FFF'00000000'00000000_u128); |
70 | #endif |
71 | const T test1_val = test1.get_val(); |
72 | TEST_SPECIAL(cx, test1_val, 1, FE_INVALID); |
73 | EXPECT_FP_EQ(cx, aNaN); |
74 | |
75 | // Exponent | Significand | Meaning |
76 | // | Bits 63-62 | Bits 61-0 | |
77 | // All Ones | 00 | Non-Zero | Pseudo NaN, Value = SNaN |
78 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
79 | FPBits test2_1(0x00007FFF'00000000'00000001_u96); |
80 | #else |
81 | FPBits test2_1(0x00000000'00007FFF'00000000'00000001_u128); |
82 | #endif |
83 | const T test2_1_val = test2_1.get_val(); |
84 | TEST_SPECIAL(cx, test2_1_val, 1, FE_INVALID); |
85 | EXPECT_FP_EQ(cx, aNaN); |
86 | |
87 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
88 | FPBits test2_2(0x00007FFF'00000042'70000001_u96); |
89 | #else |
90 | FPBits test2_2(0x00000000'00007FFF'00000042'70000001_u128); |
91 | #endif |
92 | const T test2_2_val = test2_2.get_val(); |
93 | TEST_SPECIAL(cx, test2_2_val, 1, FE_INVALID); |
94 | EXPECT_FP_EQ(cx, aNaN); |
95 | |
96 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
97 | FPBits test2_3(0x00007FFF'00000000'08261001_u96); |
98 | #else |
99 | FPBits test2_3(0x00000000'00007FFF'00000000'08261001_u128); |
100 | #endif |
101 | const T test2_3_val = test2_3.get_val(); |
102 | TEST_SPECIAL(cx, test2_3_val, 1, FE_INVALID); |
103 | EXPECT_FP_EQ(cx, aNaN); |
104 | |
105 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
106 | FPBits test2_4(0x00007FFF'00007800'08261001_u96); |
107 | #else |
108 | FPBits test2_4(0x00000000'00007FFF'00007800'08261001_u128); |
109 | #endif |
110 | const T test2_4_val = test2_4.get_val(); |
111 | TEST_SPECIAL(cx, test2_4_val, 1, FE_INVALID); |
112 | EXPECT_FP_EQ(cx, aNaN); |
113 | |
114 | // Exponent | Significand | Meaning |
115 | // | Bits 63-62 | Bits 61-0 | |
116 | // All Ones | 01 | Anything | Pseudo NaN, Value = SNaN |
117 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
118 | FPBits test3_1(0x00007FFF'40000000'00000000_u96); |
119 | #else |
120 | FPBits test3_1(0x00000000'00007FFF'40000000'00000000_u128); |
121 | #endif |
122 | const T test3_1_val = test3_1.get_val(); |
123 | TEST_SPECIAL(cx, test3_1_val, 1, FE_INVALID); |
124 | EXPECT_FP_EQ(cx, aNaN); |
125 | |
126 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
127 | FPBits test3_2(0x00007FFF'40000042'70000001_u96); |
128 | #else |
129 | FPBits test3_2(0x00000000'00007FFF'40000042'70000001_u128); |
130 | #endif |
131 | const T test3_2_val = test3_2.get_val(); |
132 | TEST_SPECIAL(cx, test3_2_val, 1, FE_INVALID); |
133 | EXPECT_FP_EQ(cx, aNaN); |
134 | |
135 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
136 | FPBits test3_3(0x00007FFF'40000000'08261001_u96); |
137 | #else |
138 | FPBits test3_3(0x00000000'00007FFF'40000000'08261001_u128); |
139 | #endif |
140 | const T test3_3_val = test3_3.get_val(); |
141 | TEST_SPECIAL(cx, test3_3_val, 1, FE_INVALID); |
142 | EXPECT_FP_EQ(cx, aNaN); |
143 | |
144 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
145 | FPBits test3_4(0x00007FFF'40007800'08261001_u96); |
146 | #else |
147 | FPBits test3_4(0x00000000'00007FFF'40007800'08261001_u128); |
148 | #endif |
149 | const T test3_4_val = test3_4.get_val(); |
150 | TEST_SPECIAL(cx, test3_4_val, 1, FE_INVALID); |
151 | EXPECT_FP_EQ(cx, aNaN); |
152 | |
153 | // Exponent | Significand | Meaning |
154 | // | Bit 63 | Bits 62-0 | |
155 | // All zeroes | One | Anything | Pseudo Denormal, Value = |
156 | // | | | (−1)**s × m × 2**−16382 |
157 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
158 | FPBits test4_1(0x00000000'80000000'00000000_u96); |
159 | #else |
160 | FPBits test4_1(0x00000000'00000000'80000000'00000000_u128); |
161 | #endif |
162 | const T test4_1_val = test4_1.get_val(); |
163 | TEST_SPECIAL(cx, test4_1_val, 0, 0); |
164 | EXPECT_FP_EQ( |
165 | cx, FPBits::make_value(test4_1.get_explicit_mantissa(), 0).get_val()); |
166 | |
167 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
168 | FPBits test4_2(0x00000000'80000042'70000001_u96); |
169 | #else |
170 | FPBits test4_2(0x00000000'00000000'80000042'70000001_u128); |
171 | #endif |
172 | const T test4_2_val = test4_2.get_val(); |
173 | TEST_SPECIAL(cx, test4_2_val, 0, 0); |
174 | EXPECT_FP_EQ( |
175 | cx, FPBits::make_value(test4_2.get_explicit_mantissa(), 0).get_val()); |
176 | |
177 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
178 | FPBits test4_3(0x00000000'80000000'08261001_u96); |
179 | #else |
180 | FPBits test4_3(0x00000000'00000000'80000000'08261001_u128); |
181 | #endif |
182 | const T test4_3_val = test4_3.get_val(); |
183 | TEST_SPECIAL(cx, test4_3_val, 0, 0); |
184 | EXPECT_FP_EQ( |
185 | cx, FPBits::make_value(test4_3.get_explicit_mantissa(), 0).get_val()); |
186 | |
187 | // Exponent | Significand | Meaning |
188 | // | Bit 63 | Bits 62-0 | |
189 | // All Other | Zero | Anything | Unnormal, Value = SNaN |
190 | // Values | | | |
191 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
192 | FPBits test5_1(0x00000040'00000000'00000001_u96); |
193 | #else |
194 | FPBits test5_1(0x00000000'00000040'00000000'00000001_u128); |
195 | #endif |
196 | const T test5_1_val = test5_1.get_val(); |
197 | TEST_SPECIAL(cx, test5_1_val, 1, FE_INVALID); |
198 | EXPECT_FP_EQ(cx, aNaN); |
199 | |
200 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
201 | FPBits test5_2(0x00000230'00000042'70000001_u96); |
202 | #else |
203 | FPBits test5_2(0x00000000'00000230'00000042'70000001_u128); |
204 | #endif |
205 | const T test5_2_val = test5_2.get_val(); |
206 | TEST_SPECIAL(cx, test5_2_val, 1, FE_INVALID); |
207 | EXPECT_FP_EQ(cx, aNaN); |
208 | |
209 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
210 | FPBits test5_3(0x00000560'00000000'08261001_u96); |
211 | #else |
212 | FPBits test5_3(0x00000000'00000560'00000000'08261001_u128); |
213 | #endif |
214 | const T test5_3_val = test5_3.get_val(); |
215 | TEST_SPECIAL(cx, test5_3_val, 1, FE_INVALID); |
216 | EXPECT_FP_EQ(cx, aNaN); |
217 | |
218 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
219 | FPBits test5_4(0x00000780'00000028'16000000_u96); |
220 | #else |
221 | FPBits test5_4(0x00000000'00000780'00000028'16000000_u128); |
222 | #endif |
223 | const T test5_4_val = test5_4.get_val(); |
224 | TEST_SPECIAL(cx, test5_4_val, 1, FE_INVALID); |
225 | EXPECT_FP_EQ(cx, aNaN); |
226 | |
227 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
228 | FPBits test5_5(0x00000900'00000042'70000001_u96); |
229 | #else |
230 | FPBits test5_5(0x00000000'00000900'00000042'70000001_u128); |
231 | #endif |
232 | const T test5_5_val = test5_5.get_val(); |
233 | TEST_SPECIAL(cx, test5_5_val, 1, FE_INVALID); |
234 | EXPECT_FP_EQ(cx, aNaN); |
235 | |
236 | #if __SIZEOF_LONG_DOUBLE__ == 12 |
237 | FPBits test5_6(0x00000AB0'00000000'08261001_u96); |
238 | #else |
239 | FPBits test5_6(0x00000000'00000AB0'00000000'08261001_u128); |
240 | #endif |
241 | const T test5_6_val = test5_6.get_val(); |
242 | TEST_SPECIAL(cx, test5_6_val, 1, FE_INVALID); |
243 | EXPECT_FP_EQ(cx, aNaN); |
244 | } |
245 | } |
246 | |
247 | void testRegularNumbers(CanonicalizeFunc f) { |
248 | T cx; |
249 | const T test_var_1 = T(1.0); |
250 | TEST_REGULAR(cx, test_var_1, 0); |
251 | EXPECT_FP_EQ(cx, test_var_1); |
252 | const T test_var_2 = T(-1.0); |
253 | TEST_REGULAR(cx, test_var_2, 0); |
254 | EXPECT_FP_EQ(cx, test_var_2); |
255 | const T test_var_3 = T(10.0); |
256 | TEST_REGULAR(cx, test_var_3, 0); |
257 | EXPECT_FP_EQ(cx, test_var_3); |
258 | const T test_var_4 = T(-10.0); |
259 | TEST_REGULAR(cx, test_var_4, 0); |
260 | EXPECT_FP_EQ(cx, test_var_4); |
261 | const T test_var_5 = T(1234.0); |
262 | TEST_REGULAR(cx, test_var_5, 0); |
263 | EXPECT_FP_EQ(cx, test_var_5); |
264 | const T test_var_6 = T(-1234.0); |
265 | TEST_REGULAR(cx, test_var_6, 0); |
266 | EXPECT_FP_EQ(cx, test_var_6); |
267 | } |
268 | }; |
269 | |
270 | #define LIST_CANONICALIZE_TESTS(T, func) \ |
271 | using LlvmLibcCanonicalizeTest = CanonicalizeTest<T>; \ |
272 | TEST_F(LlvmLibcCanonicalizeTest, SpecialNumbers) { \ |
273 | testSpecialNumbers(&func); \ |
274 | } \ |
275 | TEST_F(LlvmLibcCanonicalizeTest, RegularNubmers) { \ |
276 | testRegularNumbers(&func); \ |
277 | } |
278 | |
279 | #define X86_80_SPECIAL_CANONICALIZE_TEST(T, func) \ |
280 | using LlvmLibcCanonicalizeTest = CanonicalizeTest<T>; \ |
281 | TEST_F(LlvmLibcCanonicalizeTest, X64_80SpecialNumbers) { \ |
282 | testX64_80SpecialNumbers(&func); \ |
283 | } |
284 | |
285 | #endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H |
286 | |