From 3e07767efffbaa57c99fbb2fd2f1f5f9bc0c651e Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Fri, 8 Sep 2023 08:27:11 -0700 Subject: [PATCH] [flang] Improve length information in character transformational Intrinsic resolution currently does not resolve constant length information for character transformational (with "sameChar") where the argument has constant length but is not a variable. It is not required to fold those expressions (only inquiry on constant expression or variable with constant length is required to be a constant expression). But constant length information for character is valuable for lowering, so I think this is a nice and easy to have. --- flang/lib/Evaluate/intrinsics.cpp | 10 +++++++++- flang/test/Evaluate/fold-substr.f90 | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp index fd549dd816559..030e5b2fd2c6d 100644 --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -2093,7 +2093,15 @@ std::optional IntrinsicInterface::Match( CHECK(sameArg); if (std::optional aType{sameArg->GetType()}) { if (result.categorySet.test(aType->category())) { - resultType = *aType; + if (const auto *sameChar{UnwrapExpr>(*sameArg)}) { + if (auto len{ToInt64(Fold(context, sameChar->LEN()))}) { + resultType = DynamicType{aType->kind(), *len}; + } else { + resultType = *aType; + } + } else { + resultType = *aType; + } } else { resultType = DynamicType{*category, aType->kind()}; } diff --git a/flang/test/Evaluate/fold-substr.f90 b/flang/test/Evaluate/fold-substr.f90 index b36887e7f4dfd..daf62bd197ace 100644 --- a/flang/test/Evaluate/fold-substr.f90 +++ b/flang/test/Evaluate/fold-substr.f90 @@ -20,3 +20,11 @@ module m logical, parameter :: test_07d = ca(1)(5:) == "" logical, parameter :: test_07e = ca(1)(:) == "abcd" end module + +subroutine foo(x) + character(4) :: x(:, :) + logical, parameter :: test_01 = len(transpose(x(:, :)(:))) == 4 + logical, parameter :: test_02 = len(transpose(x(:, :)(1:2))) == 2 + logical, parameter :: test_03 = len(maxval(x(:, :)(:))) == 4 + logical, parameter :: test_04 = len(maxval(x(:, :)(1:2))) == 2 +end subroutine