71 changes: 13 additions & 58 deletions libc/test/src/math/exhaustive/atanf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,72 +7,27 @@
//===----------------------------------------------------------------------===//

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

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcAtanfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Atan, x, __llvm_libc::atanf(x),
0.5, rounding);
} while (bits++ < stop);
return result;
}
};

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

// Range: [0, 1.0];
static const uint32_t POS_START = 0x0000'0000U;
static const uint32_t POS_STOP = FPBits::inf().uintval();
using LlvmLibcAtanfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Atan,
__llvm_libc::atanf>;

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

TEST_F(LlvmLibcAtanfExhaustiveTest, PostiveRangeRoundUp) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Upward);
}
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcAtanfExhaustiveTest, PostiveRangeRoundDown) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Downward);
TEST_F(LlvmLibcAtanfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

TEST_F(LlvmLibcAtanfExhaustiveTest, 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 = FPBits::neg_inf().uintval();

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

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

TEST_F(LlvmLibcAtanfExhaustiveTest, NegativeRangeRoundDown) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

TEST_F(LlvmLibcAtanfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcAtanfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
58 changes: 7 additions & 51 deletions libc/test/src/math/exhaustive/atanhf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,68 +11,24 @@
#include "src/math/atanhf.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcAtanhfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Atanh, x,
__llvm_libc::atanhf(x), 0.5, rounding);
} while (bits++ < stop);
return result;
}
};

static const int NUM_THREADS = std::thread::hardware_concurrency();
using LlvmLibcAtanhfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Atanh,
__llvm_libc::atanhf>;

// Range: [0, 1.0];
static const uint32_t POS_START = 0x0000'0000U;
static const uint32_t POS_STOP = FPBits(1.0f).uintval();

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

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

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

TEST_F(LlvmLibcAtanhfExhaustiveTest, PostiveRangeRoundTowardZero) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcAtanhfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

// Range: [-1.0, 0];
static const uint32_t NEG_START = 0x8000'0000U;
static const uint32_t NEG_STOP = FPBits(-1.0f).uintval();

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

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

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

TEST_F(LlvmLibcAtanhfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcAtanhfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
65 changes: 10 additions & 55 deletions libc/test/src/math/exhaustive/cosf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,72 +7,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/cosf.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcCosfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
bool r = TEST_MPFR_MATCH(mpfr::Operation::Cos, x, __llvm_libc::cosf(x),
0.5, rounding);
result &= r;
} while (++bits < stop);
return result;
}
};
using LlvmLibcCosfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Cos,
__llvm_libc::cosf>;

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

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

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

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

TEST_F(LlvmLibcCosfExhaustiveTest, PostiveRangeRoundTowardZero) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcCosfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

// Range: (-Inf, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

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

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

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

TEST_F(LlvmLibcCosfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcCosfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
48 changes: 12 additions & 36 deletions libc/test/src/math/exhaustive/coshf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/coshf.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcCoshfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Cosh, x, __llvm_libc::coshf(x),
0.5, rounding);
} while (bits++ < stop);
return result;
}
};
using LlvmLibcCoshfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Cosh,
__llvm_libc::coshf>;

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

TEST_F(LlvmLibcCoshfExhaustiveTest, PostiveRangeRoundNearestTieToEven) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Nearest);
TEST_F(LlvmLibcCoshfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

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

TEST_F(LlvmLibcCoshfExhaustiveTest, PostiveRangeRoundDown) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Downward);
}
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

TEST_F(LlvmLibcCoshfExhaustiveTest, PostiveRangeRoundTowardZero) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcCoshfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
94 changes: 0 additions & 94 deletions libc/test/src/math/exhaustive/exhaustive_test.cpp

This file was deleted.

163 changes: 151 additions & 12 deletions libc/test/src/math/exhaustive/exhaustive_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,164 @@

#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FPBits.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <atomic>
#include <functional>
#include <iostream>
#include <mutex>
#include <sstream>
#include <thread>
#include <vector>

