[flang-commits] [flang] e8a5010 - [flang][runtime] Use std::fmod for most MOD/MODULO (#78745)
via flang-commits
flang-commits at lists.llvm.org
Thu Jan 25 15:24:59 PST 2024
Author: Peter Klausler
Date: 2024-01-25T15:24:54-08:00
New Revision: e8a5010c0338357c08c740de121b660aa933d5f4
URL: https://github.com/llvm/llvm-project/commit/e8a5010c0338357c08c740de121b660aa933d5f4
DIFF: https://github.com/llvm/llvm-project/commit/e8a5010c0338357c08c740de121b660aa933d5f4.diff
LOG: [flang][runtime] Use std::fmod for most MOD/MODULO (#78745)
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.
Added:
Modified:
flang/runtime/numeric.cpp
Removed:
################################################################################
diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 3f6f553e7bb554d..df73502bee5fed0 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