[libc-commits] [libc] 86b0cca - [libc][NFC] unify nextafter and nexttoward code (#73698)

via libc-commits libc-commits at lists.llvm.org
Tue Nov 28 15:14:20 PST 2023


Author: michaelrj-google
Date: 2023-11-28T15:14:15-08:00
New Revision: 86b0ccaee12221d088b35b7b57d415ba290fabb9

URL: https://github.com/llvm/llvm-project/commit/86b0ccaee12221d088b35b7b57d415ba290fabb9
DIFF: https://github.com/llvm/llvm-project/commit/86b0ccaee12221d088b35b7b57d415ba290fabb9.diff

LOG: [libc][NFC] unify nextafter and nexttoward code (#73698)

Previously the nextafter and nexttoward implementations were almost
identical, with the exception of whether or not the second argument was
a template or just long double. This patch unifies them by making the
two argument templates independent.

Added: 
    

Modified: 
    libc/src/__support/FPUtil/ManipulationFunctions.h
    libc/src/math/generic/nexttoward.cpp
    libc/src/math/generic/nexttowardf.cpp
    libc/src/math/generic/nexttowardl.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index f1768885d4ca500..9286deee2d92c47 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -144,59 +144,26 @@ LIBC_INLINE T ldexp(T x, int exp) {
   return normal;
 }
 
-template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T nextafter(T from, T to) {
-  FPBits<T> from_bits(from);
-  if (from_bits.is_nan())
-    return from;
-
-  FPBits<T> to_bits(to);
-  if (to_bits.is_nan())
-    return to;
-
-  if (from == to)
-    return to;
-
-  using UIntType = typename FPBits<T>::UIntType;
-  UIntType int_val = from_bits.uintval();
-  UIntType sign_mask = (UIntType(1) << (sizeof(T) * 8 - 1));
-  if (from != T(0.0)) {
-    if ((from < to) == (from > T(0.0))) {
-      ++int_val;
-    } else {
-      --int_val;
-    }
-  } else {
-    int_val = (to_bits.uintval() & sign_mask) + UIntType(1);
-  }
-
-  UIntType exponent_bits = int_val & FloatProperties<T>::EXPONENT_MASK;
-  if (exponent_bits == UIntType(0))
-    raise_except_if_required(FE_UNDERFLOW | FE_INEXACT);
-  else if (exponent_bits == FloatProperties<T>::EXPONENT_MASK)
-    raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
-
-  return cpp::bit_cast<T>(int_val);
-}
-
-template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T>
-nexttoward(T from, long double to) {
+template <
+    typename T, typename U,
+    cpp::enable_if_t<cpp::is_floating_point_v<T> && cpp::is_floating_point_v<U>,
+                     int> = 0>
+LIBC_INLINE T nextafter(T from, U to) {
   FPBits<T> from_bits(from);
   if (from_bits.is_nan())
     return from;
 
-  FPBits<long double> to_bits(to);
+  FPBits<U> to_bits(to);
   if (to_bits.is_nan())
-    return to;
+    return static_cast<T>(to);
 
-  if ((long double)from == to)
-    return to;
+  if (static_cast<U>(from) == to)
+    return static_cast<T>(to);
 
   using UIntType = typename FPBits<T>::UIntType;
   UIntType int_val = from_bits.uintval();
-  if (from != T(0.0)) {
-    if ((from < to) == (from > T(0.0))) {
+  if (from != FPBits<T>::zero()) {
+    if ((static_cast<U>(from) < to) == (from > FPBits<T>::zero())) {
       ++int_val;
     } else {
       --int_val;

diff  --git a/libc/src/math/generic/nexttoward.cpp b/libc/src/math/generic/nexttoward.cpp
index 38b45d6d2f65d9c..ce3e4e6a69ad231 100644
--- a/libc/src/math/generic/nexttoward.cpp
+++ b/libc/src/math/generic/nexttoward.cpp
@@ -13,7 +13,9 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(double, nexttoward, (double x, long double y)) {
-  return fputil::nexttoward(x, y);
+  // We can reuse the nextafter implementation because the internal nextafter is
+  // templated on the types of the arguments.
+  return fputil::nextafter(x, y);
 }
 
 } // namespace LIBC_NAMESPACE

diff  --git a/libc/src/math/generic/nexttowardf.cpp b/libc/src/math/generic/nexttowardf.cpp
index 59a9f805a6946a1..3b0762c50160ac1 100644
--- a/libc/src/math/generic/nexttowardf.cpp
+++ b/libc/src/math/generic/nexttowardf.cpp
@@ -13,7 +13,9 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(float, nexttowardf, (float x, long double y)) {
-  return fputil::nexttoward(x, y);
+  // We can reuse the nextafter implementation because the internal nextafter is
+  // templated on the types of the arguments.
+  return fputil::nextafter(x, y);
 }
 
 } // namespace LIBC_NAMESPACE

diff  --git a/libc/src/math/generic/nexttowardl.cpp b/libc/src/math/generic/nexttowardl.cpp
index 0c887ae0671bc98..e9f7f8390760342 100644
--- a/libc/src/math/generic/nexttowardl.cpp
+++ b/libc/src/math/generic/nexttowardl.cpp
@@ -13,9 +13,8 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(long double, nexttowardl, (long double x, long double y)) {
-  // We can reuse the nextafter implementation because nexttoward behaves
-  // exactly same as nextafter in case of long doubles. Also, we have explcitly
-  // handled the special 80-bit long doubles in nextafter implementation.
+  // We can reuse the nextafter implementation because the internal nextafter is
+  // templated on the types of the arguments.
   return fputil::nextafter(x, y);
 }
 


        


More information about the libc-commits mailing list