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( 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 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 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 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