[flang-commits] [flang] [flang] Better IS_CONTIGUOUS folding for substrings (PR #115970)
via flang-commits
flang-commits at lists.llvm.org
Wed Nov 13 02:50:22 PST 2024
================
@@ -908,7 +908,39 @@ class IsContiguousHelper
Result operator()(const ComplexPart &x) const {
return x.complex().Rank() == 0;
}
- Result operator()(const Substring &) const { return std::nullopt; }
+ Result operator()(const Substring &x) const {
+ auto base{x.GetBaseObject()};
+ if (x.Rank() == 0) {
+ return true; // scalar substring always contiguous
+ }
+ Result result{(*this)(base)};
+ if (!result || *result) {
+ if (auto lower{ToInt64(Fold(context_, x.lower()))}) {
+ auto upperExpr{x.upper()};
+ auto lenExpr{base.LEN()};
+ if (!upperExpr) {
+ 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
+ }
+ }
+ }
----------------
jeanPerier wrote:
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.
https://github.com/llvm/llvm-project/pull/115970
More information about the flang-commits
mailing list