diff options
Diffstat (limited to 'libc/test')
-rw-r--r-- | libc/test/shared/CMakeLists.txt | 2 | ||||
-rw-r--r-- | libc/test/shared/shared_math_test.cpp | 2 | ||||
-rw-r--r-- | libc/test/src/math/CMakeLists.txt | 11 | ||||
-rw-r--r-- | libc/test/src/math/RsqrtTest.h | 74 | ||||
-rw-r--r-- | libc/test/src/math/exhaustive/CMakeLists.txt | 15 | ||||
-rw-r--r-- | libc/test/src/math/exhaustive/rsqrtf_test.cpp | 27 | ||||
-rw-r--r-- | libc/test/src/math/rsqrtf_test.cpp | 12 | ||||
-rw-r--r-- | libc/test/src/math/smoke/CMakeLists.txt | 15 | ||||
-rw-r--r-- | libc/test/src/math/smoke/rsqrtf16_test.cpp | 1 | ||||
-rw-r--r-- | libc/test/src/math/smoke/rsqrtf_test.cpp | 41 | ||||
-rw-r--r-- | libc/test/src/stdfix/CMakeLists.txt | 16 | ||||
-rw-r--r-- | libc/test/src/stdfix/DivITest.h | 74 | ||||
-rw-r--r-- | libc/test/src/stdfix/rdivi_test.cpp | 14 |
13 files changed, 302 insertions, 2 deletions
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt index dbc3889c..f341d3f 100644 --- a/libc/test/shared/CMakeLists.txt +++ b/libc/test/shared/CMakeLists.txt @@ -53,6 +53,6 @@ add_fp_unittest( libc.src.__support.math.ldexpf libc.src.__support.math.ldexpf128 libc.src.__support.math.ldexpf16 + libc.src.__support.math.rsqrtf libc.src.__support.math.rsqrtf16 - ) diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp index d118d96..477b7ec 100644 --- a/libc/test/shared/shared_math_test.cpp +++ b/libc/test/shared/shared_math_test.cpp @@ -70,6 +70,8 @@ TEST(LlvmLibcSharedMathTest, AllFloat) { ASSERT_FP_EQ(float(8 << 5), LIBC_NAMESPACE::shared::ldexpf(8.0f, 5)); ASSERT_FP_EQ(float(-1 * (8 << 5)), LIBC_NAMESPACE::shared::ldexpf(-8.0f, 5)); + + EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::rsqrtf(1.0f)); } TEST(LlvmLibcSharedMathTest, AllDouble) { diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt index 2d2d528..b3f54ab 100644 --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -1679,6 +1679,17 @@ add_fp_unittest( ) add_fp_unittest( + rsqrtf_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + rsqrtf_test.cpp + DEPENDS + libc.src.math.rsqrtf +) + +add_fp_unittest( rsqrtf16_test NEED_MPFR SUITE diff --git a/libc/test/src/math/RsqrtTest.h b/libc/test/src/math/RsqrtTest.h new file mode 100644 index 0000000..d11d708 --- /dev/null +++ b/libc/test/src/math/RsqrtTest.h @@ -0,0 +1,74 @@ +//===-- Utility class to test rsqrt[f|l] ------------------------*- 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_RSQRTTEST_H +#define LLVM_LIBC_TEST_SRC_MATH_RSQRTTEST_H + +#include "test/UnitTest/FEnvSafeTest.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +template <typename OutType, typename InType = OutType> +class RsqrtTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { + + DECLARE_SPECIAL_CONSTANTS(InType) + + static constexpr StorageType HIDDEN_BIT = + StorageType(1) << LIBC_NAMESPACE::fputil::FPBits<InType>::FRACTION_LEN; + +public: + using RsqrtFunc = OutType (*)(InType); + + // Subnormal inputs: probe both power-of-two mantissas and an even sampling + // across the subnormal range. + void test_denormal_values(RsqrtFunc func) { + // Powers of two in the subnormal mantissa space. + for (StorageType mant = 1; mant < HIDDEN_BIT; mant <<= 1) { + FPBits denormal(zero); + denormal.set_mantissa(mant); + InType x = denormal.get_val(); + ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, func(x), 0.5); + } + + // Even sampling across all subnormals. + constexpr StorageType COUNT = 200'001; + constexpr StorageType STEP = HIDDEN_BIT / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + InType x = FPBits(i).get_val(); + ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, func(x), 0.5); + } + } + + // Positive normal range sampling: skip NaNs and negative values. + void test_normal_range(RsqrtFunc func) { + constexpr StorageType COUNT = 200'001; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + FPBits x_bits(v); + InType x = x_bits.get_val(); + if (x_bits.is_nan() || x_bits.is_neg()) + continue; + ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, func(x), 0.5); + } + } +}; + +#define LIST_RSQRT_TESTS(T, func) \ + using LlvmLibcRsqrtTest = RsqrtTest<T, T>; \ + TEST_F(LlvmLibcRsqrtTest, DenormalValues) { test_denormal_values(&func); } \ + TEST_F(LlvmLibcRsqrtTest, NormalRange) { test_normal_range(&func); } + +#define LIST_NARROWING_RSQRT_TESTS(OutType, InType, func) \ + using LlvmLibcRsqrtTest = RsqrtTest<OutType, InType>; \ + TEST_F(LlvmLibcRsqrtTest, DenormalValues) { test_denormal_values(&func); } \ + TEST_F(LlvmLibcRsqrtTest, NormalRange) { test_normal_range(&func); } + +#endif // LLVM_LIBC_TEST_SRC_MATH_RSQRTTEST_H diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt index 07c36f424..1583ab6 100644 --- a/libc/test/src/math/exhaustive/CMakeLists.txt +++ b/libc/test/src/math/exhaustive/CMakeLists.txt @@ -27,6 +27,21 @@ add_fp_unittest( ) add_fp_unittest( + rsqrtf_test + NO_RUN_POSTBUILD + NEED_MPFR + SUITE + libc_math_exhaustive_tests + SRCS + rsqrtf_test.cpp + DEPENDS + .exhaustive_test + libc.src.math.rsqrtf + LINK_LIBRARIES + -lpthread +) + +add_fp_unittest( sinf_test NO_RUN_POSTBUILD NEED_MPFR diff --git a/libc/test/src/math/exhaustive/rsqrtf_test.cpp b/libc/test/src/math/exhaustive/rsqrtf_test.cpp new file mode 100644 index 0000000..803c9b4 --- /dev/null +++ b/libc/test/src/math/exhaustive/rsqrtf_test.cpp @@ -0,0 +1,27 @@ +//===-- Exhaustive test for rsqrtf ----------------------------------------===// +// +// 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/math/rsqrtf.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +using LlvmLibcRsqrtfTest = LIBC_NAMESPACE::testing::FPTest<float>; + +using LlvmLibcRsqrtfExhaustiveTest = + LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Rsqrt, + LIBC_NAMESPACE::rsqrtf>; + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +// Range: [0, Inf] +static constexpr uint32_t POS_START = 0x0000'0000U; +static constexpr uint32_t POS_STOP = 0x7f80'0000U; + +TEST_F(LlvmLibcRsqrtfExhaustiveTest, PositiveRange) { + test_full_range_all_roundings(POS_START, POS_STOP); +} diff --git a/libc/test/src/math/rsqrtf_test.cpp b/libc/test/src/math/rsqrtf_test.cpp new file mode 100644 index 0000000..4e476c0 --- /dev/null +++ b/libc/test/src/math/rsqrtf_test.cpp @@ -0,0 +1,12 @@ +//===-- Unittests for rsqrtf ----------------------------------------------===// +// 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 "RsqrtTest.h" + +#include "src/math/rsqrtf.h" + +LIST_RSQRT_TESTS(float, LIBC_NAMESPACE::rsqrtf) diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 42a97ba..5afd3a9 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -3503,14 +3503,27 @@ add_fp_unittest( ) add_fp_unittest( + rsqrtf_test + SUITE + libc-math-smoke-tests + SRCS + rsqrtf_test.cpp + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.rsqrtf +) + +add_fp_unittest( rsqrtf16_test SUITE libc-math-smoke-tests SRCS rsqrtf16_test.cpp DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros libc.src.math.rsqrtf16 - libc.hdr.errno_macros ) add_fp_unittest( diff --git a/libc/test/src/math/smoke/rsqrtf16_test.cpp b/libc/test/src/math/smoke/rsqrtf16_test.cpp index e103e73..13d9a33 100644 --- a/libc/test/src/math/smoke/rsqrtf16_test.cpp +++ b/libc/test/src/math/smoke/rsqrtf16_test.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/macros/properties/architectures.h" #include "src/math/rsqrtf16.h" diff --git a/libc/test/src/math/smoke/rsqrtf_test.cpp b/libc/test/src/math/smoke/rsqrtf_test.cpp new file mode 100644 index 0000000..d71b82c --- /dev/null +++ b/libc/test/src/math/smoke/rsqrtf_test.cpp @@ -0,0 +1,41 @@ +//===-- Unittests for rsqrtf --------------------------------------------===// +// +// 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 "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" +#include "src/math/rsqrtf.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" + +using LlvmLibcRsqrtfTest = LIBC_NAMESPACE::testing::FPTest<float>; + +TEST_F(LlvmLibcRsqrtfTest, SpecialNumbers) { + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::rsqrtf(aNaN)); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::rsqrtf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ(inf, LIBC_NAMESPACE::rsqrtf(zero)); + EXPECT_MATH_ERRNO(ERANGE); + + EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::rsqrtf(neg_zero)); + EXPECT_MATH_ERRNO(ERANGE); + + EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::rsqrtf(1.0f)); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ(zero, LIBC_NAMESPACE::rsqrtf(inf)); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::rsqrtf(neg_inf)); + EXPECT_MATH_ERRNO(EDOM); + + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::rsqrtf(-2.0f)); + EXPECT_MATH_ERRNO(EDOM); +} diff --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt index e2b4bc1..7415222 100644 --- a/libc/test/src/stdfix/CMakeLists.txt +++ b/libc/test/src/stdfix/CMakeLists.txt @@ -120,6 +120,22 @@ foreach(suffix IN ITEMS r lr k lk ur ulr uk ulk) ) endforeach() +foreach(suffix IN ITEMS r) + add_libc_test( + ${suffix}divi_test + SUITE + libc-stdfix-tests + HDRS + DivITest.h + SRCS + ${suffix}divi_test.cpp + DEPENDS + libc.src.stdfix.${suffix}divi + libc.src.__support.fixed_point.fx_bits + libc.hdr.signal_macros + ) +endforeach() + add_libc_test( uhksqrtus_test SUITE diff --git a/libc/test/src/stdfix/DivITest.h b/libc/test/src/stdfix/DivITest.h new file mode 100644 index 0000000..ad15637 --- /dev/null +++ b/libc/test/src/stdfix/DivITest.h @@ -0,0 +1,74 @@ +//===-- Utility class to test fxdivi functions ------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/CPP/type_traits.h" +#include "src/__support/fixed_point/fx_bits.h" +#include "src/__support/fixed_point/fx_rep.h" +#include "test/UnitTest/Test.h" + +template <typename XType> XType get_epsilon() = delete; +template <> fract get_epsilon() { return FRACT_EPSILON; } +template <> unsigned fract get_epsilon() { return UFRACT_EPSILON; } +template <> long fract get_epsilon() { return LFRACT_EPSILON; } + +template <typename XType> +class DivITest : public LIBC_NAMESPACE::testing::Test { + using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<XType>; + using FXBits = LIBC_NAMESPACE::fixed_point::FXBits<XType>; + +public: + typedef XType (*DivIFunc)(int, int); + + void testBasic(DivIFunc func) { + XType epsilon = get_epsilon<XType>(); + EXPECT_LT((func(2, 3) - 0.666656494140625r), epsilon); + EXPECT_LT((func(3, 4) - 0.75r), epsilon); + EXPECT_LT((func(1043, 2764) - 0.3773516643r), epsilon); + EXPECT_LT((func(60000, 720293) - 0.08329943509r), epsilon); + + EXPECT_EQ(func(128, 256), 0.5r); + EXPECT_EQ(func(1, 2), 0.5r); + EXPECT_EQ(func(1, 4), 0.25r); + EXPECT_EQ(func(1, 8), 0.125r); + EXPECT_EQ(func(1, 16), 0.0625r); + + EXPECT_EQ(func(-1, 2), -0.5r); + EXPECT_EQ(func(1, -4), -0.25r); + EXPECT_EQ(func(-1, 8), -0.125r); + EXPECT_EQ(func(1, -16), -0.0625r); + } + + void testSpecial(DivIFunc func) { + XType epsilon = get_epsilon<XType>(); + EXPECT_EQ(func(0, 10), 0.r); + EXPECT_EQ(func(0, -10), 0.r); + EXPECT_EQ(func(-(1 << FRACT_FBIT), 1 << FRACT_FBIT), FRACT_MIN); + EXPECT_EQ(func((1 << FRACT_FBIT) - 1, 1 << FRACT_FBIT), FRACT_MAX); + // From Section 7.18a.6.1, functions returning a fixed-point value, the + // return value is saturated on overflow. + EXPECT_EQ(func(INT_MAX, INT_MAX), FRACT_MAX); + EXPECT_LT(func(INT_MAX - 1, INT_MAX) - 0.99999999r, epsilon); + EXPECT_EQ(func(INT_MIN, INT_MAX), FRACT_MIN); + // Expecting 0 here as fract is not precise enough to + // handle 1/INT_MAX + EXPECT_LT(func(1, INT_MAX) - 0.r, epsilon); + // This results in 1.1739, which should be saturated to FRACT_MAX + EXPECT_EQ(func(27, 23), FRACT_MAX); + + EXPECT_EQ(func(INT_MIN, 1), FRACT_MIN); + EXPECT_LT(func(1, INT_MIN) - 0.r, epsilon); + + EXPECT_EQ(func(INT_MIN, INT_MIN), 1.r); + } +}; + +#define LIST_DIVI_TESTS(Name, XType, func) \ + using LlvmLibc##Name##diviTest = DivITest<XType>; \ + TEST_F(LlvmLibc##Name##diviTest, Basic) { testBasic(&func); } \ + TEST_F(LlvmLibc##Name##diviTest, Special) { testSpecial(&func); } \ + static_assert(true, "Require semicolon.") diff --git a/libc/test/src/stdfix/rdivi_test.cpp b/libc/test/src/stdfix/rdivi_test.cpp new file mode 100644 index 0000000..10ab366 --- /dev/null +++ b/libc/test/src/stdfix/rdivi_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for rdivi -----------------------------------------------===// +// +// 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 "DivITest.h" + +#include "llvm-libc-macros/stdfix-macros.h" // fract +#include "src/stdfix/rdivi.h" + +LIST_DIVI_TESTS(r, fract, LIBC_NAMESPACE::rdivi); |