[flang-commits] [flang] [flang] Disable copy-out to INTENT(IN) args (PR #192382)
via flang-commits
flang-commits at lists.llvm.org
Thu Apr 16 03:40:47 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Eugene Epshteyn (eugeneepshteyn)
<details>
<summary>Changes</summary>
Don't copy out to actual args that themselves happen to be INTENT(IN) dummy args.
```
subroutine test(a)
real, intent(in) :: a(:)
call require_contiguous_arg(a(1:n:2)) ! copy-in only, no copy-out
end
```
---
Full diff: https://github.com/llvm/llvm-project/pull/192382.diff
2 Files Affected:
- (modified) flang/lib/Evaluate/check-expression.cpp (+11)
- (modified) flang/test/Lower/call-copy-in-out.f90 (+15)
``````````diff
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index be7db0f20821d..25a6dfa799e9e 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -1649,6 +1649,17 @@ std::optional<bool> ActualArgNeedsCopy(const ActualArgument *actual,
// Expressions are copy-in, but not copy-out.
return forCopyIn;
}
+ if (forCopyOut) {
+ // If the actual argument's base object has INTENT(IN) in the caller's
+ // context, copy-out would violate the read-only semantics of INTENT(IN).
+ if (const Expr<SomeType> *expr{actual->UnwrapExpr()}) {
+ if (const Symbol *symbol{GetFirstSymbol(*expr)}) {
+ if (semantics::IsIntentIn(*symbol)) {
+ return false;
+ }
+ }
+ }
+ }
auto maybeContigActual{IsContiguous(*actual, fc)};
if (dummyObj) { // Explict interface
CopyInOutExplicitInterface check{fc, *actual, *dummyObj};
diff --git a/flang/test/Lower/call-copy-in-out.f90 b/flang/test/Lower/call-copy-in-out.f90
index fa2182ac11bac..e87ae5e294a84 100644
--- a/flang/test/Lower/call-copy-in-out.f90
+++ b/flang/test/Lower/call-copy-in-out.f90
@@ -84,6 +84,21 @@ subroutine bar_intent_in(x)
call bar_intent_in(x)
end subroutine
+! Test copy-out is skipped when the actual argument has INTENT(IN).
+! CHECK-LABEL: func @_QPtest_actual_arg_intent_in(
+subroutine test_actual_arg_intent_in(x)
+ real, intent(in) :: x(:)
+! CHECK: hlfir.copy_in
+! CHECK-SAME: to
+! CHECK: fir.call @_QPbar
+! Note: no-op hlfir.copy_out has comma separated list of args.
+! The actual working hlfir.copy_out has "to" in it.
+! CHECK: hlfir.copy_out
+! CHECK-SAME: ,
+! CHECK: return
+ call bar(x)
+end subroutine
+
! Test copy-in/copy-out is done for intent(inout)
! CHECK-LABEL: func @_QPtest_intent_inout(
subroutine test_intent_inout(x)
``````````
</details>
https://github.com/llvm/llvm-project/pull/192382
More information about the flang-commits
mailing list