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
TEST_F(LlvmLibcPowfTest,SpecialNumbers)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( 0.0f, exponent )
36 EXPECT_FP_EQ_WITH_EXCEPTION(
37 inf, LIBC_NAMESPACE::powf(zero, neg_odd_integer), FE_DIVBYZERO);
38 EXPECT_FP_EQ_WITH_EXCEPTION(
39 inf, LIBC_NAMESPACE::powf(zero, neg_even_integer), FE_DIVBYZERO);
40 EXPECT_FP_EQ_WITH_EXCEPTION(
41 inf, LIBC_NAMESPACE::powf(zero, neg_non_integer), FE_DIVBYZERO);
42 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(zero, pos_odd_integer));
43 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(zero, pos_even_integer));
44 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(zero, pos_non_integer));
45 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(zero, one_half));
46 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(zero, zero));
47 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(zero, neg_zero));
48 EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(zero, inf));
49 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::powf(zero, neg_inf),
50 FE_DIVBYZERO);
51 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(zero, aNaN));
52
53 // pow( -0.0f, exponent )
54 EXPECT_FP_EQ_WITH_EXCEPTION(
55 neg_inf, LIBC_NAMESPACE::powf(neg_zero, neg_odd_integer), FE_DIVBYZERO);
56 EXPECT_FP_EQ_WITH_EXCEPTION(
57 inf, LIBC_NAMESPACE::powf(neg_zero, neg_even_integer), FE_DIVBYZERO);
58 EXPECT_FP_EQ_WITH_EXCEPTION(
59 inf, LIBC_NAMESPACE::powf(neg_zero, neg_non_integer), FE_DIVBYZERO);
60 EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::powf(neg_zero, pos_odd_integer));
61 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_zero, pos_even_integer));
62 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_zero, pos_non_integer));
63 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_zero, one_half));
64 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_zero, zero));
65 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_zero, neg_zero));
66 EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(neg_zero, inf));
67 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::powf(neg_zero, neg_inf),
68 FE_DIVBYZERO);
69 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(neg_zero, aNaN));
70
71 // pow( 1.0f, exponent )
72 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, zero));
73 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_zero));
74 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, 1.0f));
75 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, -1.0f));
76 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_odd_integer));
77 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_even_integer));
78 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_non_integer));
79 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, pos_odd_integer));
80 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, pos_even_integer));
81 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, pos_non_integer));
82 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, inf));
83 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_inf));
84 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, aNaN));
85
86 // pow( 1.0f, exponent )
87 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, zero));
88 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, neg_zero));
89 EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::powf(-1.0f, 1.0f));
90 EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::powf(-1.0f, -1.0f));
91 EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::powf(-1.0f, neg_odd_integer));
92 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, neg_even_integer));
93 EXPECT_FP_IS_NAN_WITH_EXCEPTION(
94 LIBC_NAMESPACE::powf(-1.0f, neg_non_integer), FE_INVALID);
95 EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::powf(-1.0f, pos_odd_integer));
96 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, pos_even_integer));
97 EXPECT_FP_IS_NAN_WITH_EXCEPTION(
98 LIBC_NAMESPACE::powf(-1.0f, pos_non_integer), FE_INVALID);
99 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, inf));
100 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, neg_inf));
101 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(-1.0f, aNaN));
102
103 // pow( inf, exponent )
104 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(inf, zero));
105 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(inf, neg_zero));
106 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, 1.0f));
107 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, -1.0f));
108 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, neg_odd_integer));
109 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, neg_even_integer));
110 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, neg_non_integer));
111 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, pos_odd_integer));
112 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, pos_even_integer));
113 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, pos_non_integer));
114 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, one_half));
115 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, inf));
116 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(inf, neg_inf));
117 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(inf, aNaN));
118
119 // pow( -inf, exponent )
120 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_inf, zero));
121 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_inf, neg_zero));
122 EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::powf(neg_inf, 1.0f));
123 EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::powf(neg_inf, -1.0f));
124 EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::powf(neg_inf, neg_odd_integer));
125 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_inf, neg_even_integer));
126 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_inf, neg_non_integer));
127 EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::powf(neg_inf, pos_odd_integer));
128 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(neg_inf, pos_even_integer));
129 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(neg_inf, pos_non_integer));
130 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(neg_inf, one_half));
131 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(neg_inf, inf));
132 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(neg_inf, neg_inf));
133 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(neg_inf, aNaN));
134
135 // pow ( aNaN, exponent )
136 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(aNaN, zero));
137 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(aNaN, neg_zero));
138 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, 1.0f));
139 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, -1.0f));
140 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, neg_odd_integer));
141 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, neg_even_integer));
142 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, neg_non_integer));
143 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, pos_odd_integer));
144 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, pos_even_integer));
145 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, pos_non_integer));
146 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, inf));
147 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, neg_inf));
148 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, aNaN));
149
150 // pow ( base, inf )
151 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(0.1f, inf));
152 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(-0.1f, inf));
153 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(1.1f, inf));
154 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(-1.1f, inf));
155
156 // pow ( base, -inf )
157 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(0.1f, neg_inf));
158 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(-0.1f, neg_inf));
159 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(1.1f, neg_inf));
160 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(-1.1f, neg_inf));
161
162 // Exact powers of 2:
163 EXPECT_FP_EQ(0x1.0p15f, LIBC_NAMESPACE::powf(2.0f, 15.0f));
164 EXPECT_FP_EQ(0x1.0p126f, LIBC_NAMESPACE::powf(2.0f, 126.0f));
165 EXPECT_FP_EQ(0x1.0p-45f, LIBC_NAMESPACE::powf(2.0f, -45.0f));
166 EXPECT_FP_EQ(0x1.0p-126f, LIBC_NAMESPACE::powf(2.0f, -126.0f));
167 EXPECT_FP_EQ(0x1.0p-149f, LIBC_NAMESPACE::powf(2.0f, -149.0f));
168
169 // Exact powers of 10:
170 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(10.0f, 0.0f));
171 EXPECT_FP_EQ(10.0f, LIBC_NAMESPACE::powf(10.0f, 1.0f));
172 EXPECT_FP_EQ(100.0f, LIBC_NAMESPACE::powf(10.0f, 2.0f));
173 EXPECT_FP_EQ(1000.0f, LIBC_NAMESPACE::powf(10.0f, 3.0f));
174 EXPECT_FP_EQ(10000.0f, LIBC_NAMESPACE::powf(10.0f, 4.0f));
175 EXPECT_FP_EQ(100000.0f, LIBC_NAMESPACE::powf(10.0f, 5.0f));
176 EXPECT_FP_EQ(1000000.0f, LIBC_NAMESPACE::powf(10.0f, 6.0f));
177 EXPECT_FP_EQ(10000000.0f, LIBC_NAMESPACE::powf(10.0f, 7.0f));
178 EXPECT_FP_EQ(100000000.0f, LIBC_NAMESPACE::powf(10.0f, 8.0f));
179 EXPECT_FP_EQ(1000000000.0f, LIBC_NAMESPACE::powf(10.0f, 9.0f));
180 EXPECT_FP_EQ(10000000000.0f, LIBC_NAMESPACE::powf(10.0f, 10.0f));
181
182 // Overflow / Underflow:
183 if (ROUNDING_MODES[i] != RoundingMode::Downward &&
184 ROUNDING_MODES[i] != RoundingMode::TowardZero) {
185 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::powf(3.1f, 201.0f),
186 FE_OVERFLOW);
187 }
188 if (ROUNDING_MODES[i] != RoundingMode::Upward) {
189 EXPECT_FP_EQ_WITH_EXCEPTION(0.0f, LIBC_NAMESPACE::powf(3.1f, -201.0f),
190 FE_UNDERFLOW);
191 }
192 }
193
194 EXPECT_FP_EQ(-0.0f, LIBC_NAMESPACE::powf(-0.015625f, 25.0f));
195 EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(-0.015625f, 26.0f));
196 }
197
198 #ifdef LIBC_TEST_FTZ_DAZ
199
200 using namespace LIBC_NAMESPACE::testing;
201
TEST_F(LlvmLibcPowfTest,FTZMode)202 TEST_F(LlvmLibcPowfTest, FTZMode) {
203 ModifyMXCSR mxcsr(FTZ);
204
205 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(-min_denormal, 0.5f));
206 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(2.0f, min_denormal));
207 }
208
TEST_F(LlvmLibcPowfTest,DAZMode)209 TEST_F(LlvmLibcPowfTest, DAZMode) {
210 ModifyMXCSR mxcsr(DAZ);
211
212 EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(-min_denormal, 0.5f));
213 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(2.0f, min_denormal));
214 }
215
TEST_F(LlvmLibcPowfTest,FTZDAZMode)216 TEST_F(LlvmLibcPowfTest, FTZDAZMode) {
217 ModifyMXCSR mxcsr(FTZ | DAZ);
218
219 EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::powf(-min_denormal, 0.5f));
220 EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(2.0f, min_denormal));
221 }
222
223 #endif
224