-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[flang] Fixed regression in copy-in/copy-out #161259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
eugeneepshteyn
merged 27 commits into
llvm:main
from
eugeneepshteyn:fix-poly-copy-in-out
Nov 12, 2025
Merged
Changes from 20 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
632ed7b
[flang] Fixed regression in copy-in/copy-out
eugeneepshteyn 97cbeed
Merge branch 'llvm:main' into fix-poly-copy-in-out
eugeneepshteyn 9189ede
Restore HavePolymorphicDifferences(), but with different checks
eugeneepshteyn f572da2
Tweaked the change to ignore assumed type in polymorphic check
eugeneepshteyn 91f9e67
clang-format
eugeneepshteyn f52136b
Merge branch 'main' into fix-poly-copy-in-out
eugeneepshteyn d60edf8
Replaced s6() with an interface, since only care about the call
eugeneepshteyn 1e69803
New test to check for copy-in/out for potential slicing test
eugeneepshteyn 94f69ed
Tweaked test comment
eugeneepshteyn 42382e0
Merge branch 'llvm:main' into fix-poly-copy-in-out
eugeneepshteyn 5eff815
Begin the switch to ternary logic using std::optional<bool>. Renamed …
eugeneepshteyn 68bab54
New name: ActualArgNeedsCopy(). Reworked the implicit interface case
eugeneepshteyn 413718c
Continue refactoring. Extracted DummyNeedsContiguity() functionality …
eugeneepshteyn 329445c
Continue refactoring
eugeneepshteyn ad080f1
clang-format
eugeneepshteyn 8792ba4
Simplified check.HavePolymorphicDifferences(). Now seems to work
eugeneepshteyn 8fd9427
clang-format
eugeneepshteyn 4371a28
Merge branch 'llvm:main' into 1-copy-in-out-new-interface
eugeneepshteyn 23393fe
Merge branch 'llvm:main' into fix-poly-copy-in-out
eugeneepshteyn 1c202be
Merge branch '1-copy-in-out-new-interface' into fix-poly-copy-in-out
eugeneepshteyn 3423413
Merge branch 'llvm:main' into fix-poly-copy-in-out
eugeneepshteyn 80b2ccb
One code review comment (tests are still passing)
eugeneepshteyn 2cef85a
Attempting to address Jean's comments. Currently 58 regressions in LI…
eugeneepshteyn d93b7e2
Fixed the regressions
eugeneepshteyn 2abf0cb
Lower/force-temp.f90: added a test with IGNORE_TKR(C) and CONTIGUOUS
eugeneepshteyn 57d67d7
Code review feedback
eugeneepshteyn e85c4e9
Merge branch 'main' into fix-poly-copy-in-out
eugeneepshteyn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1475,13 +1475,9 @@ class CopyInOutExplicitInterface { | |
| const characteristics::DummyDataObject &dummyObj) | ||
| : fc_{fc}, actual_{actual}, dummyObj_{dummyObj} {} | ||
|
|
||
| // Returns true, if actual and dummy have different contiguity requirements | ||
| bool HaveContiguityDifferences() const { | ||
| // Check actual contiguity, unless dummy doesn't care | ||
| // Returns true if dummy arg needs to be contiguous | ||
| bool DummyNeedsContiguity() const { | ||
| bool dummyTreatAsArray{dummyObj_.ignoreTKR.test(common::IgnoreTKR::Rank)}; | ||
| bool actualTreatAsContiguous{ | ||
| dummyObj_.ignoreTKR.test(common::IgnoreTKR::Contiguous) || | ||
| IsSimplyContiguous(actual_, fc_)}; | ||
| bool dummyIsExplicitShape{dummyObj_.type.IsExplicitShape()}; | ||
| bool dummyIsAssumedSize{dummyObj_.type.attrs().test( | ||
| characteristics::TypeAndShape::Attr::AssumedSize)}; | ||
|
|
@@ -1498,32 +1494,17 @@ class CopyInOutExplicitInterface { | |
| (dummyTreatAsArray && !dummyIsPolymorphic) || dummyIsVoidStar || | ||
| dummyObj_.attrs.test( | ||
| characteristics::DummyDataObject::Attr::Contiguous)}; | ||
| return !actualTreatAsContiguous && dummyNeedsContiguity; | ||
| return dummyNeedsContiguity; | ||
| } | ||
|
|
||
| // Returns true, if actual and dummy have polymorphic differences | ||
| bool HavePolymorphicDifferences() const { | ||
| bool dummyIsAssumedRank{dummyObj_.type.attrs().test( | ||
| characteristics::TypeAndShape::Attr::AssumedRank)}; | ||
| bool actualIsAssumedRank{semantics::IsAssumedRank(actual_)}; | ||
| bool dummyIsAssumedShape{dummyObj_.type.attrs().test( | ||
| characteristics::TypeAndShape::Attr::AssumedShape)}; | ||
| bool actualIsAssumedShape{semantics::IsAssumedShape(actual_)}; | ||
| if ((actualIsAssumedRank && dummyIsAssumedRank) || | ||
| (actualIsAssumedShape && dummyIsAssumedShape)) { | ||
| // Assumed-rank and assumed-shape arrays are represented by descriptors, | ||
| // so don't need to do polymorphic check. | ||
| } else if (!dummyObj_.ignoreTKR.test(common::IgnoreTKR::Type)) { | ||
| // flang supports limited cases of passing polymorphic to non-polimorphic. | ||
| // These cases require temporary of non-polymorphic type. (For example, | ||
| // the actual argument could be polymorphic array of child type, | ||
| // while the dummy argument could be non-polymorphic array of parent | ||
| // type.) | ||
| if (dummyObj_.ignoreTKR.test(common::IgnoreTKR::Type)) { | ||
| return false; | ||
| } | ||
| if (auto actualType{ | ||
| characteristics::TypeAndShape::Characterize(actual_, fc_)}) { | ||
| bool actualIsPolymorphic{actualType->type().IsPolymorphic()}; | ||
| bool dummyIsPolymorphic{dummyObj_.type.type().IsPolymorphic()}; | ||
| auto actualType{ | ||
| characteristics::TypeAndShape::Characterize(actual_, fc_)}; | ||
| bool actualIsPolymorphic{ | ||
| actualType && actualType->type().IsPolymorphic()}; | ||
| if (actualIsPolymorphic && !dummyIsPolymorphic) { | ||
| return true; | ||
| } | ||
|
|
@@ -1572,28 +1553,35 @@ class CopyInOutExplicitInterface { | |
| // procedures with explicit interface, it's expected that "dummy" is not null. | ||
| // For procedures with implicit interface dummy may be null. | ||
| // | ||
| // Returns std::optional<bool> indicating whether the copy is known to be | ||
| // needed (true) or not needed (false); returns std::nullopt if the necessity | ||
| // of the copy is undetermined. | ||
| // | ||
| // Note that these copy-in and copy-out checks are done from the caller's | ||
| // perspective, meaning that for copy-in the caller need to do the copy | ||
| // before calling the callee. Similarly, for copy-out the caller is expected | ||
| // to do the copy after the callee returns. | ||
| bool MayNeedCopy(const ActualArgument *actual, | ||
| std::optional<bool> ActualArgNeedsCopy(const ActualArgument *actual, | ||
| const characteristics::DummyArgument *dummy, FoldingContext &fc, | ||
| bool forCopyOut) { | ||
| constexpr auto unknown = std::nullopt; | ||
| if (!actual) { | ||
| return false; | ||
| return unknown; | ||
| } | ||
| if (actual->isAlternateReturn()) { | ||
| return false; | ||
| return unknown; | ||
| } | ||
| const auto *dummyObj{dummy | ||
| ? std::get_if<characteristics::DummyDataObject>(&dummy->u) | ||
| : nullptr}; | ||
| const bool forCopyIn = !forCopyOut; | ||
|
||
| if (!evaluate::IsVariable(*actual)) { | ||
| // Actual argument expressions that aren’t variables are copy-in, but | ||
| // not copy-out. | ||
| // Expressions are copy-in, but not copy-out. | ||
| return forCopyIn; | ||
| } | ||
| auto maybeContigActual{IsContiguous(*actual, fc)}; | ||
| bool isContiguousActual{ | ||
| maybeContigActual.has_value() && maybeContigActual.value()}; | ||
jeanPerier marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (dummyObj) { // Explict interface | ||
| CopyInOutExplicitInterface check{fc, *actual, *dummyObj}; | ||
| if (forCopyOut && check.HasIntentIn()) { | ||
|
|
@@ -1616,28 +1604,19 @@ bool MayNeedCopy(const ActualArgument *actual, | |
| if (!check.HaveArrayOrAssumedRankArgs()) { | ||
| return false; | ||
| } | ||
| if (check.HaveContiguityDifferences()) { | ||
| return true; | ||
| } | ||
| if (check.HavePolymorphicDifferences()) { | ||
| bool actualTreatAsContiguous{isContiguousActual || | ||
| dummyObj->ignoreTKR.test(common::IgnoreTKR::Contiguous)}; | ||
jeanPerier marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if ((!actualTreatAsContiguous || check.HavePolymorphicDifferences()) && | ||
| check.DummyNeedsContiguity()) { | ||
| return true; | ||
| } | ||
| } else { // Implicit interface | ||
| if (ExtractCoarrayRef(*actual)) { | ||
| // Coindexed actual args may need copy-in and copy-out with implicit | ||
| // interface | ||
| return true; | ||
| } | ||
| if (!IsSimplyContiguous(*actual, fc)) { | ||
| // Copy-in: actual arguments that are variables are copy-in when | ||
| // non-contiguous. | ||
| // Copy-out: vector subscripts could refer to duplicate elements, can't | ||
| // copy out. | ||
| return !(forCopyOut && HasVectorSubscript(*actual)); | ||
| if (isContiguousActual) { | ||
| // Known contiguous, don't copy in/out | ||
| return false; | ||
| } | ||
| } | ||
| // For everything else, no copy-in or copy-out | ||
| return false; | ||
| return unknown; | ||
| } | ||
|
|
||
| } // namespace Fortran::evaluate | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe this would increase readability if it were visible to clients, but it doesn't improve anything in the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It helped me to think about the implementation. I can remove it now.