[flang-commits] [flang] [flang][cuda][openacc] Fix OpenACC use_device host association symbol copies (PR #194705)

via flang-commits flang-commits at lists.llvm.org
Tue Apr 28 11:50:36 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Valentin Clement (バレンタイン クレメン) (clementval)

<details>
<summary>Changes</summary>

When a use_device object comes from host association, the OpenACC construct scope may already contain a HostAssocDetails symbol. Reusing that symbol prevents semantics from applying the CUDA DEVICE attribute, because the copied symbol is not an object entity. The fix materializes the expected host-associated symbol in the containing scope, then replaces the OpenACC-scope symbol with an ObjectEntityDetails copy that can carry the device attribute.

This allows generic resolution and lowering to see the device version inside the host_data construct while preserving the host-associated binding needed by lowering.

---
Full diff: https://github.com/llvm/llvm-project/pull/194705.diff


1 Files Affected:

- (modified) flang/lib/Semantics/resolve-names.cpp (+37-11) 


``````````diff
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index cda75fe566087..7cc9d2fab6051 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1478,6 +1478,7 @@ class AccVisitor : public virtual DeclarationVisitor {
       llvm::ArrayRef<SourceName> componentPath, parser::Designator &designator);
 
 private:
+  Symbol *CopyUseDeviceSymbol(const Symbol &symbol);
   SemanticsContext &context_;
 };
 
@@ -1615,30 +1616,55 @@ void AccVisitor::CopySymbolWithDevice(const parser::Name *name) {
   // New symbols are created for those appearing in the use_device clause.
   // These new symbols get the CUDA device attribute.
   if (name && name->symbol) {
-    Symbol *copy{currScope().CopySymbol(name->symbol->GetUltimate())};
+    Symbol *copy{CopyUseDeviceSymbol(*name->symbol)};
     if (copy) {
-      if (auto *object{copy->GetUltimate().detailsIf<ObjectEntityDetails>()}) {
+      if (auto *object{copy->detailsIf<ObjectEntityDetails>()}) {
         object->set_cudaDataAttr(common::CUDADataAttr::Device);
       }
-    } else {
-      copy = FindInScope(currScope(), name->symbol->GetUltimate().name());
-    }
-    if (copy) {
       name->symbol = copy;
     }
   }
 }
 
+Symbol *AccVisitor::CopyUseDeviceSymbol(const Symbol &symbol) {
+  const Symbol &ultimate{symbol.GetUltimate()};
+  Symbol *copy{currScope().CopySymbol(ultimate)};
+  if (!copy) {
+    copy = FindInScope(currScope(), ultimate.name());
+  }
+  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())) {
+        auto pair{hostScope.try_emplace(
+            ultimate.name(), HostAssocDetails{hostAssoc->symbol()})};
+        Symbol &hostCopy{*pair.first->second};
+        hostCopy.attrs() = hostAssoc->symbol().attrs();
+        hostCopy.implicitAttrs() =
+            hostCopy.attrs() & Attrs{Attr::ASYNCHRONOUS, Attr::VOLATILE};
+        hostCopy.implicitAttrs() |=
+            hostAssoc->symbol().implicitAttrs() & Attrs{Attr::SAVE};
+        hostCopy.flags() = hostAssoc->symbol().flags();
+      }
+    }
+    if (const auto *object{ultimate.detailsIf<ObjectEntityDetails>()}) {
+      currScope().erase(copy->name());
+      auto pair{currScope().try_emplace(
+          ultimate.name(), ultimate.attrs(), ObjectEntityDetails{*object})};
+      copy = &*pair.first->second;
+      copy->flags() = ultimate.flags();
+    }
+  }
+  return copy;
+}
+
 void AccVisitor::CopySymbolWithDeviceStructurePath(const parser::Name *baseName,
     llvm::ArrayRef<SourceName> componentPath, parser::Designator &designator) {
   if (!baseName || !baseName->symbol || componentPath.empty()) {
     return;
   }
-  const Symbol &orig{*baseName->symbol};
-  Symbol *copy{currScope().CopySymbol(orig)};
-  if (!copy) {
-    copy = FindInScope(currScope(), baseName->symbol->name());
-  }
+  Symbol *copy{CopyUseDeviceSymbol(*baseName->symbol)};
   if (!copy) {
     return;
   }

``````````

</details>


https://github.com/llvm/llvm-project/pull/194705


More information about the flang-commits mailing list