diff options
author | OverMighty <its.overmighty@gmail.com> | 2024-07-01 14:45:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-01 08:45:36 -0400 |
commit | 44a2589cfc7fa2d3486f60000166a7dea0621494 (patch) | |
tree | c86ee748d0956d6846ca105a1c27b6e155c41905 /libc/test | |
parent | de68294b4dd31370773cb7a976b2d59e0e8b9bcc (diff) | |
download | llvm-44a2589cfc7fa2d3486f60000166a7dea0621494.zip llvm-44a2589cfc7fa2d3486f60000166a7dea0621494.tar.gz llvm-44a2589cfc7fa2d3486f60000166a7dea0621494.tar.bz2 |
[libc][math] Add MPFR unit tests for nearbyint{,f,l,f16} (#94479)
Diffstat (limited to 'libc/test')
-rw-r--r-- | libc/test/src/math/CMakeLists.txt | 60 | ||||
-rw-r--r-- | libc/test/src/math/NearbyIntTest.h | 118 | ||||
-rw-r--r-- | libc/test/src/math/nearbyint_test.cpp | 13 | ||||
-rw-r--r-- | libc/test/src/math/nearbyintf16_test.cpp | 13 | ||||
-rw-r--r-- | libc/test/src/math/nearbyintf_test.cpp | 13 | ||||
-rw-r--r-- | libc/test/src/math/nearbyintl_test.cpp | 13 |
6 files changed, 230 insertions, 0 deletions
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt index 1326d08..729d9fe 100644 --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -587,6 +587,66 @@ add_fp_unittest( ) add_fp_unittest( + nearbyint_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + nearbyint_test.cpp + HDRS + NearbyIntTest.h + DEPENDS + libc.src.math.nearbyint + libc.src.__support.CPP.algorithm + libc.src.__support.CPP.array +) + +add_fp_unittest( + nearbyintf_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + nearbyintf_test.cpp + HDRS + NearbyIntTest.h + DEPENDS + libc.src.math.nearbyintf + libc.src.__support.CPP.algorithm + libc.src.__support.CPP.array +) + +add_fp_unittest( + nearbyintl_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + nearbyintl_test.cpp + HDRS + NearbyIntTest.h + DEPENDS + libc.src.math.nearbyintl + libc.src.__support.CPP.algorithm + libc.src.__support.CPP.array +) + +add_fp_unittest( + nearbyintf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + nearbyintf16_test.cpp + HDRS + NearbyIntTest.h + DEPENDS + libc.src.math.nearbyintf16 + libc.src.__support.CPP.algorithm + libc.src.__support.CPP.array +) + +add_fp_unittest( rint_test NEED_MPFR SUITE diff --git a/libc/test/src/math/NearbyIntTest.h b/libc/test/src/math/NearbyIntTest.h new file mode 100644 index 0000000..88cdf45 --- /dev/null +++ b/libc/test/src/math/NearbyIntTest.h @@ -0,0 +1,118 @@ +//===-- Utility class to test different flavors of nearbyint ----*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TEST_SRC_MATH_NEARBYINTTEST_H +#define LLVM_LIBC_TEST_SRC_MATH_NEARBYINTTEST_H + +#include "src/__support/CPP/algorithm.h" +#include "src/__support/CPP/array.h" +#include "test/UnitTest/FEnvSafeTest.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +using namespace LIBC_NAMESPACE::fputil::testing; + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +template <typename T> +class NearbyIntTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest { + + DECLARE_SPECIAL_CONSTANTS(T) + + static constexpr LIBC_NAMESPACE::cpp::array<RoundingMode, 4> ROUNDING_MODES = + { + RoundingMode::Upward, + RoundingMode::Downward, + RoundingMode::TowardZero, + RoundingMode::Nearest, + }; + + static constexpr StorageType MIN_SUBNORMAL = + FPBits::min_subnormal().uintval(); + static constexpr StorageType MAX_SUBNORMAL = + FPBits::max_subnormal().uintval(); + static constexpr StorageType MIN_NORMAL = FPBits::min_normal().uintval(); + static constexpr StorageType MAX_NORMAL = FPBits::max_normal().uintval(); + +public: + using NearbyIntFunc = T (*)(T); + + void test_round_numbers(NearbyIntFunc func) { + for (RoundingMode mode : ROUNDING_MODES) { + if (ForceRoundingMode r(mode); r.success) { + EXPECT_FP_EQ(func(T(1.0)), mpfr::round(T(1.0), mode)); + EXPECT_FP_EQ(func(T(-1.0)), mpfr::round(T(-1.0), mode)); + EXPECT_FP_EQ(func(T(10.0)), mpfr::round(T(10.0), mode)); + EXPECT_FP_EQ(func(T(-10.0)), mpfr::round(T(-10.0), mode)); + EXPECT_FP_EQ(func(T(1234.0)), mpfr::round(T(1234.0), mode)); + EXPECT_FP_EQ(func(T(-1234.0)), mpfr::round(T(-1234.0), mode)); + } + } + } + + void test_fractions(NearbyIntFunc func) { + for (RoundingMode mode : ROUNDING_MODES) { + if (ForceRoundingMode r(mode); r.success) { + EXPECT_FP_EQ(func(T(0.5)), mpfr::round(T(0.5), mode)); + EXPECT_FP_EQ(func(T(-0.5)), mpfr::round(T(-0.5), mode)); + EXPECT_FP_EQ(func(T(0.115)), mpfr::round(T(0.115), mode)); + EXPECT_FP_EQ(func(T(-0.115)), mpfr::round(T(-0.115), mode)); + EXPECT_FP_EQ(func(T(0.715)), mpfr::round(T(0.715), mode)); + EXPECT_FP_EQ(func(T(-0.715)), mpfr::round(T(-0.715), mode)); + } + } + } + + void test_subnormal_range(NearbyIntFunc func) { + constexpr int COUNT = 100'001; + const StorageType STEP = LIBC_NAMESPACE::cpp::max( + static_cast<StorageType>((MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT), + StorageType(1)); + for (StorageType i = MIN_SUBNORMAL; i <= MAX_SUBNORMAL; i += STEP) { + T x = FPBits(i).get_val(); + for (RoundingMode mode : ROUNDING_MODES) { + if (ForceRoundingMode r(mode); r.success) { + EXPECT_FP_EQ(func(x), mpfr::round(x, mode)); + } + } + } + } + + void test_normal_range(NearbyIntFunc func) { + constexpr int COUNT = 100'001; + const StorageType STEP = LIBC_NAMESPACE::cpp::max( + static_cast<StorageType>((MAX_NORMAL - MIN_NORMAL) / COUNT), + StorageType(1)); + for (StorageType i = MIN_NORMAL; i <= MAX_NORMAL; i += STEP) { + FPBits xbits(i); + T x = xbits.get_val(); + // In normal range on x86 platforms, the long double implicit 1 bit can be + // zero making the numbers NaN. We will skip them. + if (xbits.is_nan()) + continue; + + for (RoundingMode mode : ROUNDING_MODES) { + if (ForceRoundingMode r(mode); r.success) { + EXPECT_FP_EQ(func(x), mpfr::round(x, mode)); + } + } + } + } +}; + +#define LIST_NEARBYINT_TESTS(F, func) \ + using LlvmLibcNearbyIntTest = NearbyIntTestTemplate<F>; \ + TEST_F(LlvmLibcNearbyIntTest, RoundNumbers) { test_round_numbers(&func); } \ + TEST_F(LlvmLibcNearbyIntTest, Fractions) { test_fractions(&func); } \ + TEST_F(LlvmLibcNearbyIntTest, SubnormalRange) { \ + test_subnormal_range(&func); \ + } \ + TEST_F(LlvmLibcNearbyIntTest, NormalRange) { test_normal_range(&func); } + +#endif // LLVM_LIBC_TEST_SRC_MATH_NEARBYINTTEST_H diff --git a/libc/test/src/math/nearbyint_test.cpp b/libc/test/src/math/nearbyint_test.cpp new file mode 100644 index 0000000..11a5c33 --- /dev/null +++ b/libc/test/src/math/nearbyint_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for nearbyint -------------------------------------------===// +// +// 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 "NearbyIntTest.h" + +#include "src/math/nearbyint.h" + +LIST_NEARBYINT_TESTS(double, LIBC_NAMESPACE::nearbyint) diff --git a/libc/test/src/math/nearbyintf16_test.cpp b/libc/test/src/math/nearbyintf16_test.cpp new file mode 100644 index 0000000..e6ec250 --- /dev/null +++ b/libc/test/src/math/nearbyintf16_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for nearbyintf16 ----------------------------------------===// +// +// 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 "NearbyIntTest.h" + +#include "src/math/nearbyintf16.h" + +LIST_NEARBYINT_TESTS(float16, LIBC_NAMESPACE::nearbyintf16) diff --git a/libc/test/src/math/nearbyintf_test.cpp b/libc/test/src/math/nearbyintf_test.cpp new file mode 100644 index 0000000..fd26153 --- /dev/null +++ b/libc/test/src/math/nearbyintf_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for nearbyintf ------------------------------------------===// +// +// 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 "NearbyIntTest.h" + +#include "src/math/nearbyintf.h" + +LIST_NEARBYINT_TESTS(float, LIBC_NAMESPACE::nearbyintf) diff --git a/libc/test/src/math/nearbyintl_test.cpp b/libc/test/src/math/nearbyintl_test.cpp new file mode 100644 index 0000000..a6d81a1 --- /dev/null +++ b/libc/test/src/math/nearbyintl_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for nearbyintl ------------------------------------------===// +// +// 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 "NearbyIntTest.h" + +#include "src/math/nearbyintl.h" + +LIST_NEARBYINT_TESTS(long double, LIBC_NAMESPACE::nearbyintl) |