[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:21 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
+ }
+ }
+ }
+ } else {
+ return std::nullopt; // lower bound not known
+ }
+ }
+ return result;
+ }
----------------
jeanPerier wrote:
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...
https://github.com/llvm/llvm-project/pull/115970
More information about the flang-commits
mailing list