[flang-commits] [flang] [flang][runtime] Use std::fmod for most MOD/MODULO (PR #78745)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Fri Jan 19 10:09:05 PST 2024
https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/78745
>From 41f5c93e4a63ce95a877909c283bd85b945eea78 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Fri, 19 Jan 2024 09:01:20 -0800
Subject: [PATCH] [flang][runtime] Use std::fmod for most MOD/MODULO
The new accurate algorithm for real MOD and MODULO in the
runtime is not as fast as std::fmod(), which is also
accurate. So use std::fmod() for those floating-point
types that it supports.
Fixes https://github.com/llvm/llvm-project/issues/78641.
---
flang/runtime/numeric.cpp | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 3f6f553e7bb554..df73502bee5fed 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -144,6 +144,21 @@ inline RT_API_ATTRS T RealMod(
return std::numeric_limits<T>::quiet_NaN();
} else if (std::isinf(p)) {
return a;
+ } else if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double> ||
+ std::is_same_v<T, long double>) {
+ // std::fmod() semantics on signed operands seems to match
+ // the requirements of MOD(). MODULO() needs adjustment.
+ T result{std::fmod(a, p)};
+ if constexpr (IS_MODULO) {
+ if ((a < 0) != (p < 0)) {
+ if (result == 0.) {
+ result = -result;
+ } else {
+ result += p;
+ }
+ }
+ }
+ return result;
} else {
// The standard defines MOD(a,p)=a-AINT(a/p)*p and
// MODULO(a,p)=a-FLOOR(a/p)*p, but those definitions lose
More information about the flang-commits
mailing list