// To test exhaustively for inputs in the range [start, stop) in parallel:
// 1. Inherit from LlvmLibcExhaustiveTest class
// 2. Overide the test method: void check(T, T, RoundingMode)
// 4. Call: test_full_range(start, stop, nthreads, rounding)
// 1. Define a Checker class with:
// - FloatType: define floating point type to be used.
// - FPBits: fputil::FPBits<FloatType>.
// - UIntType: define bit type for the corresponding floating point type.
// - uint64_t check(start, stop, rounding_mode): a method to test in given
// range for a given rounding mode, which returns the number of
// failures.
// 2. Use LlvmLibcExhaustiveMathTest<Checker> class
// 3. Call: test_full_range(start, stop, nthreads, rounding)
// or test_full_range_all_roundings(start, stop).
// * For single input single output math function, use the convenient template:
// LlvmLibcUnaryOpExhaustiveMathTest<FloatType, Op, Func>.
namespace mpfr = __llvm_libc::testing::mpfr;

template <typename T, typename FloatType = float>
struct LlvmLibcExhaustiveTest : public __llvm_libc::testing::Test {
static constexpr T increment = (1 << 20);
static_assert(
__llvm_libc::cpp::is_same_v<
T, typename __llvm_libc::fputil::FPBits<FloatType>::UIntType>,
"Types are not consistent");
template <typename T> using UnaryOp = T(T);

template <typename T, mpfr::Operation Op, UnaryOp<T> Func>
struct UnaryOpChecker : public virtual __llvm_libc::testing::Test {
using FloatType = T;
using FPBits = __llvm_libc::fputil::FPBits<FloatType>;
using UIntType = typename FPBits::UIntType;

static constexpr UnaryOp<FloatType> *FUNC = Func;

// Check in a range, return the number of failures.
uint64_t check(UIntType start, UIntType stop, mpfr::RoundingMode rounding) {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return (stop > start);
UIntType bits = start;
uint64_t failed = 0;
do {
FPBits xbits(bits);
FloatType x = FloatType(xbits);
bool correct =
TEST_MPFR_MATCH_ROUNDING_SILENTLY(Op, x, FUNC(x), 0.5, rounding);
failed += (!correct);
// Uncomment to print out failed values.
// if (!correct) {
// TEST_MPFR_MATCH(Op::Operation, x, Op::func(x), 0.5, rounding);
// }
} while (bits++ < stop);
return failed;
}
};

// Checker class needs inherit from __llvm_libc::testing::Test and provide
// UIntType and check method.
template <typename Checker>
struct LlvmLibcExhaustiveMathTest : public virtual __llvm_libc::testing::Test,
public Checker {
using FloatType = typename Checker::FloatType;
using FPBits = typename Checker::FPBits;
using UIntType = typename Checker::UIntType;

static constexpr UIntType INCREMENT = (1 << 20);

// Break [start, stop) into `nthreads` subintervals and apply *check to each
// subinterval in parallel.
void test_full_range(T start, T stop, mpfr::RoundingMode rounding);
void test_full_range(UIntType start, UIntType stop,
mpfr::RoundingMode rounding) {
int n_threads = std::thread::hardware_concurrency();
std::vector<std::thread> thread_list;
std::mutex mx_cur_val;
int current_percent = -1;
UIntType current_value = start;
std::atomic<uint64_t> failed(0);

for (int i = 0; i < n_threads; ++i) {
thread_list.emplace_back([&, this]() {
while (true) {
UIntType range_begin, range_end;
int new_percent = -1;
{
std::lock_guard<std::mutex> lock(mx_cur_val);
if (current_value == stop)
return;

virtual bool check(T start, T stop, mpfr::RoundingMode rounding) = 0;
range_begin = current_value;
if (stop >= INCREMENT && stop - INCREMENT >= current_value) {
range_end = current_value + INCREMENT;
} else {
range_end = stop;
}
current_value = range_end;
int pc = 100.0 * (range_end - start) / (stop - start);
if (current_percent != pc) {
new_percent = pc;
current_percent = pc;
}
}
if (new_percent >= 0) {
std::stringstream msg;
msg << new_percent << "% is in process \r";
std::cout << msg.str() << std::flush;
}

uint64_t failed_in_range =
Checker::check(range_begin, range_end, rounding);
if (failed_in_range > 0) {
std::stringstream msg;
msg << "Test failed for " << std::dec << failed_in_range
<< " inputs in range: " << range_begin << " to " << range_end
<< " [0x" << std::hex << range_begin << ", 0x" << range_end
<< "), [" << std::hexfloat
<< static_cast<FloatType>(FPBits(range_begin)) << ", "
<< static_cast<FloatType>(FPBits(range_end)) << ")\n";
std::cerr << msg.str() << std::flush;

failed.fetch_add(failed_in_range);
}
}
});
}

for (auto &thread : thread_list) {
if (thread.joinable()) {
thread.join();
}
}

std::cout << std::endl;
std::cout << "Test " << ((failed > 0) ? "FAILED" : "PASSED") << std::endl;
ASSERT_EQ(failed.load(), uint64_t(0));
}

void test_full_range_all_roundings(UIntType start, UIntType stop) {
std::cout << "-- Testing for FE_TONEAREST in range [0x" << std::hex << start
<< ", 0x" << stop << ") --" << std::dec << std::endl;
test_full_range(start, stop, mpfr::RoundingMode::Nearest);

std::cout << "-- Testing for FE_UPWARD in range [0x" << std::hex << start
<< ", 0x" << stop << ") --" << std::dec << std::endl;
test_full_range(start, stop, mpfr::RoundingMode::Upward);

std::cout << "-- Testing for FE_DOWNWARD in range [0x" << std::hex << start
<< ", 0x" << stop << ") --" << std::dec << std::endl;
test_full_range(start, stop, mpfr::RoundingMode::Downward);

std::cout << "-- Testing for FE_TOWARDZERO in range [0x" << std::hex
<< start << ", 0x" << stop << ") --" << std::dec << std::endl;
test_full_range(start, stop, mpfr::RoundingMode::TowardZero);
};
};

template <typename FloatType, mpfr::Operation Op, UnaryOp<FloatType> Func>
using LlvmLibcUnaryOpExhaustiveMathTest =
LlvmLibcExhaustiveMathTest<UnaryOpChecker<FloatType, Op, Func>>;
68 changes: 12 additions & 56 deletions libc/test/src/math/exhaustive/exp10f_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,71 +7,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/exp10f.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcExp10fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Exp10, x,
__llvm_libc::exp10f(x), 0.5, rounding);
} while (bits++ < stop);
return result;
}
};
using LlvmLibcExp10fExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Exp10,
__llvm_libc::exp10f>;

