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