76 changes: 76 additions & 0 deletions libc/test/src/math/exhaustive/asinhf_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//===-- Exhaustive test for asinhf ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/asinhf.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

using FPBits = __llvm_libc::fputil::FPBits<float>;

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcAsinhfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= EXPECT_MPFR_MATCH(mpfr::Operation::Asinh, x,
__llvm_libc::asinhf(x), 0.5, rounding);
} while (bits++ < stop);
return result;
}
};

static const int NUM_THREADS = std::thread::hardware_concurrency();

// Range: [0, Inf];
static const uint32_t POS_START = 0x0000'0000U;
static const uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcAsinhfExhaustiveTest, PostiveRangeRoundNearestTieToEven) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Nearest);
}

TEST_F(LlvmLibcAsinhfExhaustiveTest, PostiveRangeRoundUp) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Upward);
}

TEST_F(LlvmLibcAsinhfExhaustiveTest, PostiveRangeRoundDown) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Downward);
}

TEST_F(LlvmLibcAsinhfExhaustiveTest, PostiveRangeRoundTowardZero) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::TowardZero);
}

// Range: [-1.0, 0];
static const uint32_t NEG_START = 0x8000'0000U;
static const uint32_t NEG_STOP = 0xff80'0000U;

TEST_F(LlvmLibcAsinhfExhaustiveTest, NegativeRangeRoundNearestTieToEven) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Nearest);
}

TEST_F(LlvmLibcAsinhfExhaustiveTest, NegativeRangeRoundUp) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Upward);
}

TEST_F(LlvmLibcAsinhfExhaustiveTest, NegativeRangeRoundDown) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}

TEST_F(LlvmLibcAsinhfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
}
7 changes: 4 additions & 3 deletions libc/test/src/math/exhaustive/exhaustive_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ void LlvmLibcExhaustiveTest<T, FloatType>::test_full_range(
range_begin = current_value;
if (stop >= increment && stop - increment >= current_value) {
range_end = current_value + increment;
} else
} else {
range_end = stop;
}
current_value = range_end;
int pc = 100.0 * double(range_end - start) / double(stop - start);
int pc = 100.0 * (range_end - start) / (stop - start);
if (current_percent != pc) {
new_percent = pc;
current_percent = pc;
Expand All @@ -54,7 +55,6 @@ void LlvmLibcExhaustiveTest<T, FloatType>::test_full_range(
std::stringstream msg;
msg << new_percent << "% is in process \r";
std::cout << msg.str() << std::flush;
;
}

bool check_passed = check(range_begin, range_end, rounding);
Expand Down Expand Up @@ -84,6 +84,7 @@ void LlvmLibcExhaustiveTest<T, FloatType>::test_full_range(
}
std::cout << std::endl;
std::cout << "Test " << ((failed > 0) ? "FAILED" : "PASSED") << std::endl;
ASSERT_EQ(failed.load(), uint64_t(0));
}

template void
Expand Down
7 changes: 7 additions & 0 deletions libc/utils/MPFRWrapper/MPFRUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ class MPFRNumber {
return result;
}

MPFRNumber asinh() const {
MPFRNumber result(*this);
mpfr_asinh(result.value, value, mpfr_rounding);
return result;
}
MPFRNumber atan() const {
MPFRNumber result(*this);
mpfr_atan(result.value, value, mpfr_rounding);
Expand Down Expand Up @@ -542,6 +547,8 @@ unary_operation(Operation op, InputType input, unsigned int precision,
return mpfrInput.acos();
case Operation::Asin:
return mpfrInput.asin();
case Operation::Asinh:
return mpfrInput.asinh();
case Operation::Atan:
return mpfrInput.atan();
case Operation::Atanh:
Expand Down
1 change: 1 addition & 0 deletions libc/utils/MPFRWrapper/MPFRUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum class Operation : int {
Abs,
Acos,
Asin,
Asinh,
Atan,
Atanh,
Ceil,
Expand Down