// Range: [0, 89];
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x42b2'0000U;

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

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

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

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

// Range: [-104, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
static constexpr uint32_t NEG_STOP = 0xc2d0'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcExp10fExhaustiveTest, NegativeRangeRoundNearestTieToEven) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Nearest);
TEST_F(LlvmLibcExp10fExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

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

TEST_F(LlvmLibcExp10fExhaustiveTest, NegativeRangeRoundDown) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

TEST_F(LlvmLibcExp10fExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcExp10fExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
60 changes: 9 additions & 51 deletions libc/test/src/math/exhaustive/exp2f_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,69 +7,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/exp2f.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcExp2fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x),
0.5, rounding);
} while (bits++ < stop);
return result;
}
};
using LlvmLibcExp2fExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Exp2,
__llvm_libc::exp2f>;

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

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

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

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

TEST_F(LlvmLibcExp2fExhaustiveTest, PostiveRangeRoundTowardZero) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcExp2fExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

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

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

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

TEST_F(LlvmLibcExp2fExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcExp2fExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
68 changes: 12 additions & 56 deletions libc/test/src/math/exhaustive/expf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,71 +7,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/expf.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcExpfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x),
0.5, rounding);
} while (bits++ < stop);
return result;
}
};
using LlvmLibcExpfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Exp,
__llvm_libc::expf>;

// Range: [0, 89];
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x42b2'0000U;

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

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

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

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

