1f1ec99f9STue Ly //===-- Exhaustive test for hypotf ----------------------------------------===//
2f1ec99f9STue Ly //
3f1ec99f9STue Ly // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f1ec99f9STue Ly // See https://llvm.org/LICENSE.txt for license information.
5f1ec99f9STue Ly // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f1ec99f9STue Ly //
7f1ec99f9STue Ly //===----------------------------------------------------------------------===//
8f1ec99f9STue Ly 
9f1ec99f9STue Ly #include "exhaustive_test.h"
10f1ec99f9STue Ly #include "src/__support/FPUtil/FPBits.h"
11f1ec99f9STue Ly #include "src/__support/FPUtil/Hypot.h"
12f1ec99f9STue Ly #include "src/math/hypotf.h"
13f1ec99f9STue Ly #include "utils/MPFRWrapper/MPFRUtils.h"
14f1ec99f9STue Ly #include "utils/UnitTest/FPMatcher.h"
15f1ec99f9STue Ly 
16f1ec99f9STue Ly using FPBits = __llvm_libc::fputil::FPBits<float>;
17f1ec99f9STue Ly 
18f1ec99f9STue Ly namespace mpfr = __llvm_libc::testing::mpfr;
19f1ec99f9STue Ly 
20f1ec99f9STue Ly struct LlvmLibcHypotfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
checkLlvmLibcHypotfExhaustiveTest214c9bfec6STue Ly   bool check(uint32_t start, uint32_t stop,
22f1ec99f9STue Ly              mpfr::RoundingMode rounding) override {
23f1ec99f9STue Ly     // Range of the second input: [2^37, 2^48).
24f1ec99f9STue Ly     constexpr uint32_t Y_START = (37U + 127U) << 23;
25f1ec99f9STue Ly     constexpr uint32_t Y_STOP = (48U + 127U) << 23;
26f1ec99f9STue Ly 
27f1ec99f9STue Ly     mpfr::ForceRoundingMode r(rounding);
28f1ec99f9STue Ly     uint32_t xbits = start;
294c9bfec6STue Ly     bool result = true;
30f1ec99f9STue Ly     do {
31f1ec99f9STue Ly       float x = float(FPBits(xbits));
32f1ec99f9STue Ly       uint32_t ybits = Y_START;
33f1ec99f9STue Ly       do {
34f1ec99f9STue Ly         float y = float(FPBits(ybits));
354c9bfec6STue Ly         result &= EXPECT_FP_EQ(__llvm_libc::fputil::hypot(x, y),
36f1ec99f9STue Ly                                __llvm_libc::hypotf(x, y));
37f1ec99f9STue Ly         // Using MPFR will be much slower.
38f1ec99f9STue Ly         // mpfr::BinaryInput<float> input{x, y};
39f1ec99f9STue Ly         // EXPECT_MPFR_MATCH(mpfr::Operation::Hypot, input,
40f1ec99f9STue Ly         // __llvm_libc::hypotf(x, y), 0.5,
41f1ec99f9STue Ly         //                   rounding);
42f1ec99f9STue Ly       } while (ybits++ < Y_STOP);
43f1ec99f9STue Ly     } while (xbits++ < stop);
444c9bfec6STue Ly     return result;
45f1ec99f9STue Ly   }
46f1ec99f9STue Ly };
47f1ec99f9STue Ly 
48f1ec99f9STue Ly // Range of the first input: [2^23, 2^24);
49f1ec99f9STue Ly static constexpr uint32_t START = (23U + 127U) << 23;
50f1ec99f9STue Ly static constexpr uint32_t STOP = ((23U + 127U) << 23) + 1;
51f1ec99f9STue Ly 
TEST_F(LlvmLibcHypotfExhaustiveTest,RoundNearestTieToEven)52f1ec99f9STue Ly TEST_F(LlvmLibcHypotfExhaustiveTest, RoundNearestTieToEven) {
53*fdf1fda5SKirill Okhotnikov   test_full_range(START, STOP, mpfr::RoundingMode::Nearest);
54f1ec99f9STue Ly }
55f1ec99f9STue Ly 
TEST_F(LlvmLibcHypotfExhaustiveTest,RoundUp)56f1ec99f9STue Ly TEST_F(LlvmLibcHypotfExhaustiveTest, RoundUp) {
57*fdf1fda5SKirill Okhotnikov   test_full_range(START, STOP, mpfr::RoundingMode::Upward);
58f1ec99f9STue Ly }
59f1ec99f9STue Ly 
TEST_F(LlvmLibcHypotfExhaustiveTest,RoundDown)60f1ec99f9STue Ly TEST_F(LlvmLibcHypotfExhaustiveTest, RoundDown) {
61*fdf1fda5SKirill Okhotnikov   test_full_range(START, STOP, mpfr::RoundingMode::Downward);
62f1ec99f9STue Ly }
63f1ec99f9STue Ly 
TEST_F(LlvmLibcHypotfExhaustiveTest,RoundTowardZero)64f1ec99f9STue Ly TEST_F(LlvmLibcHypotfExhaustiveTest, RoundTowardZero) {
65*fdf1fda5SKirill Okhotnikov   test_full_range(START, STOP, mpfr::RoundingMode::TowardZero);
66f1ec99f9STue Ly }
67