diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt index e4a3087c9055f..79e6e89a5324e 100644 --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -440,11 +440,11 @@ add_fp_unittest( HDRS RoundToIntegerTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno - libc.src.fenv.feclearexcept - libc.src.fenv.feraiseexcept - libc.src.fenv.fetestexcept libc.src.math.lround + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -458,11 +458,11 @@ add_fp_unittest( HDRS RoundToIntegerTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno - libc.src.fenv.feclearexcept - libc.src.fenv.feraiseexcept - libc.src.fenv.fetestexcept libc.src.math.lroundf + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -476,11 +476,29 @@ add_fp_unittest( HDRS RoundToIntegerTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno - libc.src.fenv.feclearexcept - libc.src.fenv.feraiseexcept - libc.src.fenv.fetestexcept libc.src.math.lroundl + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( + lroundf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + lroundf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.errno.errno + libc.src.math.lroundf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -494,11 +512,11 @@ add_fp_unittest( HDRS RoundToIntegerTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno - libc.src.fenv.feclearexcept - libc.src.fenv.feraiseexcept - libc.src.fenv.fetestexcept libc.src.math.llround + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -512,11 +530,11 @@ add_fp_unittest( HDRS RoundToIntegerTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno - libc.src.fenv.feclearexcept - libc.src.fenv.feraiseexcept - libc.src.fenv.fetestexcept libc.src.math.llroundf + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -530,11 +548,29 @@ add_fp_unittest( HDRS RoundToIntegerTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno - libc.src.fenv.feclearexcept - libc.src.fenv.feraiseexcept - libc.src.fenv.fetestexcept libc.src.math.llroundl + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( + llroundf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + llroundf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.errno.errno + libc.src.math.llroundf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -548,7 +584,9 @@ add_fp_unittest( HDRS RIntTest.h DEPENDS + libc.hdr.fenv_macros libc.src.math.rint + libc.src.__support.CPP.algorithm libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -563,7 +601,9 @@ add_fp_unittest( HDRS RIntTest.h DEPENDS + libc.hdr.fenv_macros libc.src.math.rintf + libc.src.__support.CPP.algorithm libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -578,7 +618,26 @@ add_fp_unittest( HDRS RIntTest.h DEPENDS + libc.hdr.fenv_macros libc.src.math.rintl + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( + rintf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + rintf16_test.cpp + HDRS + RIntTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.math.rintf16 + libc.src.__support.CPP.algorithm libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -594,6 +653,7 @@ add_fp_unittest( RoundToIntegerTest.h DEPENDS libc.src.math.lrint + libc.src.__support.CPP.algorithm libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -609,6 +669,7 @@ add_fp_unittest( RoundToIntegerTest.h DEPENDS libc.src.math.lrintf + libc.src.__support.CPP.algorithm libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -624,6 +685,23 @@ add_fp_unittest( RoundToIntegerTest.h DEPENDS libc.src.math.lrintl + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( + lrintf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + lrintf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.src.math.lrintf16 + libc.src.__support.CPP.algorithm libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -639,6 +717,7 @@ add_fp_unittest( RoundToIntegerTest.h DEPENDS libc.src.math.llrint + libc.src.__support.CPP.algorithm libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -654,6 +733,7 @@ add_fp_unittest( RoundToIntegerTest.h DEPENDS libc.src.math.llrintf + libc.src.__support.CPP.algorithm libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) @@ -669,6 +749,23 @@ add_fp_unittest( RoundToIntegerTest.h DEPENDS libc.src.math.llrintl + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( + llrintf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + llrintf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.src.math.llrintf16 + libc.src.__support.CPP.algorithm libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits ) diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h index 007b50427ba34..d31bf743f1a37 100644 --- a/libc/test/src/math/RIntTest.h +++ b/libc/test/src/math/RIntTest.h @@ -9,6 +9,7 @@ #ifndef LLVM_LIBC_TEST_SRC_MATH_RINTTEST_H #define LLVM_LIBC_TEST_SRC_MATH_RINTTEST_H +#include "src/__support/CPP/algorithm.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "test/UnitTest/FEnvSafeTest.h" @@ -18,7 +19,6 @@ #include "hdr/fenv_macros.h" #include "hdr/math_macros.h" -#include namespace mpfr = LIBC_NAMESPACE::testing::mpfr; @@ -101,8 +101,10 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest { } void testSubnormalRange(RIntFunc func) { - constexpr StorageType COUNT = 100'001; - constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT; + constexpr int COUNT = 100'001; + constexpr StorageType STEP = LIBC_NAMESPACE::cpp::max( + static_cast((MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT), + StorageType(1)); for (StorageType i = MIN_SUBNORMAL; i <= MAX_SUBNORMAL; i += STEP) { T x = FPBits(i).get_val(); for (int mode : ROUNDING_MODES) { @@ -114,15 +116,17 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest { } void testNormalRange(RIntFunc func) { - constexpr StorageType COUNT = 100'001; - constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT; + constexpr int COUNT = 100'001; + constexpr StorageType STEP = LIBC_NAMESPACE::cpp::max( + static_cast((MAX_NORMAL - MIN_NORMAL) / COUNT), + StorageType(1)); for (StorageType i = MIN_NORMAL; i <= MAX_NORMAL; i += STEP) { - T x = FPBits(i).get_val(); + 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 (isnan(x)) { + if (xbits.is_nan()) continue; - } for (int mode : ROUNDING_MODES) { LIBC_NAMESPACE::fputil::set_round(mode); diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h index d40e15080087c..bb7e8643973c3 100644 --- a/libc/test/src/math/RoundToIntegerTest.h +++ b/libc/test/src/math/RoundToIntegerTest.h @@ -9,6 +9,7 @@ #ifndef LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H #define LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H +#include "src/__support/CPP/algorithm.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "test/UnitTest/FEnvSafeTest.h" @@ -136,10 +137,13 @@ class RoundToIntegerTestTemplate return; constexpr int EXPONENT_LIMIT = sizeof(I) * 8 - 1; + constexpr int BIASED_EXPONENT_LIMIT = EXPONENT_LIMIT + FPBits::EXP_BIAS; + if (BIASED_EXPONENT_LIMIT > FPBits::MAX_BIASED_EXPONENT) + return; // We start with 1.0 so that the implicit bit for x86 long doubles // is set. FPBits bits(F(1.0)); - bits.set_biased_exponent(EXPONENT_LIMIT + FPBits::EXP_BIAS); + bits.set_biased_exponent(BIASED_EXPONENT_LIMIT); bits.set_sign(Sign::NEG); bits.set_mantissa(0); @@ -200,10 +204,13 @@ class RoundToIntegerTestTemplate return; constexpr int EXPONENT_LIMIT = sizeof(I) * 8 - 1; + constexpr int BIASED_EXPONENT_LIMIT = EXPONENT_LIMIT + FPBits::EXP_BIAS; + if (BIASED_EXPONENT_LIMIT > FPBits::MAX_BIASED_EXPONENT) + return; // We start with 1.0 so that the implicit bit for x86 long doubles // is set. FPBits bits(F(1.0)); - bits.set_biased_exponent(EXPONENT_LIMIT + FPBits::EXP_BIAS); + bits.set_biased_exponent(BIASED_EXPONENT_LIMIT); bits.set_sign(Sign::NEG); bits.set_mantissa(FPBits::FRACTION_MASK); @@ -226,8 +233,10 @@ class RoundToIntegerTestTemplate } void testSubnormalRange(RoundToIntegerFunc func) { - constexpr StorageType COUNT = 1'000'001; - constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT; + constexpr int COUNT = 1'000'001; + constexpr StorageType STEP = LIBC_NAMESPACE::cpp::max( + static_cast((MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT), + StorageType(1)); for (StorageType i = MIN_SUBNORMAL; i <= MAX_SUBNORMAL; i += STEP) { F x = FPBits(i).get_val(); if (x == F(0.0)) @@ -268,15 +277,17 @@ class RoundToIntegerTestTemplate if (sizeof(I) > sizeof(long)) return; - constexpr StorageType COUNT = 1'000'001; - constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT; + constexpr int COUNT = 1'000'001; + constexpr StorageType STEP = LIBC_NAMESPACE::cpp::max( + static_cast((MAX_NORMAL - MIN_NORMAL) / COUNT), + StorageType(1)); for (StorageType i = MIN_NORMAL; i <= MAX_NORMAL; i += STEP) { - F x = FPBits(i).get_val(); + FPBits xbits(i); + F 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 (isnan(x)) { + if (xbits.is_nan()) continue; - } if (TestModes) { for (int m : ROUNDING_MODES) { diff --git a/libc/test/src/math/llrintf16_test.cpp b/libc/test/src/math/llrintf16_test.cpp new file mode 100644 index 0000000000000..d16bd8f38b052 --- /dev/null +++ b/libc/test/src/math/llrintf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for llrintf16 -------------------------------------------===// +// +// 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 "RoundToIntegerTest.h" + +#include "src/math/llrintf16.h" + +LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(float16, long long, + LIBC_NAMESPACE::llrintf16) diff --git a/libc/test/src/math/llroundf16_test.cpp b/libc/test/src/math/llroundf16_test.cpp new file mode 100644 index 0000000000000..9342b24fd5d04 --- /dev/null +++ b/libc/test/src/math/llroundf16_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for llroundf16 ------------------------------------------===// +// +// 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 "RoundToIntegerTest.h" + +#include "src/math/llroundf16.h" + +LIST_ROUND_TO_INTEGER_TESTS(float16, long long, LIBC_NAMESPACE::llroundf16) diff --git a/libc/test/src/math/lrintf16_test.cpp b/libc/test/src/math/lrintf16_test.cpp new file mode 100644 index 0000000000000..28b1a1cb888d7 --- /dev/null +++ b/libc/test/src/math/lrintf16_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for lrintf16 --------------------------------------------===// +// +// 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 "RoundToIntegerTest.h" + +#include "src/math/lrintf16.h" + +LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(float16, long, LIBC_NAMESPACE::lrintf16) diff --git a/libc/test/src/math/lroundf16_test.cpp b/libc/test/src/math/lroundf16_test.cpp new file mode 100644 index 0000000000000..3077134d58f91 --- /dev/null +++ b/libc/test/src/math/lroundf16_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for lroundf16 -------------------------------------------===// +// +// 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 "RoundToIntegerTest.h" + +#include "src/math/lroundf16.h" + +LIST_ROUND_TO_INTEGER_TESTS(float16, long, LIBC_NAMESPACE::lroundf16) diff --git a/libc/test/src/math/rintf16_test.cpp b/libc/test/src/math/rintf16_test.cpp new file mode 100644 index 0000000000000..2adf2560bae1f --- /dev/null +++ b/libc/test/src/math/rintf16_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for rintf16 ---------------------------------------------===// +// +// 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 "RIntTest.h" + +#include "src/math/rintf16.h" + +LIST_RINT_TESTS(float16, LIBC_NAMESPACE::rintf16) diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp index a9177fa050f86..6918139fa83b7 100644 --- a/libc/utils/MPFRWrapper/MPFRUtils.cpp +++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp @@ -1085,6 +1085,9 @@ template bool round_to_long(T x, long &result) { template bool round_to_long(float, long &); template bool round_to_long(double, long &); template bool round_to_long(long double, long &); +#ifdef LIBC_TYPES_HAS_FLOAT16 +template bool round_to_long(float16, long &); +#endif template bool round_to_long(T x, RoundingMode mode, long &result) { MPFRNumber mpfr(x); @@ -1094,6 +1097,9 @@ template bool round_to_long(T x, RoundingMode mode, long &result) { template bool round_to_long(float, RoundingMode, long &); template bool round_to_long(double, RoundingMode, long &); template bool round_to_long(long double, RoundingMode, long &); +#ifdef LIBC_TYPES_HAS_FLOAT16 +template bool round_to_long(float16, RoundingMode, long &); +#endif template T round(T x, RoundingMode mode) { MPFRNumber mpfr(x); @@ -1104,6 +1110,9 @@ template T round(T x, RoundingMode mode) { template float round(float, RoundingMode); template double round(double, RoundingMode); template long double round(long double, RoundingMode); +#ifdef LIBC_TYPES_HAS_FLOAT16 +template float16 round(float16, RoundingMode); +#endif } // namespace mpfr } // namespace testing