xref: /aosp_15_r20/external/llvm-libc/test/src/math/smoke/pow_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Unittests for pow -------------------------------------------------===//
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/fenv_macros.h"
10 #include "src/math/pow.h"
11 #include "test/UnitTest/FPMatcher.h"
12 #include "test/UnitTest/Test.h"
13 
14 using LlvmLibcPowTest = LIBC_NAMESPACE::testing::FPTest<double>;
15 using LIBC_NAMESPACE::fputil::testing::ForceRoundingMode;
16 using LIBC_NAMESPACE::fputil::testing::RoundingMode;
17 
TEST_F(LlvmLibcPowTest,SpecialNumbers)18 TEST_F(LlvmLibcPowTest, SpecialNumbers) {
19   constexpr double NEG_ODD_INTEGER = -3.0;
20   constexpr double NEG_EVEN_INTEGER = -6.0;
21   constexpr double NEG_NON_INTEGER = -1.1;
22   constexpr double POS_ODD_INTEGER = 5.0;
23   constexpr double POS_EVEN_INTEGER = 8.0;
24   constexpr double POS_NON_INTEGER = 1.1;
25   constexpr double ONE_HALF = 0.5;
26 
27   for (int i = 0; i < N_ROUNDING_MODES; ++i) {
28     ForceRoundingMode __r(ROUNDING_MODES[i]);
29     if (!__r.success)
30       continue;
31 
32     // pow( 0.0, exponent )
33     EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, NEG_ODD_INTEGER),
34                                 FE_DIVBYZERO);
35     EXPECT_FP_EQ_WITH_EXCEPTION(
36         inf, LIBC_NAMESPACE::pow(zero, NEG_EVEN_INTEGER), FE_DIVBYZERO);
37     EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, NEG_NON_INTEGER),
38                                 FE_DIVBYZERO);
39     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_ODD_INTEGER));
40     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_EVEN_INTEGER));
41     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_NON_INTEGER));
42     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, ONE_HALF));
43     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(zero, zero));
44     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(zero, neg_zero));
45     EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(zero, inf));
46     EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, neg_inf),
47                                 FE_DIVBYZERO);
48     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(zero, aNaN));
49 
50     // pow( -0.0, exponent )
51     EXPECT_FP_EQ_WITH_EXCEPTION(
52         neg_inf, LIBC_NAMESPACE::pow(neg_zero, NEG_ODD_INTEGER), FE_DIVBYZERO);
53     EXPECT_FP_EQ_WITH_EXCEPTION(
54         inf, LIBC_NAMESPACE::pow(neg_zero, NEG_EVEN_INTEGER), FE_DIVBYZERO);
55     EXPECT_FP_EQ_WITH_EXCEPTION(
56         inf, LIBC_NAMESPACE::pow(neg_zero, NEG_NON_INTEGER), FE_DIVBYZERO);
57     EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_zero, POS_ODD_INTEGER));
58     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, POS_EVEN_INTEGER));
59     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, POS_NON_INTEGER));
60     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, ONE_HALF));
61     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_zero, zero));
62     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_zero, neg_zero));
63     EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(neg_zero, inf));
64     EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(neg_zero, neg_inf),
65                                 FE_DIVBYZERO);
66     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_zero, aNaN));
67 
68     // pow( 1.0, exponent )
69     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, zero));
70     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_zero));
71     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, 1.0));
72     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, -1.0));
73     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_ODD_INTEGER));
74     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_EVEN_INTEGER));
75     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_NON_INTEGER));
76     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_ODD_INTEGER));
77     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_EVEN_INTEGER));
78     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_NON_INTEGER));
79     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, inf));
80     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_inf));
81     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, aNaN));
82 
83     // pow( 1.0, exponent )
84     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, zero));
85     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, neg_zero));
86     EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, 1.0));
87     EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, -1.0));
88     EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, NEG_ODD_INTEGER));
89     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, NEG_EVEN_INTEGER));
90     EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::pow(-1.0, NEG_NON_INTEGER),
91                                     FE_INVALID);
92     EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, POS_ODD_INTEGER));
93     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, POS_EVEN_INTEGER));
94     EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::pow(-1.0, POS_NON_INTEGER),
95                                     FE_INVALID);
96     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, inf));
97     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, neg_inf));
98     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(-1.0, aNaN));
99 
100     // pow( inf, exponent )
101     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, zero));
102     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, neg_zero));
103     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, 1.0));
104     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, -1.0));
105     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_ODD_INTEGER));
106     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_EVEN_INTEGER));
107     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_NON_INTEGER));
108     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_ODD_INTEGER));
109     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_EVEN_INTEGER));
110     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_NON_INTEGER));
111     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, ONE_HALF));
112     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, inf));
113     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, neg_inf));
114     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(inf, aNaN));
115 
116     // pow( -inf, exponent )
117     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, zero));
118     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, neg_zero));
119     EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::pow(neg_inf, 1.0));
120     EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_inf, -1.0));
121     EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_inf, NEG_ODD_INTEGER));
122     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, NEG_EVEN_INTEGER));
123     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, NEG_NON_INTEGER));
124     EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::pow(neg_inf, POS_ODD_INTEGER));
125     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, POS_EVEN_INTEGER));
126     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, POS_NON_INTEGER));
127     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, ONE_HALF));
128     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, inf));
129     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, neg_inf));
130     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_inf, aNaN));
131 
132     // pow ( aNaN, exponent )
133     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, zero));
134     EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, neg_zero));
135     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, 1.0));
136     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, -1.0));
137     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_ODD_INTEGER));
138     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_EVEN_INTEGER));
139     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_NON_INTEGER));
140     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_ODD_INTEGER));
141     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_EVEN_INTEGER));
142     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_NON_INTEGER));
143     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, inf));
144     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, neg_inf));
145     EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, aNaN));
146 
147     // pow ( base, inf )
148     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(0.1, inf));
149     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(-0.1, inf));
150     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(1.1, inf));
151     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(-1.1, inf));
152 
153     // pow ( base, -inf )
154     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(0.1, neg_inf));
155     EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(-0.1, neg_inf));
156     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(1.1, neg_inf));
157     EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(-1.1, neg_inf));
158 
159     // Exact powers of 2:
160     // TODO: Enable these tests when we use exp2.
161     // EXPECT_FP_EQ(0x1.0p15, LIBC_NAMESPACE::pow(2.0, 15.0));
162     // EXPECT_FP_EQ(0x1.0p126, LIBC_NAMESPACE::pow(2.0, 126.0));
163     // EXPECT_FP_EQ(0x1.0p-45, LIBC_NAMESPACE::pow(2.0, -45.0));
164     // EXPECT_FP_EQ(0x1.0p-126, LIBC_NAMESPACE::pow(2.0, -126.0));
165     // EXPECT_FP_EQ(0x1.0p-149, LIBC_NAMESPACE::pow(2.0, -149.0));
166 
167     // Exact powers of 10:
168     // TODO: Enable these tests when we use exp10
169     // EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(10.0, 0.0));
170     // EXPECT_FP_EQ(10.0, LIBC_NAMESPACE::pow(10.0, 1.0));
171     // EXPECT_FP_EQ(100.0, LIBC_NAMESPACE::pow(10.0, 2.0));
172     // EXPECT_FP_EQ(1000.0, LIBC_NAMESPACE::pow(10.0, 3.0));
173     // EXPECT_FP_EQ(10000.0, LIBC_NAMESPACE::pow(10.0, 4.0));
174     // EXPECT_FP_EQ(100000.0, LIBC_NAMESPACE::pow(10.0, 5.0));
175     // EXPECT_FP_EQ(1000000.0, LIBC_NAMESPACE::pow(10.0, 6.0));
176     // EXPECT_FP_EQ(10000000.0, LIBC_NAMESPACE::pow(10.0, 7.0));
177     // EXPECT_FP_EQ(100000000.0, LIBC_NAMESPACE::pow(10.0, 8.0));
178     // EXPECT_FP_EQ(1000000000.0, LIBC_NAMESPACE::pow(10.0, 9.0));
179     // EXPECT_FP_EQ(10000000000.0, LIBC_NAMESPACE::pow(10.0, 10.0));
180 
181     // Overflow / Underflow:
182     if (ROUNDING_MODES[i] != RoundingMode::Downward &&
183         ROUNDING_MODES[i] != RoundingMode::TowardZero) {
184       EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(3.1, 2001.0),
185                                   FE_OVERFLOW);
186     }
187     if (ROUNDING_MODES[i] != RoundingMode::Upward) {
188       EXPECT_FP_EQ_WITH_EXCEPTION(0.0, LIBC_NAMESPACE::pow(3.1, -2001.0),
189                                   FE_UNDERFLOW);
190     }
191   }
192 }
193 
194 #ifdef LIBC_TEST_FTZ_DAZ
195 
196 using namespace LIBC_NAMESPACE::testing;
197 
TEST_F(LlvmLibcPowTest,FTZMode)198 TEST_F(LlvmLibcPowTest, FTZMode) {
199   ModifyMXCSR mxcsr(FTZ);
200 
201   EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(-min_denormal, 0.5));
202   EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal));
203 }
204 
TEST_F(LlvmLibcPowTest,DAZMode)205 TEST_F(LlvmLibcPowTest, DAZMode) {
206   ModifyMXCSR mxcsr(DAZ);
207 
208   EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(-min_denormal, 0.5));
209   EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal));
210 }
211 
TEST_F(LlvmLibcPowTest,FTZDAZMode)212 TEST_F(LlvmLibcPowTest, FTZDAZMode) {
213   ModifyMXCSR mxcsr(FTZ | DAZ);
214 
215   EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(-min_denormal, 0.5));
216   EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal));
217 }
218 
219 #endif
220