diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp index df73502bee5fe..8e512aff1ea1d 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::quiet_NaN(); } else if (std::isinf(p)) { return a; - } else if constexpr (std::is_same_v || std::is_same_v || + } + if (auto aInt{static_cast(a)}; a == aInt) { + if (auto pInt{static_cast(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(mod); + } + } + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) { // std::fmod() semantics on signed operands seems to match // the requirements of MOD(). MODULO() needs adjustment.