// Range: [-104, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
static constexpr uint32_t NEG_STOP = 0xc2d0'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcExpfExhaustiveTest, NegativeRangeRoundNearestTieToEven) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Nearest);
TEST_F(LlvmLibcExpfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

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

TEST_F(LlvmLibcExpfExhaustiveTest, NegativeRangeRoundDown) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

TEST_F(LlvmLibcExpfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcExpfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
68 changes: 12 additions & 56 deletions libc/test/src/math/exhaustive/expm1f_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,71 +7,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/expm1f.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcExpm1fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = stop;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Expm1, x,
__llvm_libc::expm1f(x), 0.5, rounding);
} while (bits-- > start);
return result;
}
};
using LlvmLibcExpm1fExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Expm1,
__llvm_libc::expm1f>;

// Range: [0, 89];
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x42b2'0000U;

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

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

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

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

// Range: [-104, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
static constexpr uint32_t NEG_STOP = 0xc2d0'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcExpm1fExhaustiveTest, NegativeRangeRoundNearestTieToEven) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Nearest);
TEST_F(LlvmLibcExpm1fExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

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

TEST_F(LlvmLibcExpm1fExhaustiveTest, NegativeRangeRoundDown) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

TEST_F(LlvmLibcExpm1fExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcExpm1fExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
44 changes: 18 additions & 26 deletions libc/test/src/math/exhaustive/hypotf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcHypotfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
struct HypotfChecker : public virtual __llvm_libc::testing::Test {
using FloatType = float;
using FPBits = __llvm_libc::fputil::FPBits<float>;
using UIntType = typename FPBits::UIntType;

uint64_t check(uint32_t start, uint32_t stop, mpfr::RoundingMode rounding) {
// Range of the second input: [2^37, 2^48).
constexpr uint32_t Y_START = (37U + 127U) << 23;
constexpr uint32_t Y_STOP = (48U + 127U) << 23;
Expand All @@ -28,41 +29,32 @@ struct LlvmLibcHypotfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
if (!r.success)
return true;
uint32_t xbits = start;
bool result = true;
uint64_t failed = 0;
do {
float x = float(FPBits(xbits));
uint32_t ybits = Y_START;
do {
float y = float(FPBits(ybits));
result &= TEST_FP_EQ(__llvm_libc::fputil::hypot(x, y),
__llvm_libc::hypotf(x, y));
bool correct = TEST_FP_EQ(__llvm_libc::fputil::hypot(x, y),
__llvm_libc::hypotf(x, y));
// Using MPFR will be much slower.
// mpfr::BinaryInput<float> input{x, y};
// EXPECT_MPFR_MATCH(mpfr::Operation::Hypot, input,
// __llvm_libc::hypotf(x, y), 0.5,
// rounding);
// bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY(
// mpfr::Operation::Hypot, input, __llvm_libc::hypotf(x, y), 0.5,
// rounding);
failed += (!correct);
} while (ybits++ < Y_STOP);
} while (xbits++ < stop);
return result;
return failed;
}
};

using LlvmLibcHypotfExhaustiveTest = LlvmLibcExhaustiveMathTest<HypotfChecker>;

// Range of the first input: [2^23, 2^24);
static constexpr uint32_t START = (23U + 127U) << 23;
static constexpr uint32_t STOP = ((23U + 127U) << 23) + 1;

TEST_F(LlvmLibcHypotfExhaustiveTest, RoundNearestTieToEven) {
test_full_range(START, STOP, mpfr::RoundingMode::Nearest);
}

TEST_F(LlvmLibcHypotfExhaustiveTest, RoundUp) {
test_full_range(START, STOP, mpfr::RoundingMode::Upward);
}

TEST_F(LlvmLibcHypotfExhaustiveTest, RoundDown) {
test_full_range(START, STOP, mpfr::RoundingMode::Downward);
}

TEST_F(LlvmLibcHypotfExhaustiveTest, RoundTowardZero) {
test_full_range(START, STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcHypotfExhaustiveTest, PositiveRange) {
test_full_range_all_roundings(START, STOP);
}
48 changes: 8 additions & 40 deletions libc/test/src/math/exhaustive/log10f_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,19 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/log10f.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcLog10fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Log10, x,
__llvm_libc::log10f(x), 0.5, rounding);
} while (bits++ < stop);
return result;
}
};

