diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp --- a/flang/lib/Evaluate/fold-real.cpp +++ b/flang/lib/Evaluate/fold-real.cpp @@ -149,10 +149,15 @@ } else if (name == "dot_product") { return FoldDotProduct(context, std::move(funcRef)); } else if (name == "dprod") { - if (auto scalars{GetScalarConstantArguments(context, args)}) { - return Fold(context, - Expr{Multiply{ - Expr{std::get<0>(*scalars)}, Expr{std::get<1>(*scalars)}}}); + // Rewrite DPROD(x,y) -> DBLE(x)*DBLE(y) + if (args.at(0) && args.at(1)) { + const auto *xExpr{args[0]->UnwrapExpr()}; + const auto *yExpr{args[1]->UnwrapExpr()}; + if (xExpr && yExpr) { + return Fold(context, + ToReal(context, common::Clone(*xExpr)) * + ToReal(context, common::Clone(*yExpr))); + } } } else if (name == "epsilon") { return Expr{Scalar::EPSILON()}; diff --git a/flang/test/Evaluate/fold-dprod.f90 b/flang/test/Evaluate/fold-dprod.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Evaluate/fold-dprod.f90 @@ -0,0 +1,8 @@ +! RUN: %python %S/test_folding.py %s %flang_fc1 +! Tests folding of DPROD() +module m + logical, parameter :: test_kind = kind(dprod(2., 3.)) == kind(0.d0) + logical, parameter :: test_ss = dprod(2., 3.) == 6.d0 + logical, parameter :: test_sv = all(dprod(2., [3.,4.]) == [6.d0,8.d0]) + logical, parameter :: test_vv = all(dprod([2.,3.], [4.,5.]) == [8.d0,15.0d0]) +end