1 | //===-- Unittests for powf ------------------------------------------------===// |
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 | #include "hdr/math_macros.h" |
10 | #include "src/__support/FPUtil/FPBits.h" |
11 | #include "src/math/powf.h" |
12 | #include "test/UnitTest/FPMatcher.h" |
13 | #include "test/UnitTest/Test.h" |
14 | |
15 | #include <stdint.h> |
16 | |
17 | using LlvmLibcPowfTest = LIBC_NAMESPACE::testing::FPTest<float>; |
18 | using LIBC_NAMESPACE::fputil::testing::ForceRoundingMode; |
19 | using LIBC_NAMESPACE::fputil::testing::RoundingMode; |
20 | |
21 | TEST_F(LlvmLibcPowfTest, SpecialNumbers) { |
22 | constexpr float neg_odd_integer = -3.0f; |
23 | constexpr float neg_even_integer = -6.0f; |
24 | constexpr float neg_non_integer = -1.1f; |
25 | constexpr float pos_odd_integer = 5.0f; |
26 | constexpr float pos_even_integer = 8.0f; |
27 | constexpr float pos_non_integer = 1.3f; |
28 | constexpr float one_half = 0.5f; |
29 | |
30 | for (int i = 0; i < N_ROUNDING_MODES; ++i) { |
31 | ForceRoundingMode __r(ROUNDING_MODES[i]); |
32 | if (!__r.success) |
33 | continue; |
34 | |
35 | // pow( sNaN, exponent) |
36 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, sNaN), |
37 | FE_INVALID); |
38 | EXPECT_FP_EQ_WITH_EXCEPTION( |
39 | aNaN, LIBC_NAMESPACE::powf(sNaN, neg_odd_integer), FE_INVALID); |
40 | EXPECT_FP_EQ_WITH_EXCEPTION( |
41 | aNaN, LIBC_NAMESPACE::powf(sNaN, neg_even_integer), FE_INVALID); |
42 | EXPECT_FP_EQ_WITH_EXCEPTION( |
43 | aNaN, LIBC_NAMESPACE::powf(sNaN, pos_odd_integer), FE_INVALID); |
44 | EXPECT_FP_EQ_WITH_EXCEPTION( |
45 | aNaN, LIBC_NAMESPACE::powf(sNaN, pos_even_integer), FE_INVALID); |
46 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, one_half), |
47 | FE_INVALID); |
48 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, zero), |
49 | FE_INVALID); |
50 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, neg_zero), |
51 | FE_INVALID); |
52 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, inf), |
53 | FE_INVALID); |
54 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, neg_inf), |
55 | FE_INVALID); |
56 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, aNaN), |
57 | FE_INVALID); |
58 | |
59 | // pow( 0.0f, exponent ) |
60 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(zero, sNaN), |
61 | FE_INVALID); |
62 | EXPECT_FP_EQ_WITH_EXCEPTION( |
63 | inf, LIBC_NAMESPACE::powf(zero, neg_odd_integer), FE_DIVBYZERO); |
64 | EXPECT_FP_EQ_WITH_EXCEPTION( |
65 | inf, LIBC_NAMESPACE::powf(zero, neg_even_integer), FE_DIVBYZERO); |
66 | EXPECT_FP_EQ_WITH_EXCEPTION( |
67 | inf, LIBC_NAMESPACE::powf(zero, neg_non_integer), FE_DIVBYZERO); |
68 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(zero, pos_odd_integer)); |
69 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(zero, pos_even_integer)); |
70 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(zero, pos_non_integer)); |
71 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(zero, one_half)); |
72 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(zero, zero)); |
73 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(zero, neg_zero)); |
74 | EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(zero, inf)); |
75 | EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::powf(zero, neg_inf), |
76 | FE_DIVBYZERO); |
77 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(zero, aNaN)); |
78 | |
79 | // pow( -0.0f, exponent ) |
80 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(neg_zero, sNaN), |
81 | FE_INVALID); |
82 | EXPECT_FP_EQ_WITH_EXCEPTION( |
83 | neg_inf, LIBC_NAMESPACE::powf(neg_zero, neg_odd_integer), FE_DIVBYZERO); |
84 | EXPECT_FP_EQ_WITH_EXCEPTION( |
85 | inf, LIBC_NAMESPACE::powf(neg_zero, neg_even_integer), FE_DIVBYZERO); |
86 | EXPECT_FP_EQ_WITH_EXCEPTION( |
87 | inf, LIBC_NAMESPACE::powf(neg_zero, neg_non_integer), FE_DIVBYZERO); |
88 | EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::powf(neg_zero, pos_odd_integer)); |
89 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_zero, pos_even_integer)); |
90 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_zero, pos_non_integer)); |
91 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_zero, one_half)); |
92 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_zero, zero)); |
93 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_zero, neg_zero)); |
94 | EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(neg_zero, inf)); |
95 | EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::powf(neg_zero, neg_inf), |
96 | FE_DIVBYZERO); |
97 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(neg_zero, aNaN)); |
98 | |
99 | // pow( 1.0f, exponent ) |
100 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(1.0f, sNaN), |
101 | FE_INVALID); |
102 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, zero)); |
103 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_zero)); |
104 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, 1.0f)); |
105 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, -1.0f)); |
106 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_odd_integer)); |
107 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_even_integer)); |
108 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_non_integer)); |
109 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, pos_odd_integer)); |
110 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, pos_even_integer)); |
111 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, pos_non_integer)); |
112 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, inf)); |
113 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_inf)); |
114 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, aNaN)); |
115 | |
116 | // pow( -1.0f, exponent ) |
117 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(-1.0f, sNaN), |
118 | FE_INVALID); |
119 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, zero)); |
120 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, neg_zero)); |
121 | EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::powf(-1.0f, 1.0f)); |
122 | EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::powf(-1.0f, -1.0f)); |
123 | EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::powf(-1.0f, neg_odd_integer)); |
124 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, neg_even_integer)); |
125 | EXPECT_FP_IS_NAN_WITH_EXCEPTION( |
126 | LIBC_NAMESPACE::powf(-1.0f, neg_non_integer), FE_INVALID); |
127 | EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::powf(-1.0f, pos_odd_integer)); |
128 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, pos_even_integer)); |
129 | EXPECT_FP_IS_NAN_WITH_EXCEPTION( |
130 | LIBC_NAMESPACE::powf(-1.0f, pos_non_integer), FE_INVALID); |
131 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, inf)); |
132 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, neg_inf)); |
133 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(-1.0f, aNaN)); |
134 | |
135 | // pow( inf, exponent ) |
136 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(inf, sNaN), |
137 | FE_INVALID); |
138 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(inf, zero)); |
139 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(inf, neg_zero)); |
140 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, 1.0f)); |
141 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, -1.0f)); |
142 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, neg_odd_integer)); |
143 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, neg_even_integer)); |
144 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, neg_non_integer)); |
145 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, pos_odd_integer)); |
146 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, pos_even_integer)); |
147 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, pos_non_integer)); |
148 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, one_half)); |
149 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, inf)); |
150 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, neg_inf)); |
151 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(inf, aNaN)); |
152 | |
153 | // pow( -inf, exponent ) |
154 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(neg_inf, sNaN), |
155 | FE_INVALID); |
156 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_inf, zero)); |
157 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_inf, neg_zero)); |
158 | EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::powf(neg_inf, 1.0f)); |
159 | EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::powf(neg_inf, -1.0f)); |
160 | EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::powf(neg_inf, neg_odd_integer)); |
161 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_inf, neg_even_integer)); |
162 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_inf, neg_non_integer)); |
163 | EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::powf(neg_inf, pos_odd_integer)); |
164 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(neg_inf, pos_even_integer)); |
165 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(neg_inf, pos_non_integer)); |
166 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(neg_inf, one_half)); |
167 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(neg_inf, inf)); |
168 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_inf, neg_inf)); |
169 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(neg_inf, aNaN)); |
170 | |
171 | // pow ( aNaN, exponent ) |
172 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(aNaN, sNaN), |
173 | FE_INVALID); |
174 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(aNaN, zero)); |
175 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(aNaN, neg_zero)); |
176 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, 1.0f)); |
177 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, -1.0f)); |
178 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, neg_odd_integer)); |
179 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, neg_even_integer)); |
180 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, neg_non_integer)); |
181 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, pos_odd_integer)); |
182 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, pos_even_integer)); |
183 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, pos_non_integer)); |
184 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, inf)); |
185 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, neg_inf)); |
186 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, aNaN)); |
187 | |
188 | // pow ( base, inf ) |
189 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(0.1f, inf)); |
190 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(-0.1f, inf)); |
191 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(1.1f, inf)); |
192 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(-1.1f, inf)); |
193 | |
194 | // pow ( base, -inf ) |
195 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(0.1f, neg_inf)); |
196 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(-0.1f, neg_inf)); |
197 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(1.1f, neg_inf)); |
198 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(-1.1f, neg_inf)); |
199 | |
200 | // Exact powers of 2: |
201 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(2.0f, sNaN), |
202 | FE_INVALID); |
203 | EXPECT_FP_EQ(0x1.0p15f, LIBC_NAMESPACE::powf(2.0f, 15.0f)); |
204 | EXPECT_FP_EQ(0x1.0p126f, LIBC_NAMESPACE::powf(2.0f, 126.0f)); |
205 | EXPECT_FP_EQ(0x1.0p-45f, LIBC_NAMESPACE::powf(2.0f, -45.0f)); |
206 | EXPECT_FP_EQ(0x1.0p-126f, LIBC_NAMESPACE::powf(2.0f, -126.0f)); |
207 | EXPECT_FP_EQ(0x1.0p-149f, LIBC_NAMESPACE::powf(2.0f, -149.0f)); |
208 | |
209 | // Exact powers of 10: |
210 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(10.0f, 0.0f)); |
211 | EXPECT_FP_EQ(10.0f, LIBC_NAMESPACE::powf(10.0f, 1.0f)); |
212 | EXPECT_FP_EQ(100.0f, LIBC_NAMESPACE::powf(10.0f, 2.0f)); |
213 | EXPECT_FP_EQ(1000.0f, LIBC_NAMESPACE::powf(10.0f, 3.0f)); |
214 | EXPECT_FP_EQ(10000.0f, LIBC_NAMESPACE::powf(10.0f, 4.0f)); |
215 | EXPECT_FP_EQ(100000.0f, LIBC_NAMESPACE::powf(10.0f, 5.0f)); |
216 | EXPECT_FP_EQ(1000000.0f, LIBC_NAMESPACE::powf(10.0f, 6.0f)); |
217 | EXPECT_FP_EQ(10000000.0f, LIBC_NAMESPACE::powf(10.0f, 7.0f)); |
218 | EXPECT_FP_EQ(100000000.0f, LIBC_NAMESPACE::powf(10.0f, 8.0f)); |
219 | EXPECT_FP_EQ(1000000000.0f, LIBC_NAMESPACE::powf(10.0f, 9.0f)); |
220 | EXPECT_FP_EQ(10000000000.0f, LIBC_NAMESPACE::powf(10.0f, 10.0f)); |
221 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(10.0f, sNaN), |
222 | FE_INVALID); |
223 | |
224 | // Overflow / Underflow: |
225 | if (ROUNDING_MODES[i] != RoundingMode::Downward && |
226 | ROUNDING_MODES[i] != RoundingMode::TowardZero) { |
227 | EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::powf(3.1f, 201.0f), |
228 | FE_OVERFLOW); |
229 | } |
230 | if (ROUNDING_MODES[i] != RoundingMode::Upward) { |
231 | EXPECT_FP_EQ_WITH_EXCEPTION(0.0f, LIBC_NAMESPACE::powf(3.1f, -201.0f), |
232 | FE_UNDERFLOW); |
233 | } |
234 | } |
235 | |
236 | EXPECT_FP_EQ(-0.0f, LIBC_NAMESPACE::powf(-0.015625f, 25.0f)); |
237 | EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(-0.015625f, 26.0f)); |
238 | } |
239 | |
240 | #ifdef LIBC_TEST_FTZ_DAZ |
241 | |
242 | using namespace LIBC_NAMESPACE::testing; |
243 | |
244 | TEST_F(LlvmLibcPowfTest, FTZMode) { |
245 | ModifyMXCSR mxcsr(FTZ); |
246 | |
247 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(-min_denormal, 0.5f)); |
248 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(2.0f, min_denormal)); |
249 | } |
250 | |
251 | TEST_F(LlvmLibcPowfTest, DAZMode) { |
252 | ModifyMXCSR mxcsr(DAZ); |
253 | |
254 | EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(-min_denormal, 0.5f)); |
255 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(2.0f, min_denormal)); |
256 | } |
257 | |
258 | TEST_F(LlvmLibcPowfTest, FTZDAZMode) { |
259 | ModifyMXCSR mxcsr(FTZ | DAZ); |
260 | |
261 | EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(-min_denormal, 0.5f)); |
262 | EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(2.0f, min_denormal)); |
263 | } |
264 | |
265 | #endif |
266 | |