1 //===-- Unittests for atanhf ----------------------------------------------===// 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/errno/libc_errno.h" 12 #include "src/math/atanhf.h" 13 #include "test/UnitTest/FPMatcher.h" 14 #include "test/UnitTest/Test.h" 15 #include "utils/MPFRWrapper/MPFRUtils.h" 16 17 #include <stdint.h> 18 19 using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>; 20 using LIBC_NAMESPACE::Sign; 21 22 namespace mpfr = LIBC_NAMESPACE::testing::mpfr; 23 24 // TODO: This test needs to have its checks for exceptions, errno 25 // tightened https://github.com/llvm/llvm-project/issues/88819. 26 TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { 27 28 LIBC_NAMESPACE::libc_errno = 0; 29 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 30 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN)); 31 // TODO: Uncomment these checks later, RoundingMode affects running 32 // tests in this way https://github.com/llvm/llvm-project/issues/90653. 33 // EXPECT_FP_EXCEPTION(0); 34 EXPECT_MATH_ERRNO(0); 35 36 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 37 EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanhf(0.0f)); 38 // See above TODO 39 // EXPECT_FP_EXCEPTION(0); 40 EXPECT_MATH_ERRNO(0); 41 42 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 43 EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanhf(-0.0f)); 44 // See above TODO 45 // EXPECT_FP_EXCEPTION(0); 46 EXPECT_MATH_ERRNO(0); 47 48 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 49 EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::atanhf(1.0f)); 50 // See above TODO 51 // EXPECT_FP_EXCEPTION(FE_DIVBYZERO); 52 EXPECT_MATH_ERRNO(ERANGE); 53 54 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 55 EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, LIBC_NAMESPACE::atanhf(-1.0f)); 56 // See above TODO 57 // EXPECT_FP_EXCEPTION(FE_DIVBYZERO); 58 EXPECT_MATH_ERRNO(ERANGE); 59 60 auto bt = FPBits(1.0f); 61 bt.set_uintval(bt.uintval() + 1); 62 63 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 64 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val())); 65 // EXPECT_FP_EXCEPTION(FE_INVALID); 66 EXPECT_MATH_ERRNO(EDOM); 67 68 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 69 bt.set_sign(Sign::NEG); 70 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val())); 71 // See above TODO 72 // EXPECT_FP_EXCEPTION(FE_INVALID); 73 EXPECT_MATH_ERRNO(EDOM); 74 75 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 76 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(2.0f)); 77 // See above TODO 78 // EXPECT_FP_EXCEPTION(FE_INVALID); 79 EXPECT_MATH_ERRNO(EDOM); 80 81 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 82 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(-2.0f)); 83 // EXPECT_FP_EXCEPTION(FE_INVALID); 84 EXPECT_MATH_ERRNO(EDOM); 85 86 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); 87 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(inf)); 88 // See above TODO 89 // EXPECT_FP_EXCEPTION(FE_INVALID); 90 EXPECT_MATH_ERRNO(EDOM); 91 92 bt.set_sign(Sign::NEG); 93 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(neg_inf)); 94 // See above TODO 95 // EXPECT_FP_EXCEPTION(FE_INVALID); 96 EXPECT_MATH_ERRNO(EDOM); 97 } 98 99 TEST_F(LlvmLibcAtanhfTest, InFloatRange) { 100 constexpr uint32_t COUNT = 100'000; 101 const uint32_t STEP = FPBits(1.0f).uintval() / COUNT; 102 for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { 103 float x = FPBits(v).get_val(); 104 ASSERT_MPFR_MATCH(mpfr::Operation::Atanh, x, LIBC_NAMESPACE::atanhf(x), 105 0.5); 106 ASSERT_MPFR_MATCH(mpfr::Operation::Atanh, -x, LIBC_NAMESPACE::atanhf(-x), 107 0.5); 108 } 109 } 110 111 // For small values, atanh(x) is x. 112 TEST_F(LlvmLibcAtanhfTest, SmallValues) { 113 float x = FPBits(uint32_t(0x17800000)).get_val(); 114 float result = LIBC_NAMESPACE::atanhf(x); 115 EXPECT_MPFR_MATCH(mpfr::Operation::Atanh, x, result, 0.5); 116 EXPECT_FP_EQ(x, result); 117 118 x = FPBits(uint32_t(0x00400000)).get_val(); 119 result = LIBC_NAMESPACE::atanhf(x); 120 EXPECT_MPFR_MATCH(mpfr::Operation::Atanh, x, result, 0.5); 121 EXPECT_FP_EQ(x, result); 122 } 123