[flang-commits] [flang] [flang] Better IS_CONTIGUOUS folding for substrings (PR #115970)
via flang-commits
flang-commits at lists.llvm.org
Thu Nov 14 01:36:05 PST 2024
================
@@ -908,7 +908,54 @@ 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 {
+ if (x.Rank() == 0) {
+ return true; // scalar substring always contiguous
+ }
+ // Substrings with rank must have DataRefs as their parents
+ const DataRef &parentDataRef{DEREF(x.GetParentIf<DataRef>())};
+ std::optional<std::int64_t> len;
+ if (auto lenExpr{parentDataRef.LEN()}) {
+ len = ToInt64(Fold(context_, std::move(*lenExpr)));
+ if (len) {
+ if (*len <= 0) {
+ return true; // empty substrings
+ } else if (*len == 1) {
+ // Substrings can't be incomplete; is base array contiguous?
+ return (*this)(parentDataRef);
+ }
+ }
+ }
+ auto upperExpr{x.upper()};
+ std::optional<std::int64_t> upper;
+ bool upperIsLen{false};
+ if (upperExpr) {
+ upper = ToInt64(Fold(context_, std::move(*upperExpr)));
+ if (upper) {
+ if (*upper < 1) {
+ return true; // substring(n:0) empty
+ }
+ upperIsLen = len && *upper >= *len;
+ }
+ } else {
+ upperIsLen = true; // substring(n:)
----------------
jeanPerier wrote:
It seems that some previous folding step may already have expended the absent upper into the length, blurring the information here for cases where the length is not a compile time constant:
```
subroutine test(charr)
character(*) :: charr(5)
print *, is_contiguous(charr(:)(1:))
end subroutine
```
Folds to `is_contiguous(charr(::1_8)(1_8:int(charr%len,kind=8)))` while it could be folded to true.
However, folding this may not be required by the standard, so this may be fine.
I do not find the standard very clear regarding the appearance of IS_CONTIGUOUS in constant expressions. As I understand it, it falls into the 10.1.12 (6) case since IS_CONTIGUOUS is an inquiry function. I am not sure how to read _"a variable whose properties inquired about are not assumed, deferred, or defined by an expression that is not a constant expression"_ when the "property" is the contiguity.
https://github.com/llvm/llvm-project/pull/115970
More information about the flang-commits
mailing list