[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