-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[libc][math][c23] Add nextupl and nextdownl functions #85484
Conversation
@llvm/pr-subscribers-libc Author: OverMighty (overmighty) ChangesFixes #85283. cc @lntue Full diff: https://github.com/llvm/llvm-project/pull/85484.diff 14 Files Affected:
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 7e13a7c5793c30..99182e7f92ac09 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -431,8 +431,10 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.nexttowardl
libc.src.math.nextdown
libc.src.math.nextdownf
+ libc.src.math.nextdownl
libc.src.math.nextup
libc.src.math.nextupf
+ libc.src.math.nextupl
libc.src.math.powf
libc.src.math.remainderf
libc.src.math.remainder
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 3240a8c5d2456a..dbcffc1432e8b7 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -275,12 +275,28 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextafterf128| |check| | |check| | | |check| | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| nextdown | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| nextdownf | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| nextdownl | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| nextdownf128 | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nexttoward | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nexttowardf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nexttowardl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| nextup | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| nextupf | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| nextupl | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| nextupf128 | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| remainder | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| remainderf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index b438fc6732b087..84d28cc3350304 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -538,10 +538,12 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"nextdown", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"nextdownf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
+ FunctionSpec<"nextdownl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"nextdownf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
FunctionSpec<"nextup", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"nextupf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
+ FunctionSpec<"nextupl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"nextupf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
FunctionSpec<"powf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index 1301caa497da44..201c2b3071040d 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -259,6 +259,7 @@ LIBC_INLINE constexpr T nextupdown(T x) {
#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#include "x86_64/NextAfterLongDouble.h"
+#include "x86_64/NextUpDownLongDouble.h"
#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_MANIPULATIONFUNCTIONS_H
diff --git a/libc/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h b/libc/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h
new file mode 100644
index 00000000000000..2245cb7c18c9d5
--- /dev/null
+++ b/libc/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h
@@ -0,0 +1,56 @@
+//===-- nextupdown implementation for x86 long double numbers ---*- 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___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/properties/architectures.h"
+
+#if !defined(LIBC_TARGET_ARCH_IS_X86)
+#error "Invalid include"
+#endif
+
+namespace LIBC_NAMESPACE::fputil {
+
+template <bool IsDown>
+LIBC_INLINE constexpr long double nextupdown(long double x) {
+ constexpr Sign sign = IsDown ? Sign::NEG : Sign::POS;
+
+ using FPBits_t = FPBits<long double>;
+ FPBits_t xbits(x);
+ if (xbits.is_nan() || xbits == FPBits_t::max_normal(sign) ||
+ xbits == FPBits_t::inf(sign))
+ return x;
+
+ using StorageType = typename FPBits_t::StorageType;
+ if (x == 0.0l) {
+ xbits = FPBits_t::min_subnormal(sign);
+ } else if (xbits.sign() == sign) {
+ if (xbits.get_mantissa() == FPBits_t::FRACTION_MASK) {
+ xbits.set_mantissa(0);
+ xbits.set_biased_exponent(xbits.get_biased_exponent() + 1);
+ } else {
+ xbits = FPBits_t(StorageType(xbits.uintval() + 1));
+ }
+ } else {
+ if (xbits.get_mantissa() == 0) {
+ xbits.set_mantissa(FPBits_t::FRACTION_MASK);
+ xbits.set_biased_exponent(xbits.get_biased_exponent() - 1);
+ } else {
+ xbits = FPBits_t(StorageType(xbits.uintval() - 1));
+ }
+ }
+
+ return xbits.get_val();
+}
+
+} // namespace LIBC_NAMESPACE::fputil
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 6c82caafba4f4d..5e2e6e699d0e0c 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -207,10 +207,12 @@ add_math_entrypoint_object(nexttowardl)
add_math_entrypoint_object(nextdown)
add_math_entrypoint_object(nextdownf)
+add_math_entrypoint_object(nextdownl)
add_math_entrypoint_object(nextdownf128)
add_math_entrypoint_object(nextup)
add_math_entrypoint_object(nextupf)
+add_math_entrypoint_object(nextupl)
add_math_entrypoint_object(nextupf128)
add_math_entrypoint_object(pow)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index ca99863ebffbc0..b0a35c652cd587 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1890,6 +1890,18 @@ add_entrypoint_object(
-O3
)
+add_entrypoint_object(
+ nextdownl
+ SRCS
+ nextdownl.cpp
+ HDRS
+ ../nextdownl.h
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
+ COMPILE_OPTIONS
+ -O3
+)
+
add_entrypoint_object(
nextdownf
SRCS
@@ -1927,6 +1939,18 @@ add_entrypoint_object(
-O3
)
+add_entrypoint_object(
+ nextupl
+ SRCS
+ nextupl.cpp
+ HDRS
+ ../nextupl.h
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
+ COMPILE_OPTIONS
+ -O3
+)
+
add_entrypoint_object(
nextupf
SRCS
diff --git a/libc/src/math/generic/nextdownl.cpp b/libc/src/math/generic/nextdownl.cpp
new file mode 100644
index 00000000000000..06a09c9daea595
--- /dev/null
+++ b/libc/src/math/generic/nextdownl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextdownl 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/nextdownl.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, nextdownl, (long double x)) {
+ return fputil::nextupdown</*IsDown=*/true>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextupl.cpp b/libc/src/math/generic/nextupl.cpp
new file mode 100644
index 00000000000000..ccc52445eec5c1
--- /dev/null
+++ b/libc/src/math/generic/nextupl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextupl 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/nextupl.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, nextupl, (long double x)) {
+ return fputil::nextupdown</*IsDown=*/false>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/nextdownl.h b/libc/src/math/nextdownl.h
new file mode 100644
index 00000000000000..9cb274a89b1c53
--- /dev/null
+++ b/libc/src/math/nextdownl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextdownl ---------------------*- 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_NEXTDOWNL_H
+#define LLVM_LIBC_SRC_MATH_NEXTDOWNL_H
+
+namespace LIBC_NAMESPACE {
+
+long double nextdownl(long double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNL_H
diff --git a/libc/src/math/nextupl.h b/libc/src/math/nextupl.h
new file mode 100644
index 00000000000000..cbc6a168e4bea2
--- /dev/null
+++ b/libc/src/math/nextupl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextupl -----------------------*- 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_NEXTUPL_H
+#define LLVM_LIBC_SRC_MATH_NEXTUPL_H
+
+namespace LIBC_NAMESPACE {
+
+long double nextupl(long double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTUPL_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 72cb4e9b3c0337..85dacce3b21dca 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1658,6 +1658,20 @@ add_fp_unittest(
libc.src.__support.FPUtil.manipulation_functions
)
+add_fp_unittest(
+ nextdownl_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextdownl_test.cpp
+ HDRS
+ NextDownTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.nextdownl
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
add_fp_unittest(
nextdownf128_test
SUITE
@@ -1700,6 +1714,20 @@ add_fp_unittest(
libc.src.__support.FPUtil.manipulation_functions
)
+add_fp_unittest(
+ nextupl_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextupl_test.cpp
+ HDRS
+ NextUpTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.nextupl
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
add_fp_unittest(
nextupf128_test
SUITE
diff --git a/libc/test/src/math/smoke/nextdownl_test.cpp b/libc/test/src/math/smoke/nextdownl_test.cpp
new file mode 100644
index 00000000000000..f1785eb58ce512
--- /dev/null
+++ b/libc/test/src/math/smoke/nextdownl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextdownl -------------------------------------------===//
+//
+// 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 "NextDownTest.h"
+
+#include "src/math/nextdownl.h"
+
+LIST_NEXTDOWN_TESTS(long double, LIBC_NAMESPACE::nextdownl)
diff --git a/libc/test/src/math/smoke/nextupl_test.cpp b/libc/test/src/math/smoke/nextupl_test.cpp
new file mode 100644
index 00000000000000..50f765633c2a50
--- /dev/null
+++ b/libc/test/src/math/smoke/nextupl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextupl ---------------------------------------------===//
+//
+// 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 "NextUpTest.h"
+
+#include "src/math/nextupl.h"
+
+LIST_NEXTUP_TESTS(long double, LIBC_NAMESPACE::nextupl)
|
| nextdown | |check| | | | | | | | | | | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nextdownf | |check| | | | | | | | | | | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nextdownl | |check| | | | | | | | | | | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nextdownf128 | |check| | | | | | | | | | | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nexttoward | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nexttowardf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nexttowardl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nextup | |check| | | | | | | | | | | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nextupf | |check| | | | | | | | | | | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nextupl | |check| | | | | | | | | | | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ||
| nextupf128 | |check| | | | | | | | | | | | | | ||
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ |
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 hadn't documented nextup{,f,f128}
and nextdown{,f,f128}
in #85431.
By the way, how exactly do you decide which targets to add entrypoints for? I only added entrypoints for Linux on x86-64 because that's what I develop on, but the current nextup*
and nextdown*
implementations should work on other targets too.
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.
So in general, there are several things you can try:
- For most of the generic functions for single, double, and long double, they should work everywhere. You can simply add them in your patch, and if you cannot test other architectures directly, you can watch our bots https://lab.llvm.org/buildbot/#/builders?tags=libc and get ready to fix-forward or back out the change if they failed.
- For float128, so far we only tested that they work on x86-64, aarch64, and riscv-64, so normally you can just enable them for all 3, and watch the bots.
- Some targets such as
baremetal
,windows
, ormacos
we actually don't have working bots right now, so it's ok to skip them. - If you want to be on the safe side, you can simply only enable entrypoints for the targets that you can directly test in the initial PR, and then enable the other targets on a following PR, so that if it breaks other bots, you only need to rollback your second PR.
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 see. I will enable other targets in a following PR.
|
||
using StorageType = typename FPBits_t::StorageType; | ||
if (x == 0.0l) { | ||
xbits = FPBits_t::min_subnormal(sign); |
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.
Probably using early return can reduce the nested if-else a bit:
if (x == 0.0l)
return FPBits_t::min_subnormal(sign).get_val();
if (xbits.sign() == sign) ...
…85803) See #85484 (comment). There already were entrypoints for linux/x86_64. I haven't tested on the other targets and will rely on the buildbots.
…lvm#85803) See llvm#85484 (comment). There already were entrypoints for linux/x86_64. I haven't tested on the other targets and will rely on the buildbots.
Fixes #85283.
cc @lntue