// Range: All non-negative;
static constexpr uint32_t START = 0x0000'0000U;
static constexpr uint32_t STOP = 0x7f80'0000U;
// Range: [1, 10];
// static constexpr uint32_t START = 0x3f80'0000U;
// static constexpr uint32_t STOP = 0x41c0'0000U;
TEST_F(LlvmLibcLog10fExhaustiveTest, RoundNearestTieToEven) {
test_full_range(START, STOP, mpfr::RoundingMode::Nearest);
}

TEST_F(LlvmLibcLog10fExhaustiveTest, RoundUp) {
test_full_range(START, STOP, mpfr::RoundingMode::Upward);
}
using LlvmLibcLog10fExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Log10,
__llvm_libc::log10f>;

TEST_F(LlvmLibcLog10fExhaustiveTest, RoundDown) {
test_full_range(START, STOP, mpfr::RoundingMode::Downward);
}
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcLog10fExhaustiveTest, RoundTowardZero) {
test_full_range(START, STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcLog10fExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}
64 changes: 11 additions & 53 deletions libc/test/src/math/exhaustive/log1pf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,69 +7,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/log1pf.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcLog1pfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Log1p, x,
__llvm_libc::log1pf(x), 0.5, rounding);
} while (bits++ < stop);
return result;
}
};

// Range: All non-negative;
static constexpr uint32_t START = 0x0000'0000U;
static constexpr uint32_t STOP = 0x7f80'0000U;

TEST_F(LlvmLibcLog1pfExhaustiveTest, RoundNearestTieToEven) {
test_full_range(START, STOP, mpfr::RoundingMode::Nearest);
}
using LlvmLibcLog1pfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Log1p,
__llvm_libc::log1pf>;

TEST_F(LlvmLibcLog1pfExhaustiveTest, RoundUp) {
test_full_range(START, STOP, mpfr::RoundingMode::Upward);
}

TEST_F(LlvmLibcLog1pfExhaustiveTest, RoundDown) {
test_full_range(START, STOP, mpfr::RoundingMode::Downward);
}
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcLog1pfExhaustiveTest, RoundTowardZero) {
test_full_range(START, STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcLog1pfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

// Range: [-1, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xbf7f'ffffU;

TEST_F(LlvmLibcLog1pfExhaustiveTest, NegativeRoundNearestTieToEven) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Nearest);
}

TEST_F(LlvmLibcLog1pfExhaustiveTest, NegativeRoundUp) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Upward);
}

TEST_F(LlvmLibcLog1pfExhaustiveTest, NegativeRoundDown) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}

TEST_F(LlvmLibcLog1pfExhaustiveTest, NegativeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcLog1pfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
46 changes: 8 additions & 38 deletions libc/test/src/math/exhaustive/log2f_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,19 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/log2f.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcLog2fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Log2, x, __llvm_libc::log2f(x),
0.5, rounding);
} while (bits++ < stop);
return result;
}
};

TEST_F(LlvmLibcLog2fExhaustiveTest, RoundNearestTieToEven) {
test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Nearest);
}

TEST_F(LlvmLibcLog2fExhaustiveTest, RoundUp) {
test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Upward);
}
using LlvmLibcLog2fExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Log2,
__llvm_libc::log2f>;

TEST_F(LlvmLibcLog2fExhaustiveTest, RoundDown) {
test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Downward);
}
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcLog2fExhaustiveTest, RoundTowardZero) {
test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcLog2fExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}
46 changes: 8 additions & 38 deletions libc/test/src/math/exhaustive/logf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,19 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/logf.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcLogfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Log, x, __llvm_libc::logf(x),
0.5, rounding);
} while (bits++ < stop);
return result;
}
};

TEST_F(LlvmLibcLogfExhaustiveTest, RoundNearestTieToEven) {
test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Nearest);
}

