[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 09:44:27 PST 2024


https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/78745

>From 33d46a88dea1288ed219382fe7478321ee49bb69 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 | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 3f6f553e7bb554..a5994f1081b026 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -144,6 +144,20 @@ 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) {
+        result = -result;
+      }
+      if ((a < 0) != (p < 0)) {
+        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