[flang-commits] [flang] [flang] Improve length information in character transformational (PR #65771)

via flang-commits flang-commits at lists.llvm.org
Fri Sep 8 08:41:34 PDT 2023


https://github.com/jeanPerier created https://github.com/llvm/llvm-project/pull/65771:

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 or a constant expression.

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.

Addresses my comment in https://github.com/llvm/llvm-project/pull/65705#discussion_r1319902912 where the patch is adding code to in lowering manually get constant length info into FIR type system for maxval intrinsic result instead of relying on what LEN() is able to provide.

>From 3e07767efffbaa57c99fbb2fd2f1f5f9bc0c651e Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
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 fd549dd8165599..030e5b2fd2c6d9 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -2093,7 +2093,15 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
       CHECK(sameArg);
       if (std::optional<DynamicType> aType{sameArg->GetType()}) {
         if (result.categorySet.test(aType->category())) {
-          resultType = *aType;
+          if (const auto *sameChar{UnwrapExpr<Expr<SomeCharacter>>(*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 b36887e7f4dfd2..daf62bd197ace6 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



More information about the flang-commits mailing list