[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:48:24 PDT 2026
https://github.com/khaki3 updated https://github.com/llvm/llvm-project/pull/205902
>From 0554afddc85603f254ee21fc40d01a58ba1dc6b2 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Thu, 25 Jun 2026 12:01:15 -0700
Subject: [PATCH 1/2] [flang][cuda][openacc] Propagate device attribute through
host_data use_device for USE-renamed variables
When a USE-renamed variable appears in an OpenACC host_data use_device
clause, semantics created the device copy keyed under the ultimate
symbol's name instead of the local (renamed) name. References at the call
site used the renamed name and therefore resolved to the host symbol,
causing generic resolution to fail (e.g. DEVICE dummy vs PINNED actual).
Key the use_device device copy under the as-referenced local name, and in
lowering resolve the host symbol via the enclosing scope's ultimate
(module) name so the binding is found for USE-renamed variables.
---
flang/lib/Lower/OpenACC.cpp | 9 ++++++-
flang/lib/Semantics/resolve-names.cpp | 26 ++++++++++++++++---
.../OpenACC/acc-host-data-cuda-device.f90 | 16 ++++++++++++
3 files changed, 46 insertions(+), 5 deletions(-)
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)
>From a8f86e17c85e128155b53f8ea5e62a0a8995eb52 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Thu, 25 Jun 2026 13:43:57 -0700
Subject: [PATCH 2/2] [flang][acc] Resolve use_device host binding via semantic
scope
Resolve the host symbol shadowed by a host_data use_device copy through
the semantic enclosing scope (then its ultimate) before falling back to a
name-based symbol-map lookup. This binds USE-renamed and same-name
shadowed references to the correct storage instead of an unrelated
same-name symbol in an outer scope.
---
flang/lib/Lower/OpenACC.cpp | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 9ce58e8b1662c..3614c9f4254bc 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -3167,15 +3167,17 @@ genACCHostDataOp(Fortran::lower::AbstractConverter &converter,
const Fortran::semantics::Symbol *newSym =
Fortran::parser::GetFirstName(accObject).symbol;
if (newSym) {
- const Fortran::semantics::Symbol *origSym =
- localSymbols.lookupSymbolByName(newSym->name().ToString());
- 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();
- }
+ // Resolve the host symbol this use_device copy shadows via the
+ // semantic enclosing scope, so USE-renamed (and same-name
+ // shadowed) references bind to the correct storage. Fall back to a
+ // name-based lookup if that symbol is not (yet) mapped.
+ const Fortran::semantics::Symbol *origSym = nullptr;
+ if (const Fortran::semantics::Symbol *hostSym =
+ newSym->owner().parent().FindSymbol(newSym->name()))
+ origSym = &hostSym->GetUltimate();
+ if (!origSym || !localSymbols.lookupSymbol(*origSym))
+ origSym =
+ localSymbols.lookupSymbolByName(newSym->name().ToString());
if (origSym && localSymbols.lookupSymbol(*origSym))
localSymbols.copySymbolBinding(*origSym, *newSym);
}
More information about the flang-commits
mailing list