[libc][math] Implement asinhf function correctly rounded for all rounding modes.
[llvm-project.git] / libc / test / src / math / exhaustive / exhaustive_test.cpp
bloba6d8929560c9e107176c897fe32bbe1579e113f7
1 //===-- Exhaustive test template for math functions -------------*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
9 #include <atomic>
10 #include <fenv.h>
11 #include <functional>
12 #include <iostream>
13 #include <mutex>
14 #include <sstream>
15 #include <thread>
16 #include <vector>
18 #include "src/__support/FPUtil/FPBits.h"
20 #include "exhaustive_test.h"
22 template <typename T, typename FloatType>
23 void LlvmLibcExhaustiveTest<T, FloatType>::test_full_range(
24 T start, T stop, mpfr::RoundingMode rounding) {
25 int n_threads = std::thread::hardware_concurrency();
26 std::vector<std::thread> thread_list;
27 std::mutex mx_cur_val;
28 int current_percent = -1;
29 T current_value = start;
30 std::atomic<uint64_t> failed(0);
31 for (int i = 0; i < n_threads; ++i) {
32 thread_list.emplace_back([&, this]() {
33 while (true) {
34 T range_begin, range_end;
35 int new_percent = -1;
37 std::lock_guard<std::mutex> lock(mx_cur_val);
38 if (current_value == stop)
39 return;
41 range_begin = current_value;
42 if (stop >= increment && stop - increment >= current_value) {
43 range_end = current_value + increment;
44 } else {
45 range_end = stop;
47 current_value = range_end;
48 int pc = 100.0 * (range_end - start) / (stop - start);
49 if (current_percent != pc) {
50 new_percent = pc;
51 current_percent = pc;
54 if (new_percent >= 0) {
55 std::stringstream msg;
56 msg << new_percent << "% is in process \r";
57 std::cout << msg.str() << std::flush;
60 bool check_passed = check(range_begin, range_end, rounding);
61 if (!check_passed) {
62 std::stringstream msg;
63 msg << "Test failed in range: " << std::dec << range_begin << " to "
64 << range_end << " [0x" << std::hex << range_begin << ", 0x"
65 << range_end << "), [" << std::hexfloat
66 << static_cast<FloatType>(__llvm_libc::fputil::FPBits<FloatType>(
67 static_cast<T>(range_begin)))
68 << ", "
69 << static_cast<FloatType>(
70 __llvm_libc::fputil::FPBits<FloatType>(range_end))
71 << ") " << std::endl;
72 std::cerr << msg.str() << std::flush;
74 failed.fetch_add(1);
77 });
80 for (auto &thread : thread_list) {
81 if (thread.joinable()) {
82 thread.join();
85 std::cout << std::endl;
86 std::cout << "Test " << ((failed > 0) ? "FAILED" : "PASSED") << std::endl;
87 ASSERT_EQ(failed.load(), uint64_t(0));
90 template void
91 LlvmLibcExhaustiveTest<uint32_t>::test_full_range(uint32_t, uint32_t,
92 mpfr::RoundingMode);
93 template void LlvmLibcExhaustiveTest<uint64_t, double>::test_full_range(
94 uint64_t, uint64_t, mpfr::RoundingMode);