aboutsummaryrefslogtreecommitdiff
path: root/libc/test/src
diff options
context:
space:
mode:
Diffstat (limited to 'libc/test/src')
-rw-r--r--libc/test/src/math/CMakeLists.txt11
-rw-r--r--libc/test/src/math/RsqrtTest.h74
-rw-r--r--libc/test/src/math/exhaustive/CMakeLists.txt15
-rw-r--r--libc/test/src/math/exhaustive/rsqrtf_test.cpp27
-rw-r--r--libc/test/src/math/rsqrtf_test.cpp12
-rw-r--r--libc/test/src/math/smoke/CMakeLists.txt15
-rw-r--r--libc/test/src/math/smoke/rsqrtf16_test.cpp1
-rw-r--r--libc/test/src/math/smoke/rsqrtf_test.cpp41
-rw-r--r--libc/test/src/stdfix/CMakeLists.txt16
-rw-r--r--libc/test/src/stdfix/DivITest.h74
-rw-r--r--libc/test/src/stdfix/rdivi_test.cpp14
11 files changed, 299 insertions, 1 deletions
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);