[flang-commits] [flang] 39c2f59 - [flang][runtime] Fix NEAREST() when exponent decreases (#75368)

via flang-commits flang-commits at lists.llvm.org
Tue Dec 26 15:28:40 PST 2023


Author: Peter Klausler
Date: 2023-12-26T15:28:36-08:00
New Revision: 39c2f59709f454f04cc13151301ca19c4ba9c152

URL: https://github.com/llvm/llvm-project/commit/39c2f59709f454f04cc13151301ca19c4ba9c152
DIFF: https://github.com/llvm/llvm-project/commit/39c2f59709f454f04cc13151301ca19c4ba9c152.diff

LOG: [flang][runtime] Fix NEAREST() when exponent decreases (#75368)

When the result of NEAREST() has an exponent less than that of the
argument (e.g., NEAREST(1.,-1.) and NEAREST(-1.,1.)), the result was
wrong, because the increment value uses the result of SPACING() in terms
of the argument. Fix by just calling into the C runtime routine
std::nextafter().

Added: 
    

Modified: 
    flang/runtime/numeric.cpp
    flang/unittests/Runtime/Numeric.cpp

Removed: 
    


################################################################################
diff  --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 25e58e79dbba0e..38835c2b753cef 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -261,12 +261,10 @@ template <int PREC, typename T> inline RT_API_ATTRS T Spacing(T x) {
 // NEAREST (16.9.139)
 template <int PREC, typename T>
 inline RT_API_ATTRS T Nearest(T x, bool positive) {
-  auto spacing{Spacing<PREC>(x)};
-  if (x == 0) {
-    auto least{std::numeric_limits<T>::denorm_min()};
-    return positive ? least : -least;
+  if (positive) {
+    return std::nextafter(x, std::numeric_limits<T>::infinity());
   } else {
-    return positive ? x + spacing : x - spacing;
+    return std::nextafter(x, -std::numeric_limits<T>::infinity());
   }
 }
 

diff  --git a/flang/unittests/Runtime/Numeric.cpp b/flang/unittests/Runtime/Numeric.cpp
index 5afed750c0b183..43263d1ac42315 100644
--- a/flang/unittests/Runtime/Numeric.cpp
+++ b/flang/unittests/Runtime/Numeric.cpp
@@ -86,7 +86,7 @@ TEST(Numeric, Nearest) {
   EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, true),
       Real<8>{1.0} + std::ldexp(Real<8>{1.0}, -52));
   EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, false),
-      Real<8>{1.0} - std::ldexp(Real<8>{1.0}, -52));
+      Real<8>{1.0} - 0.5 * std::ldexp(Real<8>{1.0}, -52));
 }
 
 TEST(Numeric, Nint) {


        


More information about the flang-commits mailing list