TEST_F(LlvmLibcLogfExhaustiveTest, RoundUp) {
test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Upward);
}
using LlvmLibcLogfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Log,
__llvm_libc::logf>;

TEST_F(LlvmLibcLogfExhaustiveTest, RoundDown) {
test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Downward);
}
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcLogfExhaustiveTest, RoundTowardZero) {
test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcLogfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}
86 changes: 34 additions & 52 deletions libc/test/src/math/exhaustive/sincosf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,73 +7,55 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/sincosf.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcSinCosfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
struct SincosfChecker : public virtual __llvm_libc::testing::Test {
using FloatType = float;
using FPBits = __llvm_libc::fputil::FPBits<float>;
using UIntType = uint32_t;

uint64_t check(UIntType start, UIntType stop, mpfr::RoundingMode rounding) {
UIntType bits = start;
uint64_t failed = 0;
do {
FPBits xbits(bits);
float x = float(xbits);
float sinx, cosx;
FloatType x = FloatType(xbits);
FloatType sinx, cosx;
__llvm_libc::sincosf(x, &sinx, &cosx);
result &= TEST_MPFR_MATCH(mpfr::Operation::Sin, x, sinx, 0.5, rounding);
result &= TEST_MPFR_MATCH(mpfr::Operation::Cos, x, cosx, 0.5, rounding);
} while (++bits < stop);
return result;

bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY(mpfr::Operation::Sin, x,
sinx, 0.5, rounding);
correct = correct && TEST_MPFR_MATCH_ROUNDING_SILENTLY(
mpfr::Operation::Cos, x, cosx, 0.5, rounding);
failed += (!correct);
// Uncomment to print out failed values.
// if (!correct) {
// TEST_MPFR_MATCH(mpfr::Operation::Sin, x, sinx, 0.5, rounding);
// TEST_MPFR_MATCH(mpfr::Operation::Cos, x, cosx, 0.5, rounding);
// }
} while (bits++ < stop);
return failed;
}
};

// Range: [0, +Inf);
using LlvmLibcSincosfExhaustiveTest =
LlvmLibcExhaustiveMathTest<SincosfChecker>;

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

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

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

TEST_F(LlvmLibcSinCosfExhaustiveTest, PostiveRangeRoundDown) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Downward);
TEST_F(LlvmLibcSincosfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

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

// Range: (-Inf, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

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

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

TEST_F(LlvmLibcSinCosfExhaustiveTest, NegativeRangeRoundDown) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
// Range: [-1, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xbf7f'ffffU;

TEST_F(LlvmLibcSinCosfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcSincosfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
65 changes: 10 additions & 55 deletions libc/test/src/math/exhaustive/sinf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,72 +7,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/sinf.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcSinfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
bool r = TEST_MPFR_MATCH(mpfr::Operation::Sin, x, __llvm_libc::sinf(x),
0.5, rounding);
result &= r;
} while (++bits < stop);
return result;
}
};
using LlvmLibcSinfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Sin,
__llvm_libc::sinf>;

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

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

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

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

TEST_F(LlvmLibcSinfExhaustiveTest, PostiveRangeRoundTowardZero) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcSinfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

// Range: (-Inf, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

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

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

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

TEST_F(LlvmLibcSinfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcSinfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
68 changes: 12 additions & 56 deletions libc/test/src/math/exhaustive/sinhf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,71 +7,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/sinhf.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcSinhfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Sinh, x, __llvm_libc::sinhf(x),
0.5, rounding);
} while (bits++ < stop);
return result;
}
};
using LlvmLibcSinhfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Sinh,
__llvm_libc::sinhf>;

// Range: [0, 90];
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x42b4'0000U;

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

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

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

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

