[libc-commits] [libc] [libc][math][c23] Add nextup{, f, f128} and nextdown{, f, f128} functions (PR #85431)
via libc-commits
libc-commits at lists.llvm.org
Fri Mar 15 11:47:29 PDT 2024
https://github.com/overmighty updated https://github.com/llvm/llvm-project/pull/85431
>From a4d2f4fb5dcbb3e3da172500e5781bea74331b25 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Fri, 15 Mar 2024 16:54:00 +0000
Subject: [PATCH 1/2] [libc][math][c23] Add nextup{,f,f128} and
nextdown{,f,f128} functions
---
libc/config/linux/x86_64/entrypoints.txt | 6 ++
libc/spec/stdc.td | 8 ++
.../__support/FPUtil/ManipulationFunctions.h | 21 +++++
libc/src/math/CMakeLists.txt | 8 ++
libc/src/math/generic/CMakeLists.txt | 74 ++++++++++++++++
libc/src/math/generic/nextdown.cpp | 19 +++++
libc/src/math/generic/nextdownf.cpp | 19 +++++
libc/src/math/generic/nextdownf128.cpp | 19 +++++
libc/src/math/generic/nextup.cpp | 19 +++++
libc/src/math/generic/nextupf.cpp | 19 +++++
libc/src/math/generic/nextupf128.cpp | 19 +++++
libc/src/math/nextdown.h | 18 ++++
libc/src/math/nextdownf.h | 18 ++++
libc/src/math/nextdownf128.h | 20 +++++
libc/src/math/nextup.h | 18 ++++
libc/src/math/nextupf.h | 18 ++++
libc/src/math/nextupf128.h | 20 +++++
libc/test/src/math/smoke/CMakeLists.txt | 84 +++++++++++++++++++
libc/test/src/math/smoke/NextDownTest.h | 55 ++++++++++++
libc/test/src/math/smoke/NextUpTest.h | 55 ++++++++++++
libc/test/src/math/smoke/nextdown_test.cpp | 13 +++
.../test/src/math/smoke/nextdownf128_test.cpp | 13 +++
libc/test/src/math/smoke/nextdownf_test.cpp | 13 +++
libc/test/src/math/smoke/nextup_test.cpp | 13 +++
libc/test/src/math/smoke/nextupf128_test.cpp | 13 +++
libc/test/src/math/smoke/nextupf_test.cpp | 13 +++
26 files changed, 615 insertions(+)
create mode 100644 libc/src/math/generic/nextdown.cpp
create mode 100644 libc/src/math/generic/nextdownf.cpp
create mode 100644 libc/src/math/generic/nextdownf128.cpp
create mode 100644 libc/src/math/generic/nextup.cpp
create mode 100644 libc/src/math/generic/nextupf.cpp
create mode 100644 libc/src/math/generic/nextupf128.cpp
create mode 100644 libc/src/math/nextdown.h
create mode 100644 libc/src/math/nextdownf.h
create mode 100644 libc/src/math/nextdownf128.h
create mode 100644 libc/src/math/nextup.h
create mode 100644 libc/src/math/nextupf.h
create mode 100644 libc/src/math/nextupf128.h
create mode 100644 libc/test/src/math/smoke/NextDownTest.h
create mode 100644 libc/test/src/math/smoke/NextUpTest.h
create mode 100644 libc/test/src/math/smoke/nextdown_test.cpp
create mode 100644 libc/test/src/math/smoke/nextdownf128_test.cpp
create mode 100644 libc/test/src/math/smoke/nextdownf_test.cpp
create mode 100644 libc/test/src/math/smoke/nextup_test.cpp
create mode 100644 libc/test/src/math/smoke/nextupf128_test.cpp
create mode 100644 libc/test/src/math/smoke/nextupf_test.cpp
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 4fb31c593b9dc7..f484ebf1d4df94 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -429,6 +429,10 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.nexttoward
libc.src.math.nexttowardf
libc.src.math.nexttowardl
+ libc.src.math.nextdown
+ libc.src.math.nextdownf
+ libc.src.math.nextup
+ libc.src.math.nextupf
libc.src.math.powf
libc.src.math.remainderf
libc.src.math.remainder
@@ -482,6 +486,8 @@ if(LIBC_TYPES_HAS_FLOAT128)
libc.src.math.lroundf128
libc.src.math.modff128
libc.src.math.nextafterf128
+ libc.src.math.nextdownf128
+ libc.src.math.nextupf128
libc.src.math.rintf128
libc.src.math.roundf128
libc.src.math.sqrtf128
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index afe01b1bb68566..118f9527e7264e 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -536,6 +536,14 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"nexttoward", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<LongDoubleType>]>,
FunctionSpec<"nexttowardl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
+ FunctionSpec<"nextdown", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
+ FunctionSpec<"nextdownf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
+ GuardedFunctionSpec<"nextdownf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
+
+ FunctionSpec<"nextup", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
+ FunctionSpec<"nextupf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
+ GuardedFunctionSpec<"nextupf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
+
FunctionSpec<"powf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"pow", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index f148d984f5f35c..c01cb4a5f823fb 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -230,6 +230,27 @@ LIBC_INLINE T nextafter(T from, U to) {
return from_bits.get_val();
}
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T nextupdown(T x, Sign sign) {
+ 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 != T(0)) {
+ if (xbits.sign() == sign) {
+ xbits = FPBits<T>(StorageType(xbits.uintval() + 1));
+ } else {
+ xbits = FPBits<T>(StorageType(xbits.uintval() - 1));
+ }
+ } else {
+ xbits = FPBits<T>::min_subnormal(sign);
+ }
+
+ return xbits.get_val();
+}
+
} // namespace fputil
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 750fd5f0e3a9ba..d5607585024735 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -204,6 +204,14 @@ add_math_entrypoint_object(nexttoward)
add_math_entrypoint_object(nexttowardf)
add_math_entrypoint_object(nexttowardl)
+add_math_entrypoint_object(nextdown)
+add_math_entrypoint_object(nextdownf)
+add_math_entrypoint_object(nextdownf128)
+
+add_math_entrypoint_object(nextup)
+add_math_entrypoint_object(nextupf)
+add_math_entrypoint_object(nextupf128)
+
add_math_entrypoint_object(pow)
add_math_entrypoint_object(powf)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 667381d615d1e0..fd3e846b9f7f41 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1865,6 +1865,80 @@ add_entrypoint_object(
-O3
)
+add_entrypoint_object(
+ nextdown
+ SRCS
+ nextdown.cpp
+ HDRS
+ ../nextdown.h
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
+ COMPILE_OPTIONS
+ -O3
+)
+
+add_entrypoint_object(
+ nextdownf
+ SRCS
+ nextdownf.cpp
+ HDRS
+ ../nextdownf.h
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
+ COMPILE_OPTIONS
+ -O3
+)
+
+add_entrypoint_object(
+ nextdownf128
+ SRCS
+ nextdownf128.cpp
+ HDRS
+ ../nextdownf128.h
+ DEPENDS
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.manipulation_functions
+ COMPILE_OPTIONS
+ -O3
+)
+
+add_entrypoint_object(
+ nextup
+ SRCS
+ nextup.cpp
+ HDRS
+ ../nextup.h
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
+ COMPILE_OPTIONS
+ -O3
+)
+
+add_entrypoint_object(
+ nextupf
+ SRCS
+ nextupf.cpp
+ HDRS
+ ../nextupf.h
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
+ COMPILE_OPTIONS
+ -O3
+)
+
+add_entrypoint_object(
+ nextupf128
+ SRCS
+ nextupf128.cpp
+ HDRS
+ ../nextupf128.h
+ DEPENDS
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.manipulation_functions
+ COMPILE_OPTIONS
+ -O3
+)
+
add_entrypoint_object(
fmod
SRCS
diff --git a/libc/src/math/generic/nextdown.cpp b/libc/src/math/generic/nextdown.cpp
new file mode 100644
index 00000000000000..664b5b1f585551
--- /dev/null
+++ b/libc/src/math/generic/nextdown.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextdown 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/nextdown.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, nextdown, (double x)) {
+ return fputil::nextupdown(x, fputil::Sign::NEG);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextdownf.cpp b/libc/src/math/generic/nextdownf.cpp
new file mode 100644
index 00000000000000..21c4f4f4a7a084
--- /dev/null
+++ b/libc/src/math/generic/nextdownf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextdownf 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/nextdownf.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, nextdownf, (float x)) {
+ return fputil::nextupdown(x, fputil::Sign::NEG);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextdownf128.cpp b/libc/src/math/generic/nextdownf128.cpp
new file mode 100644
index 00000000000000..487ea52cabd55a
--- /dev/null
+++ b/libc/src/math/generic/nextdownf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextdownf128 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/nextdownf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, nextdownf128, (float128 x)) {
+ return fputil::nextupdown(x, fputil::Sign::NEG);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextup.cpp b/libc/src/math/generic/nextup.cpp
new file mode 100644
index 00000000000000..bf58533e793b82
--- /dev/null
+++ b/libc/src/math/generic/nextup.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextup 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/nextup.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, nextup, (double x)) {
+ return fputil::nextupdown(x, fputil::Sign::POS);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextupf.cpp b/libc/src/math/generic/nextupf.cpp
new file mode 100644
index 00000000000000..2daebe7a5ff645
--- /dev/null
+++ b/libc/src/math/generic/nextupf.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextupf 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/nextupf.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, nextupf, (float x)) {
+ return fputil::nextupdown(x, fputil::Sign::POS);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextupf128.cpp b/libc/src/math/generic/nextupf128.cpp
new file mode 100644
index 00000000000000..09097a42480bf4
--- /dev/null
+++ b/libc/src/math/generic/nextupf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of nextupf128 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/nextupf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, nextupf128, (float128 x)) {
+ return fputil::nextupdown(x, fputil::Sign::POS);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/nextdown.h b/libc/src/math/nextdown.h
new file mode 100644
index 00000000000000..8049b170ee7211
--- /dev/null
+++ b/libc/src/math/nextdown.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextdown ----------------------*- 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_NEXTDOWN_H
+#define LLVM_LIBC_SRC_MATH_NEXTDOWN_H
+
+namespace LIBC_NAMESPACE {
+
+double nextdown(double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTDOWN_H
diff --git a/libc/src/math/nextdownf.h b/libc/src/math/nextdownf.h
new file mode 100644
index 00000000000000..0a2f23480574dc
--- /dev/null
+++ b/libc/src/math/nextdownf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextdownf ---------------------*- 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_NEXTDOWNF_H
+#define LLVM_LIBC_SRC_MATH_NEXTDOWNF_H
+
+namespace LIBC_NAMESPACE {
+
+float nextdownf(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNF_H
diff --git a/libc/src/math/nextdownf128.h b/libc/src/math/nextdownf128.h
new file mode 100644
index 00000000000000..0a3043bb431d82
--- /dev/null
+++ b/libc/src/math/nextdownf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for nextdownf128 ------------------*- 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_NEXTDOWNF128_H
+#define LLVM_LIBC_SRC_MATH_NEXTDOWNF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 nextdownf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNF128_H
diff --git a/libc/src/math/nextup.h b/libc/src/math/nextup.h
new file mode 100644
index 00000000000000..97ae82270b06e4
--- /dev/null
+++ b/libc/src/math/nextup.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextup ------------------------*- 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_NEXTUP_H
+#define LLVM_LIBC_SRC_MATH_NEXTUP_H
+
+namespace LIBC_NAMESPACE {
+
+double nextup(double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTUP_H
diff --git a/libc/src/math/nextupf.h b/libc/src/math/nextupf.h
new file mode 100644
index 00000000000000..ffc0fa168a1086
--- /dev/null
+++ b/libc/src/math/nextupf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nextupf -----------------------*- 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_NEXTUPF_H
+#define LLVM_LIBC_SRC_MATH_NEXTUPF_H
+
+namespace LIBC_NAMESPACE {
+
+float nextupf(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTUPF_H
diff --git a/libc/src/math/nextupf128.h b/libc/src/math/nextupf128.h
new file mode 100644
index 00000000000000..b4429922e4beb7
--- /dev/null
+++ b/libc/src/math/nextupf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for nextupf128 --------------------*- 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_NEXTUPF128_H
+#define LLVM_LIBC_SRC_MATH_NEXTUPF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 nextupf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTUPF128_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 293e65abd44f5a..13857d28c0e4d3 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1614,6 +1614,90 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ nextdown_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextdown_test.cpp
+ HDRS
+ NextDownTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.nextdown
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
+ nextdownf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextdownf_test.cpp
+ HDRS
+ NextDownTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.nextdownf
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
+ nextdownf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextdownf128_test.cpp
+ HDRS
+ NextDownTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.nextdownf128
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
+ nextup_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextup_test.cpp
+ HDRS
+ NextUpTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.nextup
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
+ nextupf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextupf_test.cpp
+ HDRS
+ NextUpTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.nextupf
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
+ nextupf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextupf128_test.cpp
+ HDRS
+ NextUpTest.h
+ DEPENDS
+ libc.include.math
+ libc.src.math.nextupf128
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
# TODO(lntue): The current implementation of fputil::general::fma<float> is only
# correctly rounded for the default rounding mode round-to-nearest tie-to-even.
add_fp_unittest(
diff --git a/libc/test/src/math/smoke/NextDownTest.h b/libc/test/src/math/smoke/NextDownTest.h
new file mode 100644
index 00000000000000..101c3926bf42ed
--- /dev/null
+++ b/libc/test/src/math/smoke/NextDownTest.h
@@ -0,0 +1,55 @@
+//===-- Utility class to test different flavors of nextdown -----*- 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_NEXTDOWNTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_NEXTDOWNTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class NextDownTestTemplate : public LIBC_NAMESPACE::testing::Test {
+ using FPBits = typename LIBC_NAMESPACE::fputil::FPBits<T>;
+ using Sign = typename LIBC_NAMESPACE::fputil::Sign;
+
+ static constexpr T inf = FPBits::inf().get_val();
+ static constexpr T neg_inf = FPBits::inf(Sign::NEG).get_val();
+ static constexpr T zero = FPBits::zero().get_val();
+ static constexpr T neg_zero = FPBits::zero(Sign::NEG).get_val();
+ static constexpr T nan = FPBits::quiet_nan().get_val();
+
+ static constexpr T min_subnormal = FPBits::min_subnormal().get_val();
+ static constexpr T neg_min_subnormal =
+ FPBits::min_subnormal(Sign::NEG).get_val();
+ static constexpr T max_normal = FPBits::max_normal().get_val();
+ static constexpr T neg_max_normal = FPBits::max_normal(Sign::NEG).get_val();
+
+public:
+ typedef T (*NextDownFunc)(T);
+
+ void testNaN(NextDownFunc func) { ASSERT_FP_EQ(func(nan), nan); }
+
+ void testBoundaries(NextDownFunc func) {
+ ASSERT_FP_EQ(zero, func(min_subnormal));
+
+ ASSERT_FP_EQ(neg_min_subnormal, func(zero));
+ ASSERT_FP_EQ(neg_min_subnormal, func(neg_zero));
+
+ ASSERT_FP_EQ(neg_max_normal, func(neg_max_normal));
+ ASSERT_FP_EQ(neg_inf, func(neg_inf));
+
+ ASSERT_FP_EQ(max_normal, func(inf));
+ }
+};
+
+#define LIST_NEXTDOWN_TESTS(T, func) \
+ using LlvmLibcNextDownTest = NextDownTestTemplate<T>; \
+ TEST_F(LlvmLibcNextDownTest, TestNaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcNextDownTest, TestBoundaries) { testBoundaries(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_NEXTDOWNTEST_H
diff --git a/libc/test/src/math/smoke/NextUpTest.h b/libc/test/src/math/smoke/NextUpTest.h
new file mode 100644
index 00000000000000..1db8f91cea4b4f
--- /dev/null
+++ b/libc/test/src/math/smoke/NextUpTest.h
@@ -0,0 +1,55 @@
+//===-- Utility class to test different flavors of nextup -------*- 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_NEXTUPTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_NEXTUPTEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class NextUpTestTemplate : public LIBC_NAMESPACE::testing::Test {
+ using FPBits = typename LIBC_NAMESPACE::fputil::FPBits<T>;
+ using Sign = typename LIBC_NAMESPACE::fputil::Sign;
+
+ static constexpr T inf = FPBits::inf().get_val();
+ static constexpr T neg_inf = FPBits::inf(Sign::NEG).get_val();
+ static constexpr T zero = FPBits::zero().get_val();
+ static constexpr T neg_zero = FPBits::zero(Sign::NEG).get_val();
+ static constexpr T nan = FPBits::quiet_nan().get_val();
+
+ static constexpr T min_subnormal = FPBits::min_subnormal().get_val();
+ static constexpr T neg_min_subnormal =
+ FPBits::min_subnormal(Sign::NEG).get_val();
+ static constexpr T max_normal = FPBits::max_normal().get_val();
+ static constexpr T neg_max_normal = FPBits::max_normal(Sign::NEG).get_val();
+
+public:
+ typedef T (*NextUpFunc)(T);
+
+ void testNaN(NextUpFunc func) { ASSERT_FP_EQ(func(nan), nan); }
+
+ void testBoundaries(NextUpFunc func) {
+ ASSERT_FP_EQ(neg_zero, func(neg_min_subnormal));
+
+ ASSERT_FP_EQ(min_subnormal, func(zero));
+ ASSERT_FP_EQ(min_subnormal, func(neg_zero));
+
+ ASSERT_FP_EQ(max_normal, func(max_normal));
+ ASSERT_FP_EQ(inf, func(inf));
+
+ ASSERT_FP_EQ(neg_max_normal, func(neg_inf));
+ }
+};
+
+#define LIST_NEXTUP_TESTS(T, func) \
+ using LlvmLibcNextUpTest = NextUpTestTemplate<T>; \
+ TEST_F(LlvmLibcNextUpTest, TestNaN) { testNaN(&func); } \
+ TEST_F(LlvmLibcNextUpTest, TestBoundaries) { testBoundaries(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_NEXTUPTEST_H
diff --git a/libc/test/src/math/smoke/nextdown_test.cpp b/libc/test/src/math/smoke/nextdown_test.cpp
new file mode 100644
index 00000000000000..6b0f5c6c5a6aa6
--- /dev/null
+++ b/libc/test/src/math/smoke/nextdown_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextdown --------------------------------------------===//
+//
+// 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/nextdown.h"
+
+LIST_NEXTDOWN_TESTS(double, LIBC_NAMESPACE::nextdown)
diff --git a/libc/test/src/math/smoke/nextdownf128_test.cpp b/libc/test/src/math/smoke/nextdownf128_test.cpp
new file mode 100644
index 00000000000000..932a8b36a59e47
--- /dev/null
+++ b/libc/test/src/math/smoke/nextdownf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextdownf128 ----------------------------------------===//
+//
+// 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/nextdownf128.h"
+
+LIST_NEXTDOWN_TESTS(float128, LIBC_NAMESPACE::nextdownf128)
diff --git a/libc/test/src/math/smoke/nextdownf_test.cpp b/libc/test/src/math/smoke/nextdownf_test.cpp
new file mode 100644
index 00000000000000..3c05c22d82049f
--- /dev/null
+++ b/libc/test/src/math/smoke/nextdownf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextdownf -------------------------------------------===//
+//
+// 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/nextdownf.h"
+
+LIST_NEXTDOWN_TESTS(float, LIBC_NAMESPACE::nextdownf)
diff --git a/libc/test/src/math/smoke/nextup_test.cpp b/libc/test/src/math/smoke/nextup_test.cpp
new file mode 100644
index 00000000000000..04c73ac9492f34
--- /dev/null
+++ b/libc/test/src/math/smoke/nextup_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextup ----------------------------------------------===//
+//
+// 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/nextup.h"
+
+LIST_NEXTUP_TESTS(double, LIBC_NAMESPACE::nextup)
diff --git a/libc/test/src/math/smoke/nextupf128_test.cpp b/libc/test/src/math/smoke/nextupf128_test.cpp
new file mode 100644
index 00000000000000..ddd385a7b159b4
--- /dev/null
+++ b/libc/test/src/math/smoke/nextupf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextupf128 ------------------------------------------===//
+//
+// 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/nextupf128.h"
+
+LIST_NEXTUP_TESTS(float128, LIBC_NAMESPACE::nextupf128)
diff --git a/libc/test/src/math/smoke/nextupf_test.cpp b/libc/test/src/math/smoke/nextupf_test.cpp
new file mode 100644
index 00000000000000..df73bee0117111
--- /dev/null
+++ b/libc/test/src/math/smoke/nextupf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for nextupf ---------------------------------------------===//
+//
+// 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/nextupf.h"
+
+LIST_NEXTUP_TESTS(float, LIBC_NAMESPACE::nextupf)
>From f49f9a986e7ee5ac5a4c59b1d7fcd50f950bd5ed Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Fri, 15 Mar 2024 18:46:48 +0000
Subject: [PATCH 2/2] fixup! [libc][math][c23] Add nextup{,f,f128} and
nextdown{,f,f128} functions
---
.../__support/FPUtil/ManipulationFunctions.h | 7 ++++--
libc/src/math/generic/nextdown.cpp | 2 +-
libc/src/math/generic/nextdownf.cpp | 2 +-
libc/src/math/generic/nextdownf128.cpp | 2 +-
libc/src/math/generic/nextup.cpp | 2 +-
libc/src/math/generic/nextupf.cpp | 2 +-
libc/src/math/generic/nextupf128.cpp | 2 +-
libc/test/UnitTest/FPMatcher.h | 6 +++--
libc/test/src/math/smoke/NextDownTest.h | 22 +++++--------------
libc/test/src/math/smoke/NextUpTest.h | 22 +++++--------------
10 files changed, 25 insertions(+), 44 deletions(-)
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index c01cb4a5f823fb..1301caa497da44 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -230,8 +230,11 @@ LIBC_INLINE T nextafter(T from, U to) {
return from_bits.get_val();
}
-template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T nextupdown(T x, Sign sign) {
+template <bool IsDown, typename T,
+ cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE constexpr T nextupdown(T x) {
+ constexpr Sign sign = IsDown ? Sign::NEG : Sign::POS;
+
FPBits<T> xbits(x);
if (xbits.is_nan() || xbits == FPBits<T>::max_normal(sign) ||
xbits == FPBits<T>::inf(sign))
diff --git a/libc/src/math/generic/nextdown.cpp b/libc/src/math/generic/nextdown.cpp
index 664b5b1f585551..51dee483b70e62 100644
--- a/libc/src/math/generic/nextdown.cpp
+++ b/libc/src/math/generic/nextdown.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, nextdown, (double x)) {
- return fputil::nextupdown(x, fputil::Sign::NEG);
+ return fputil::nextupdown</*IsDown=*/true>(x);
}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextdownf.cpp b/libc/src/math/generic/nextdownf.cpp
index 21c4f4f4a7a084..857b412d64c3c4 100644
--- a/libc/src/math/generic/nextdownf.cpp
+++ b/libc/src/math/generic/nextdownf.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, nextdownf, (float x)) {
- return fputil::nextupdown(x, fputil::Sign::NEG);
+ return fputil::nextupdown</*IsDown=*/true>(x);
}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextdownf128.cpp b/libc/src/math/generic/nextdownf128.cpp
index 487ea52cabd55a..2585a13df3a3c2 100644
--- a/libc/src/math/generic/nextdownf128.cpp
+++ b/libc/src/math/generic/nextdownf128.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float128, nextdownf128, (float128 x)) {
- return fputil::nextupdown(x, fputil::Sign::NEG);
+ return fputil::nextupdown</*IsDown=*/true>(x);
}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextup.cpp b/libc/src/math/generic/nextup.cpp
index bf58533e793b82..d75a336eefcc8a 100644
--- a/libc/src/math/generic/nextup.cpp
+++ b/libc/src/math/generic/nextup.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, nextup, (double x)) {
- return fputil::nextupdown(x, fputil::Sign::POS);
+ return fputil::nextupdown</*IsDown=*/false>(x);
}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextupf.cpp b/libc/src/math/generic/nextupf.cpp
index 2daebe7a5ff645..3b18dae4488d4d 100644
--- a/libc/src/math/generic/nextupf.cpp
+++ b/libc/src/math/generic/nextupf.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, nextupf, (float x)) {
- return fputil::nextupdown(x, fputil::Sign::POS);
+ return fputil::nextupdown</*IsDown=*/false>(x);
}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nextupf128.cpp b/libc/src/math/generic/nextupf128.cpp
index 09097a42480bf4..7d862c30976cb4 100644
--- a/libc/src/math/generic/nextupf128.cpp
+++ b/libc/src/math/generic/nextupf128.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float128, nextupf128, (float128 x)) {
- return fputil::nextupdown(x, fputil::Sign::POS);
+ return fputil::nextupdown</*IsDown=*/false>(x);
}
} // namespace LIBC_NAMESPACE
diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index 4525b9e830195e..ae9d674e4d39b5 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -102,8 +102,10 @@ template <typename T> struct FPTest : public Test {
const T inf = FPBits::inf(Sign::POS).get_val(); \
const T neg_inf = FPBits::inf(Sign::NEG).get_val(); \
const T min_normal = FPBits::min_normal().get_val(); \
- const T max_normal = FPBits::max_normal().get_val(); \
- const T min_denormal = FPBits::min_subnormal().get_val(); \
+ const T max_normal = FPBits::max_normal(Sign::POS).get_val(); \
+ const T neg_max_normal = FPBits::max_normal(Sign::NEG).get_val(); \
+ const T min_denormal = FPBits::min_subnormal(Sign::POS).get_val(); \
+ const T neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val(); \
const T max_denormal = FPBits::max_subnormal().get_val();
#define EXPECT_FP_EQ(expected, actual) \
diff --git a/libc/test/src/math/smoke/NextDownTest.h b/libc/test/src/math/smoke/NextDownTest.h
index 101c3926bf42ed..c678ab1db1deff 100644
--- a/libc/test/src/math/smoke/NextDownTest.h
+++ b/libc/test/src/math/smoke/NextDownTest.h
@@ -14,31 +14,19 @@
template <typename T>
class NextDownTestTemplate : public LIBC_NAMESPACE::testing::Test {
- using FPBits = typename LIBC_NAMESPACE::fputil::FPBits<T>;
- using Sign = typename LIBC_NAMESPACE::fputil::Sign;
- static constexpr T inf = FPBits::inf().get_val();
- static constexpr T neg_inf = FPBits::inf(Sign::NEG).get_val();
- static constexpr T zero = FPBits::zero().get_val();
- static constexpr T neg_zero = FPBits::zero(Sign::NEG).get_val();
- static constexpr T nan = FPBits::quiet_nan().get_val();
-
- static constexpr T min_subnormal = FPBits::min_subnormal().get_val();
- static constexpr T neg_min_subnormal =
- FPBits::min_subnormal(Sign::NEG).get_val();
- static constexpr T max_normal = FPBits::max_normal().get_val();
- static constexpr T neg_max_normal = FPBits::max_normal(Sign::NEG).get_val();
+ DECLARE_SPECIAL_CONSTANTS(T)
public:
typedef T (*NextDownFunc)(T);
- void testNaN(NextDownFunc func) { ASSERT_FP_EQ(func(nan), nan); }
+ void testNaN(NextDownFunc func) { ASSERT_FP_EQ(func(aNaN), aNaN); }
void testBoundaries(NextDownFunc func) {
- ASSERT_FP_EQ(zero, func(min_subnormal));
+ ASSERT_FP_EQ(zero, func(min_denormal));
- ASSERT_FP_EQ(neg_min_subnormal, func(zero));
- ASSERT_FP_EQ(neg_min_subnormal, func(neg_zero));
+ ASSERT_FP_EQ(neg_min_denormal, func(zero));
+ ASSERT_FP_EQ(neg_min_denormal, func(neg_zero));
ASSERT_FP_EQ(neg_max_normal, func(neg_max_normal));
ASSERT_FP_EQ(neg_inf, func(neg_inf));
diff --git a/libc/test/src/math/smoke/NextUpTest.h b/libc/test/src/math/smoke/NextUpTest.h
index 1db8f91cea4b4f..ebbdb5c73def9e 100644
--- a/libc/test/src/math/smoke/NextUpTest.h
+++ b/libc/test/src/math/smoke/NextUpTest.h
@@ -14,31 +14,19 @@
template <typename T>
class NextUpTestTemplate : public LIBC_NAMESPACE::testing::Test {
- using FPBits = typename LIBC_NAMESPACE::fputil::FPBits<T>;
- using Sign = typename LIBC_NAMESPACE::fputil::Sign;
- static constexpr T inf = FPBits::inf().get_val();
- static constexpr T neg_inf = FPBits::inf(Sign::NEG).get_val();
- static constexpr T zero = FPBits::zero().get_val();
- static constexpr T neg_zero = FPBits::zero(Sign::NEG).get_val();
- static constexpr T nan = FPBits::quiet_nan().get_val();
-
- static constexpr T min_subnormal = FPBits::min_subnormal().get_val();
- static constexpr T neg_min_subnormal =
- FPBits::min_subnormal(Sign::NEG).get_val();
- static constexpr T max_normal = FPBits::max_normal().get_val();
- static constexpr T neg_max_normal = FPBits::max_normal(Sign::NEG).get_val();
+ DECLARE_SPECIAL_CONSTANTS(T)
public:
typedef T (*NextUpFunc)(T);
- void testNaN(NextUpFunc func) { ASSERT_FP_EQ(func(nan), nan); }
+ void testNaN(NextUpFunc func) { ASSERT_FP_EQ(func(aNaN), aNaN); }
void testBoundaries(NextUpFunc func) {
- ASSERT_FP_EQ(neg_zero, func(neg_min_subnormal));
+ ASSERT_FP_EQ(neg_zero, func(neg_min_denormal));
- ASSERT_FP_EQ(min_subnormal, func(zero));
- ASSERT_FP_EQ(min_subnormal, func(neg_zero));
+ ASSERT_FP_EQ(min_denormal, func(zero));
+ ASSERT_FP_EQ(min_denormal, func(neg_zero));
ASSERT_FP_EQ(max_normal, func(max_normal));
ASSERT_FP_EQ(inf, func(inf));
More information about the libc-commits
mailing list