[flang-commits] [flang] [flang][runtime] Fix NEAREST() when exponent decreases (PR #75368)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon Dec 25 13:27:11 PST 2023
https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/75368
>From b77276145005f827a70872d150f2c6252b5b2718 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 13 Dec 2023 11:16:04 -0800
Subject: [PATCH] [flang][runtime] Fix NEAREST() when exponent decreases
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().
Fixes llvm-test-suite/Fortran/gfortran/regression/fold_nearest.f90.
---
flang/runtime/numeric.cpp | 8 +++-----
flang/unittests/Runtime/Numeric.cpp | 2 +-
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 25e58e79dbba0e5..38835c2b753cef2 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 5afed750c0b1830..43263d1ac423159 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