diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp index 3f6f553e7bb554..df73502bee5fed 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::quiet_NaN(); } else if (std::isinf(p)) { return a; + } else 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. + 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