From 6fa5353a5696bf8c4c2689126a025330c72aa8f9 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Wed, 2 Jun 2021 16:59:31 -0700 Subject: [PATCH] [flang] Fix folding of CMPLX The code for folding calls to the intrinsic function CMPLX was incorrectly dependent on the number of arguments to distinguish its two cases (conversion from one kind of complex to another, and composition of a complex value from real & imaginary parts). This was wrong since the optional KIND= argument has already been taken into account by intrinsic processing; instead, the type of the first argument should decide the issue. Differential Revision: https://reviews.llvm.org/D103568 --- flang/lib/Evaluate/fold-complex.cpp | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/flang/lib/Evaluate/fold-complex.cpp b/flang/lib/Evaluate/fold-complex.cpp index de541e1..2e574aa 100644 --- a/flang/lib/Evaluate/fold-complex.cpp +++ b/flang/lib/Evaluate/fold-complex.cpp @@ -34,25 +34,23 @@ Expr> FoldIntrinsicFunction( return FoldElementalIntrinsic( context, std::move(funcRef), &Scalar::CONJG); } else if (name == "cmplx") { - using Part = typename T::Part; - if (args.size() == 2) { // CMPLX(X, [KIND]) + if (args.size() > 0 && args[0].has_value()) { if (auto *x{UnwrapExpr>(args[0])}) { + // CMPLX(X [, KIND]) with complex X return Fold(context, ConvertToType(std::move(*x))); + } else { + // CMPLX(X [, Y [, KIND]]) with non-complex X + using Part = typename T::Part; + Expr re{std::move(*args[0].value().UnwrapExpr())}; + Expr im{args.size() >= 2 && args[1].has_value() + ? std::move(*args[1]->UnwrapExpr()) + : AsGenericExpr(Constant{Scalar{}})}; + return Fold(context, + Expr{ + ComplexConstructor{ToReal(context, std::move(re)), + ToReal(context, std::move(im))}}); } - Expr re{std::move(*args[0].value().UnwrapExpr())}; - Expr im{AsGenericExpr(Constant{Scalar{}})}; - return Fold(context, - Expr{ComplexConstructor{ToReal(context, std::move(re)), - ToReal(context, std::move(im))}}); } - // CMPLX(X, [Y, KIND]) - CHECK(args.size() == 3); - Expr re{std::move(*args[0].value().UnwrapExpr())}; - Expr im{args[1] ? std::move(*args[1].value().UnwrapExpr()) - : AsGenericExpr(Constant{Scalar{}})}; - return Fold(context, - Expr{ComplexConstructor{ToReal(context, std::move(re)), - ToReal(context, std::move(im))}}); } else if (name == "merge") { return FoldMerge(context, std::move(funcRef)); } -- 2.7.4