[libc-commits] [libc] [libc][math][c23] Add nextupl and nextdownl functions (PR #85484)

via libc-commits libc-commits at lists.llvm.org
Fri Mar 15 16:47:36 PDT 2024


https://github.com/overmighty created https://github.com/llvm/llvm-project/pull/85484

Fixes #85283.

cc @lntue

>From 5a2753f4c33d02bfb08fd2d0c16c60a2f0c21ffc Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Fri, 15 Mar 2024 23:43:32 +0000
Subject: [PATCH] [libc][math][c23] Add nextupl and nextdownl functions

Fixes #85283.
---
 libc/config/linux/x86_64/entrypoints.txt      |  2 +
 libc/docs/math/index.rst                      | 16 ++++++
 libc/spec/stdc.td                             |  2 +
 .../__support/FPUtil/ManipulationFunctions.h  |  1 +
 .../FPUtil/x86_64/NextUpDownLongDouble.h      | 56 +++++++++++++++++++
 libc/src/math/CMakeLists.txt                  |  2 +
 libc/src/math/generic/CMakeLists.txt          | 24 ++++++++
 libc/src/math/generic/nextdownl.cpp           | 19 +++++++
 libc/src/math/generic/nextupl.cpp             | 19 +++++++
 libc/src/math/nextdownl.h                     | 18 ++++++
 libc/src/math/nextupl.h                       | 18 ++++++
 libc/test/src/math/smoke/CMakeLists.txt       | 28 ++++++++++
 libc/test/src/math/smoke/nextdownl_test.cpp   | 13 +++++
 libc/test/src/math/smoke/nextupl_test.cpp     | 13 +++++
 14 files changed, 231 insertions(+)
 create mode 100644 libc/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h
 create mode 100644 libc/src/math/generic/nextdownl.cpp
 create mode 100644 libc/src/math/generic/nextupl.cpp
 create mode 100644 libc/src/math/nextdownl.h
 create mode 100644 libc/src/math/nextupl.h
 create mode 100644 libc/test/src/math/smoke/nextdownl_test.cpp
 create mode 100644 libc/test/src/math/smoke/nextupl_test.cpp

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)



More information about the libc-commits mailing list