diff --git a/flang-rt/lib/runtime/numeric.cpp b/flang-rt/lib/runtime/numeric.cpp index 37638765dc65..78f148dbc5d8 100644 --- a/flang-rt/lib/runtime/numeric.cpp +++ b/flang-rt/lib/runtime/numeric.cpp @@ -229,6 +229,24 @@ RT_API_ATTRS BTy FPowI(BTy base, ETy exp) { return result; } +// Exponentiation operator for (Unsigned ** Unsigned) cases +template RT_API_ATTRS Ty UPow(Ty base, Ty exp) { + if (exp == Ty{0}) + return Ty{1}; + Ty result{1}; + while (true) { + if (exp & Ty{1}) { + result *= base; + } + exp >>= 1; + if (exp == Ty{0}) { + break; + } + base *= base; + } + return result; +} + extern "C" { RT_EXT_API_GROUP_BEGIN @@ -933,6 +951,27 @@ CppTypeFor RTDEF(FPow16k)( } #endif +CppTypeFor RTDEF(UPow1)( + CppTypeFor b, + CppTypeFor e) { + return UPow(b, e); +} +CppTypeFor RTDEF(UPow2)( + CppTypeFor b, + CppTypeFor e) { + return UPow(b, e); +} +CppTypeFor RTDEF(UPow4)( + CppTypeFor b, + CppTypeFor e) { + return UPow(b, e); +} +CppTypeFor RTDEF(UPow8)( + CppTypeFor b, + CppTypeFor e) { + return UPow(b, e); +} + RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/include/flang/Evaluate/expression.h b/flang/include/flang/Evaluate/expression.h index 1203fca8640a..f7a1f9b95518 100644 --- a/flang/include/flang/Evaluate/expression.h +++ b/flang/include/flang/Evaluate/expression.h @@ -566,9 +566,9 @@ private: using Conversions = std::tuple, Convert, Convert>; - using Operations = - std::tuple, Negate, Add, - Subtract, Multiply, Divide, Extremum>; + using Operations = std::tuple, Negate, + Add, Subtract, Multiply, Divide, + Power, Extremum>; using Others = std::tuple, ArrayConstructor, Designator, FunctionRef>; diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index 7fcd04778301..225e1a77f041 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -750,11 +750,11 @@ Expr> PromoteAndCombine( // one of the operands to the type of the other. Handles special cases with // typeless literal operands and with REAL/COMPLEX exponentiation to INTEGER // powers. -template