xref: /aosp_15_r20/external/llvm-libc/test/src/math/smoke/powf_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
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