[flang-commits] [flang] [flang] Better IS_CONTIGUOUS folding for substrings (PR #115970)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Wed Nov 13 11:21:07 PST 2024


klausler wrote:

Thanks for looking into that code; I’ve reworked it.

From: jeanPerier ***@***.***>
Date: Wednesday, November 13, 2024 at 02:50
To: llvm/llvm-project ***@***.***>
Cc: Peter Klausler ***@***.***>, Author ***@***.***>
Subject: Re: [llvm/llvm-project] [flang] Better IS_CONTIGUOUS folding for substrings (PR #115970)

@jeanPerier commented on this pull request.

________________________________

In flang/lib/Evaluate/check-expression.cpp<https://github.com/llvm/llvm-project/pull/115970#discussion_r1839947264>:

> +          upperExpr = lenExpr;

+        }

+        if (!upperExpr) {

+          return std::nullopt; // could be empty substrings

+        } else if (auto upper{ToInt64(Fold(context_, std::move(*upperExpr)))}) {

+          if (*upper < *lower) {

+            return true; // empty substrings: vacuously contiguous

+          } else if (*lower > 1) {

+            return false; // lower > 1

+          } else if (lenExpr) {

+            if (auto lenVal{ToInt64(Fold(context_, std::move(*lenExpr)))};

+                lenVal && *lenVal != *upper) {

+              return false; // upper < length

+            }

+          }

+        }

This seems a quite broad fallback, I think the code is incorrectly falling back into it for things like:

subroutine test2(charr, n)

  character(10) :: charr(5)

  integer :: n

  print *, is_contiguous(charr(:)(1:n))

end subroutine

This folds would now fold to true, while this is cannot be folded (and will be false if n is not 10 or smaller than 1 at runtime).

It seems the code can only fall back to "return result" when it can be determined that the lower bound is one, and the upper bound is absent or equal to the length.

________________________________

In flang/lib/Evaluate/check-expression.cpp<https://github.com/llvm/llvm-project/pull/115970#discussion_r1839963549>:

> +            return true; // empty substrings: vacuously contiguous

+          } else if (*lower > 1) {

+            return false; // lower > 1

+          } else if (lenExpr) {

+            if (auto lenVal{ToInt64(Fold(context_, std::move(*lenExpr)))};

+                lenVal && *lenVal != *upper) {

+              return false; // upper < length

+            }

+          }

+        }

+      } else {

+        return std::nullopt; // lower bound not known

+      }

+    }

+    return result;

+  }

For some reason I do not explain to myself it seems your patch is incorrectly causing the folowing is_contiguous to fold to true while the substring is not empty and the base is not contiguous:

subroutine test(charr)

  character(10) :: charr(5)

  print *, is_contiguous(charr(1:5:2)(1:10))

end subroutine

My comment about incorrectly falling back into the "return is_contigous(base)" cannot explain that since the base is not contiguous...

—
Reply to this email directly, view it on GitHub<https://github.com/llvm/llvm-project/pull/115970#pullrequestreview-2432546834>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AIRI5XISOSE6PNHMHPOM2LT2AMVH7AVCNFSM6AAAAABRVIVFA6VHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDIMZSGU2DMOBTGQ>.
You are receiving this because you authored the thread.Message ID: ***@***.***>


https://github.com/llvm/llvm-project/pull/115970


More information about the flang-commits mailing list