-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] Implement roundeven C23 math functions #87678
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libc Author: Vinayak Dev (vinayakdsci) ChangesImplements the functions Patch is 25.81 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/87678.diff 25 Files Affected:
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 2742c33ae47845..1248ca6372b10b 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -494,6 +494,10 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.round
libc.src.math.roundf
libc.src.math.roundl
+ libc.src.math.roundeven
+ libc.src.math.roundevenf
+ libc.src.math.roundevenl
+ libc.src.math.roundevenf128
libc.src.math.scalbn
libc.src.math.scalbnf
libc.src.math.scalbnl
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 970a43ca87c9ec..7a7b6c9c8db5de 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -206,7 +206,7 @@ Basic Operations
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| round | |check| | |check| | |check| | | |check| | 7.12.9.6 | F.10.6.6 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| roundeven | | | | | | 7.12.9.8 | F.10.6.8 |
+| roundeven | |check| | |check| | |check| | | |check| | 7.12.9.8 | F.10.6.8 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| scalbn | |check| | |check| | |check| | | | 7.12.6.19 | F.10.3.19 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index c89792b8ac7be6..e8f699fabe3655 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -293,6 +293,11 @@ add_math_entrypoint_object(roundf)
add_math_entrypoint_object(roundl)
add_math_entrypoint_object(roundf128)
+add_math_entrypoint_object(roundeven)
+add_math_entrypoint_object(roundevenf)
+add_math_entrypoint_object(roundevenl)
+add_math_entrypoint_object(roundevenf128)
+
add_math_entrypoint_object(scalbn)
add_math_entrypoint_object(scalbnf)
add_math_entrypoint_object(scalbnl)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index dc77f8b5ddba28..5bc9066c6263cd 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -417,6 +417,55 @@ add_entrypoint_object(
libc.src.__support.FPUtil.nearest_integer_operations
)
+add_entrypoint_object(
+ roundeven
+ SRCS
+ roundeven.cpp
+ HDRS
+ ../roundeven.h
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.__support.FPUtil.nearest_integer_operations
+)
+
+add_entrypoint_object(
+ roundevenf
+ SRCS
+ roundevenf.cpp
+ HDRS
+ ../roundevenf.h
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.__support.FPUtil.nearest_integer_operations
+)
+
+add_entrypoint_object(
+ roundevenl
+ SRCS
+ roundevenl.cpp
+ HDRS
+ ../roundevenl.h
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.__support.FPUtil.nearest_integer_operations
+)
+
+add_entrypoint_object(
+ roundevenf128
+ SRCS
+ roundevenf128.cpp
+ HDRS
+ ../roundevenf128.h
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.nearest_integer_operations
+)
+
add_entrypoint_object(
lround
SRCS
diff --git a/libc/src/math/generic/roundeven.cpp b/libc/src/math/generic/roundeven.cpp
new file mode 100644
index 00000000000000..5f2adf9b5fce68
--- /dev/null
+++ b/libc/src/math/generic/roundeven.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundeven function ------------------------------===//
+//
+// 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/math/roundeven.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, roundeven, (double x)) {
+ return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/roundevenf.cpp b/libc/src/math/generic/roundevenf.cpp
new file mode 100644
index 00000000000000..353bec74ecf024
--- /dev/null
+++ b/libc/src/math/generic/roundevenf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundevenf function -----------------------------===//
+//
+// 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/math/roundevenf.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, roundevenf, (float x)) {
+ return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/roundevenf128.cpp b/libc/src/math/generic/roundevenf128.cpp
new file mode 100644
index 00000000000000..259388c86fd336
--- /dev/null
+++ b/libc/src/math/generic/roundevenf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundevenf128 function --------------------------===//
+//
+// 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/math/roundevenf128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, roundevenf128, (float128 x)) {
+ return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/roundevenl.cpp b/libc/src/math/generic/roundevenl.cpp
new file mode 100644
index 00000000000000..f8f429faeec8a8
--- /dev/null
+++ b/libc/src/math/generic/roundevenl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of roundevenl function -----------------------------===//
+//
+// 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/math/roundevenl.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, roundevenl, (long double x)) {
+ return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/roundeven.h b/libc/src/math/roundeven.h
new file mode 100644
index 00000000000000..9c76b1fe334ab5
--- /dev/null
+++ b/libc/src/math/roundeven.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for roundeven ---------------------*- 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_SRC_MATH_ROUNDEVEN_H
+#define LLVM_LIBC_SRC_MATH_ROUNDEVEN_H
+
+namespace LIBC_NAMESPACE {
+
+double roundeven(double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDEVEN_H
diff --git a/libc/src/math/roundevenf.h b/libc/src/math/roundevenf.h
new file mode 100644
index 00000000000000..447e7fd940c18a
--- /dev/null
+++ b/libc/src/math/roundevenf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for roundevenf --------------------*- 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_SRC_MATH_ROUNDEVENF_H
+#define LLVM_LIBC_SRC_MATH_ROUNDEVENF_H
+
+namespace LIBC_NAMESPACE {
+
+float roundevenf(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDEVENF_H
diff --git a/libc/src/math/roundevenf128.h b/libc/src/math/roundevenf128.h
new file mode 100644
index 00000000000000..589839d090756c
--- /dev/null
+++ b/libc/src/math/roundevenf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for roundevenf128 -----------------*- 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_SRC_MATH_ROUNDEVENF128_H
+#define LLVM_LIBC_SRC_MATH_ROUNDEVENF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 roundevenf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDEVENF128_H
diff --git a/libc/src/math/roundevenl.h b/libc/src/math/roundevenl.h
new file mode 100644
index 00000000000000..a2f3397e4479ae
--- /dev/null
+++ b/libc/src/math/roundevenl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for roundevenl --------------------*- 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_SRC_MATH_ROUNDEVENL_H
+#define LLVM_LIBC_SRC_MATH_ROUNDEVENL_H
+
+namespace LIBC_NAMESPACE {
+
+long double roundevenl(long double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDEVENL_H
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index bbf8f071e1e0c2..d928cb5c64750e 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -323,6 +323,51 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ roundeven_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ roundeven_test.cpp
+ HDRS
+ RoundEvenTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.roundeven
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+ roundevenf_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ roundevenf_test.cpp
+ HDRS
+ RoundEvenTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.roundevenf
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+ roundevenl_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ roundevenl_test.cpp
+ HDRS
+ RoundEvenTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.roundevenl
+ libc.src.__support.FPUtil.fp_bits
+)
+
add_fp_unittest(
lround_test
NEED_MPFR
diff --git a/libc/test/src/math/RoundEvenTest.h b/libc/test/src/math/RoundEvenTest.h
new file mode 100644
index 00000000000000..db7263a39c0f0a
--- /dev/null
+++ b/libc/test/src/math/RoundEvenTest.h
@@ -0,0 +1,92 @@
+//===-- Utility class to test roundeven[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_ROUNDEVENTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_ROUNDEVENTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+#include "include/llvm-libc-macros/math-macros.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+template <typename T>
+class RoundEvenTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*RoundEvenFunc)(T);
+
+ void testSpecialNumbers(RoundEvenFunc func) {
+ EXPECT_FP_EQ(zero, func(zero));
+ EXPECT_FP_EQ(neg_zero, func(neg_zero));
+
+ EXPECT_FP_EQ(inf, func(inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf));
+
+ EXPECT_FP_EQ(aNaN, func(aNaN));
+ }
+
+ void testRoundedNumbers(RoundEvenFunc func) {
+ EXPECT_FP_EQ(T(1.0), func(T(1.0)));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.0)));
+ EXPECT_FP_EQ(T(10.0), func(T(10.0)));
+ EXPECT_FP_EQ(T(-10.0), func(T(-10.0)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.0)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0)));
+ }
+
+ void testFractions(RoundEvenFunc func) {
+ EXPECT_FP_EQ(T(0.0), func(T(0.5)));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.5)));
+ EXPECT_FP_EQ(T(0.0), func(T(0.115)));
+ EXPECT_FP_EQ(T(-0.0), func(T(-0.115)));
+ EXPECT_FP_EQ(T(1.0), func(T(0.715)));
+ EXPECT_FP_EQ(T(-1.0), func(T(-0.715)));
+ EXPECT_FP_EQ(T(1.0), func(T(1.3)));
+ EXPECT_FP_EQ(T(-1.0), func(T(-1.3)));
+ EXPECT_FP_EQ(T(2.0), func(T(1.5)));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.5)));
+ EXPECT_FP_EQ(T(2.0), func(T(1.75)));
+ EXPECT_FP_EQ(T(-2.0), func(T(-1.75)));
+ EXPECT_FP_EQ(T(11.0), func(T(10.65)));
+ EXPECT_FP_EQ(T(-11.0), func(T(-10.65)));
+ EXPECT_FP_EQ(T(1233.0), func(T(1233.25)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1233.50)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1233.75)));
+ EXPECT_FP_EQ(T(-1233.0), func(T(-1233.25)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1233.50)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1233.75)));
+ EXPECT_FP_EQ(T(1234.0), func(T(1234.50)));
+ EXPECT_FP_EQ(T(-1234.0), func(T(-1234.50)));
+ }
+
+ void testRange(RoundEvenFunc func) {
+ constexpr StorageType COUNT = 100'000;
+ constexpr StorageType STEP = STORAGE_MAX / COUNT;
+ for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ T x = FPBits(v).get_val();
+ if (isnan(x) || isinf(x))
+ continue;
+
+ ASSERT_MPFR_MATCH(mpfr::Operation::RoundEven, x, func(x), 0.0);
+ }
+ }
+};
+
+#define LIST_ROUNDEVEN_TESTS(T, func) \
+ using LlvmLibcRoundEvenTest = RoundEvenTest<T>; \
+ TEST_F(LlvmLibcRoundEvenTest, SpecialNumbers) { testSpecialNumbers(&func); } \
+ TEST_F(LlvmLibcRoundEvenTest, RoundedNubmers) { testRoundedNumbers(&func); } \
+ TEST_F(LlvmLibcRoundEvenTest, Fractions) { testFractions(&func); } \
+ TEST_F(LlvmLibcRoundEvenTest, Range) { testRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_ROUNDEVENTEST_H
diff --git a/libc/test/src/math/roundeven_test.cpp b/libc/test/src/math/roundeven_test.cpp
new file mode 100644
index 00000000000000..cd1a7bf2429fbd
--- /dev/null
+++ b/libc/test/src/math/roundeven_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundeven -------------------------------------------===//
+//
+// 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 "RoundEvenTest.h"
+
+#include "src/math/roundeven.h"
+
+LIST_ROUNDEVEN_TESTS(double, LIBC_NAMESPACE::roundeven)
diff --git a/libc/test/src/math/roundevenf_test.cpp b/libc/test/src/math/roundevenf_test.cpp
new file mode 100644
index 00000000000000..68dff9b3eca9d5
--- /dev/null
+++ b/libc/test/src/math/roundevenf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundevenf ------------------------------------------===//
+//
+// 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 "RoundEvenTest.h"
+
+#include "src/math/roundevenf.h"
+
+LIST_ROUNDEVEN_TESTS(float, LIBC_NAMESPACE::roundevenf)
diff --git a/libc/test/src/math/roundevenl_test.cpp b/libc/test/src/math/roundevenl_test.cpp
new file mode 100644
index 00000000000000..f4031bd65ec21c
--- /dev/null
+++ b/libc/test/src/math/roundevenl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for roundevenl ------------------------------------------===//
+//
+// 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 "RoundEvenTest.h"
+
+#include "src/math/roundevenl.h"
+
+LIST_ROUNDEVEN_TESTS(long double, LIBC_NAMESPACE::roundevenl)
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 4ac1842cf5fae7..e9ff35577b9534 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -397,6 +397,62 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ roundeven_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ roundeven_test.cpp
+ HDRS
+ RoundEvenTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.roundeven
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+ roundevenf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ roundevenf_test.cpp
+ HDRS
+ RoundEvenTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.roundevenf
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+ roundevenl_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ roundevenl_test.cpp
+ HDRS
+ RoundEvenTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.roundevenl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+ roundevenf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ roundevenf128_test.cpp
+ HDRS
+ RoundEvenTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.roundevenf128
+ libc.src.__support.FPUtil.fp_bits
+)
+
add_fp_unittest(
lround_test
SUITE
diff --git a/libc/test/src/math/smoke/RoundEvenTest.h b/libc/test/src/math/smoke/RoundEvenTest.h
new file mode 100644
index 00000000000000..107052fa0e2867
--- /dev/null
+++ b/libc/test/src/math/smoke/RoundEvenTest.h
@@ -0,0 +1,72 @@
+//===-- Utility class to test roundeven[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_SMOKE_ROUNDEVENTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDEVENTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include "include/llvm-libc-macros/math-macros.h"
+
+template <typename T>
+class RoundEvenTest : public LIBC_NAMESPACE::testing::Test {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*RoundEvenFunc)(T);
+
+ void testSpecialNumbers(RoundEvenFunc func) {
+ EXPECT_FP_EQ(zero, func(zero));
+ EXPECT_FP_EQ(neg_zero, func(neg_zero));
+
+ EXPECT_FP_EQ(inf, func(inf));
+ EXPECT_FP_EQ(neg_inf, func(neg_inf));
+
+ EXPECT...
[truncated]
|
cc @lntue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update libc/docs/c23.rst too!
I have to remove the asterisk in front of the function name, right? There is an asterisk in front of all the function names. |
Just add |
Done! |
libc.src.math.roundeven | ||
libc.src.math.roundevenf | ||
libc.src.math.roundevenl | ||
libc.src.math.roundevenf128 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move f128
variant down with other f128
functions where they are guarded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry! I somehow didn't notice that. Fixed now.
a4abd86
to
88f23de
Compare
@@ -351,6 +351,12 @@ class MPFRNumber { | |||
return result; | |||
} | |||
|
|||
MPFRNumber roundeven() const { | |||
MPFRNumber result(*this); | |||
mpfr_roundeven(result.value, value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you double check which version of MPFR adding mpfr_roundeven
function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is present in 4.0.0, https://www.mpfr.org/mpfr-4.0.0/mpfr.pdf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add the version guard, and implement a replacement for mpfr_roundeven
when it's not available, similar to
#if MPFR_VERSION_MAJOR > 4 || \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I implemented the replacement, but I am not sure if I should simply write MPFR_VERSION_MAJOR >= 4
, or also specify the minor version. I went with the latter, but will change if required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just check MPFR_VERSION_MAJOR >= 4
should be enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also factored out the common code from the version guard.
6ac1ea5
to
cdf425a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding this! I'll merge the patch later in the morning so that I can watch the bots.
Thanks a lot! |
Implements the functions
roundeven()
,roundevenf()
,roundevenl()
from the roundeven family of functions introduced in C23. Also implementsroundevenf128()
.