// Range: [-90, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
static constexpr uint32_t NEG_STOP = 0xc2b4'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcSinhfExhaustiveTest, NegativeRangeRoundNearestTieToEven) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Nearest);
TEST_F(LlvmLibcSinhfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

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

TEST_F(LlvmLibcSinhfExhaustiveTest, NegativeRangeRoundDown) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

TEST_F(LlvmLibcSinhfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcSinhfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
22 changes: 11 additions & 11 deletions libc/test/src/math/exhaustive/sqrtf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
//
//===---------------------------------------------------------------------===//

#include "src/__support/FPUtil/FPBits.h"
#include "exhaustive_test.h"
#include "src/math/sqrtf.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
#include <math.h>

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

namespace mpfr = __llvm_libc::testing::mpfr;

TEST(LlvmLibcSqrtfExhaustiveTest, AllValues) {
uint32_t bits = 0;
do {
FPBits xbits(bits);
float x = float(xbits);
ASSERT_MPFR_MATCH(mpfr::Operation::Sqrt, x, __llvm_libc::sqrtf(x), 0.5);
} while (bits++ < 0xffff'ffffU);
using LlvmLibcSqrtfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Sqrt,
__llvm_libc::sqrtf>;

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

TEST_F(LlvmLibcSqrtfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}
72 changes: 10 additions & 62 deletions libc/test/src/math/exhaustive/tanf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,79 +8,27 @@
//===----------------------------------------------------------------------===//

#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/tanf.h"
#include "test/UnitTest/FPMatcher.h"
#include "utils/MPFRWrapper/MPFRUtils.h"

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

static constexpr int TOLERANCE = 3;
using LlvmLibcTanfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Tan,
__llvm_libc::tanf>;

struct LlvmLibcTanfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
int tol = TOLERANCE;
do {
FPBits xbits(bits);
float x = float(xbits);
bool r = TEST_MPFR_MATCH(mpfr::Operation::Tan, x, __llvm_libc::tanf(x),
0.5, rounding);
result &= r;
if (!r)
--tol;
if (!tol)
break;
} while (++bits < stop);
return result;
}
};

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

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

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

TEST_F(LlvmLibcTanfExhaustiveTest, PostiveRangeRoundDown) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Downward);
TEST_F(LlvmLibcTanfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

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

// Range: (-Inf, 0];
static constexpr uint32_t NEG_START = 0x8000'0000U;
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

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

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

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

TEST_F(LlvmLibcTanfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcTanfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}
71 changes: 13 additions & 58 deletions libc/test/src/math/exhaustive/tanhf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,72 +7,27 @@
//===----------------------------------------------------------------------===//

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

#include <thread>

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

namespace mpfr = __llvm_libc::testing::mpfr;

struct LlvmLibcTanhfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
bool check(uint32_t start, uint32_t stop,
mpfr::RoundingMode rounding) override {
mpfr::ForceRoundingMode r(rounding);
if (!r.success)
return true;
uint32_t bits = start;
bool result = true;
do {
FPBits xbits(bits);
float x = float(xbits);
result &= TEST_MPFR_MATCH(mpfr::Operation::Tanh, x, __llvm_libc::tanhf(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 = FPBits::inf(false).uintval();
using LlvmLibcTanhfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Tanh,
__llvm_libc::tanhf>;

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

TEST_F(LlvmLibcTanhfExhaustiveTest, PostiveRangeRoundUp) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Upward);
}
// Range: [0, Inf];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x7f80'0000U;

TEST_F(LlvmLibcTanhfExhaustiveTest, PostiveRangeRoundDown) {
test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Downward);
TEST_F(LlvmLibcTanhfExhaustiveTest, PostiveRange) {
test_full_range_all_roundings(POS_START, POS_STOP);
}

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

// Range: [-INF, 0];
static const uint32_t NEG_START = 0x8000'0000U;
static const uint32_t NEG_STOP = FPBits::inf(true).uintval();

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

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

TEST_F(LlvmLibcTanhfExhaustiveTest, NegativeRangeRoundDown) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
// Range: [-Inf, 0];
static constexpr uint32_t NEG_START = 0xb000'0000U;
static constexpr uint32_t NEG_STOP = 0xff80'0000U;

TEST_F(LlvmLibcTanhfExhaustiveTest, NegativeRangeRoundTowardZero) {
test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
TEST_F(LlvmLibcTanhfExhaustiveTest, NegativeRange) {
test_full_range_all_roundings(NEG_START, NEG_STOP);
}