Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flang][runtime] Add special-case faster path to real MOD/MODULO #79625

Merged
merged 1 commit into from
Jan 29, 2024

Conversation

klausler
Copy link
Contributor

When a real-valued reference to the MOD/MODULO intrinsic functions has operands that are exact integers, use the fast exact integer algorithm rather than calling std::fmod.

When a real-valued reference to the MOD/MODULO intrinsic functions
has operands that are exact integers, use the fast exact integer
algorithm rather than calling std::fmod.
@llvmbot llvmbot added flang:runtime flang Flang issues not falling into any other category labels Jan 26, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 26, 2024

@llvm/pr-subscribers-flang-runtime

Author: Peter Klausler (klausler)

Changes

When a real-valued reference to the MOD/MODULO intrinsic functions has operands that are exact integers, use the fast exact integer algorithm rather than calling std::fmod.


Full diff: https://github.com/llvm/llvm-project/pull/79625.diff

1 Files Affected:

  • (modified) flang/runtime/numeric.cpp (+12-1)
diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index df73502bee5fed..8e512aff1ea1d3 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -144,7 +144,18 @@ 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> ||
+  }
+  if (auto aInt{static_cast<std::int64_t>(a)}; a == aInt) {
+    if (auto pInt{static_cast<std::int64_t>(p)}; p == pInt) {
+      // Fast exact case for integer operands
+      auto mod{aInt - (aInt / pInt) * pInt};
+      if (IS_MODULO && (aInt > 0) != (pInt > 0)) {
+        mod += pInt;
+      }
+      return static_cast<T>(mod);
+    }
+  }
+  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.

Copy link
Contributor

@vzakhari vzakhari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! It improves performance of the ac benchmark.

@klausler klausler merged commit e6fdbd1 into llvm:main Jan 29, 2024
6 checks passed
@klausler klausler deleted the fmod branch January 29, 2024 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:runtime flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants