[flang-commits] [flang] [flang][cuda][acc] Fix use_device device attribute for USE-renamed variables (PR #205902)
via flang-commits
flang-commits at lists.llvm.org
Thu Jun 25 13:06:06 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: khaki3
<details>
<summary>Changes</summary>
Example:
```fortran
module m
complex(8), allocatable, pinned :: v(:,:)
interface callee
subroutine callee_x(x, n)
complex(8), device :: x(:,:)
integer :: n
end subroutine
end interface
end module
subroutine driver(n)
use m, only : callee, v_renamed => v
integer :: n
!$acc host_data use_device(v_renamed)
call callee(v_renamed, n)
!$acc end host_data
end subroutine
```
In this code, the `use_device` device copy was keyed under the ultimate name (`v`), so `v_renamed` resolved to the host (PINNED) symbol and generic resolution failed.
Fix: key the device copy under the local renamed name, and resolve its host binding in lowering via the enclosing scope's ultimate.
---
Full diff: https://github.com/llvm/llvm-project/pull/205902.diff
3 Files Affected:
- (modified) flang/lib/Lower/OpenACC.cpp (+8-1)
- (modified) flang/lib/Semantics/resolve-names.cpp (+22-4)
- (modified) flang/test/Lower/OpenACC/acc-host-data-cuda-device.f90 (+16)
``````````diff
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 5fbc678e6d0ae..9ce58e8b1662c 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -3169,7 +3169,14 @@ genACCHostDataOp(Fortran::lower::AbstractConverter &converter,
if (newSym) {
const Fortran::semantics::Symbol *origSym =
localSymbols.lookupSymbolByName(newSym->name().ToString());
- if (origSym)
+ if (!origSym) {
+ // For a USE-renamed variable the host symbol is mapped under its
+ // ultimate (module) name, so resolve it via the enclosing scope.
+ if (const Fortran::semantics::Symbol *hostSym =
+ newSym->owner().parent().FindSymbol(newSym->name()))
+ origSym = &hostSym->GetUltimate();
+ }
+ if (origSym && localSymbols.lookupSymbol(*origSym))
localSymbols.copySymbolBinding(*origSym, *newSym);
}
}
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 11e24a5e1cccb..c3286035c8641 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1635,22 +1635,40 @@ void AccVisitor::CopySymbolWithDevice(const parser::Name *name) {
Symbol *AccVisitor::CopyUseDeviceSymbol(const Symbol &symbol) {
const Symbol &ultimate{symbol.GetUltimate()};
- Symbol *copy{currScope().CopySymbol(ultimate)};
+ // Key the device copy under the name as referenced here, which differs from
+ // the ultimate symbol's name for a USE-renamed variable, so that references
+ // inside the construct resolve to this copy rather than the host symbol.
+ const SourceName localName{symbol.name()};
+ Symbol *copy{nullptr};
+ // CopySymbol would key the copy under the ultimate's name; only use it when
+ // that matches the local name, otherwise reuse the host-associated symbol.
+ if (localName == ultimate.name()) {
+ copy = currScope().CopySymbol(ultimate);
+ }
if (!copy) {
- copy = FindInScope(currScope(), ultimate.name());
+ copy = FindInScope(currScope(), localName);
}
if (copy && copy->has<HostAssocDetails>()) {
if (const auto *hostAssoc{copy->detailsIf<HostAssocDetails>()};
hostAssoc && copy->owner().kind() == Scope::Kind::OpenACCConstruct) {
Scope &hostScope{currScope().parent()};
- if (!FindInScope(hostScope, ultimate.name())) {
+ if (!FindInScope(hostScope, localName)) {
hostScope.CopySymbol(*copy);
}
}
if (const auto *object{ultimate.detailsIf<ObjectEntityDetails>()}) {
currScope().erase(copy->name());
auto pair{currScope().try_emplace(
- ultimate.name(), ultimate.attrs(), ObjectEntityDetails{*object})};
+ localName, ultimate.attrs(), ObjectEntityDetails{*object})};
+ copy = &*pair.first->second;
+ copy->flags() = ultimate.flags();
+ }
+ } else if (!copy) {
+ // USE-renamed object with no host-association symbol in this scope: key an
+ // object-entity copy under the local name (CopySymbol cannot rename).
+ if (const auto *object{ultimate.detailsIf<ObjectEntityDetails>()}) {
+ auto pair{currScope().try_emplace(
+ localName, ultimate.attrs(), ObjectEntityDetails{*object})};
copy = &*pair.first->second;
copy->flags() = ultimate.flags();
}
diff --git a/flang/test/Lower/OpenACC/acc-host-data-cuda-device.f90 b/flang/test/Lower/OpenACC/acc-host-data-cuda-device.f90
index 445de76bd8a94..fb06a4eda6d77 100644
--- a/flang/test/Lower/OpenACC/acc-host-data-cuda-device.f90
+++ b/flang/test/Lower/OpenACC/acc-host-data-cuda-device.f90
@@ -157,3 +157,19 @@ subroutine test_use_details()
! CHECK: fir.address_of(@_QP__host_sub)
! CHECK: fir.address_of(@_QP__device_sub)
! CHECK: fir.address_of(@_QP__host_sub)
+
+! The device attribute must propagate through use_device for a USE-renamed
+! variable, so generic resolution selects the device-specific procedure.
+subroutine test_use_rename()
+ use m, only: doit, renamed => pinned_real
+ call doit(renamed)
+ !$acc host_data use_device(renamed)
+ call doit(renamed)
+ !$acc end host_data
+ call doit(renamed)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_use_rename
+! CHECK: fir.address_of(@_QP__host_sub)
+! CHECK: fir.address_of(@_QP__device_sub)
+! CHECK: fir.address_of(@_QP__host_sub)
``````````
</details>
https://github.com/llvm/llvm-project/pull/205902
More information about the flang-commits
mailing list