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

via flang-commits flang-commits at lists.llvm.org
Sun May 3 15:59:50 PDT 2026


Author: Valentin Clement (バレンタイン クレメン)
Date: 2026-05-03T15:59:45-07:00
New Revision: 9da250c97b8f2d1fcf6548b79c1908e1a2a87b04

URL: https://github.com/llvm/llvm-project/commit/9da250c97b8f2d1fcf6548b79c1908e1a2a87b04
DIFF: https://github.com/llvm/llvm-project/commit/9da250c97b8f2d1fcf6548b79c1908e1a2a87b04.diff

LOG: [flang][cuda][openacc] Fix OpenACC use_device host association symbol copies (#194705)

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.

Added: 
    flang/test/Lower/OpenACC/acc-host-data-cuda-host-assoc.f90

Modified: 
    flang/lib/Semantics/resolve-names.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 86eefc57f9749..822fc8b593fae 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1480,6 +1480,7 @@ class AccVisitor : public virtual DeclarationVisitor {
       llvm::ArrayRef<SourceName> componentPath, parser::Designator &designator);
 
 private:
+  Symbol *CopyUseDeviceSymbol(const Symbol &symbol);
   SemanticsContext &context_;
 };
 
@@ -1617,30 +1618,47 @@ 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())) {
+        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})};
+      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;
   }

diff  --git a/flang/test/Lower/OpenACC/acc-host-data-cuda-host-assoc.f90 b/flang/test/Lower/OpenACC/acc-host-data-cuda-host-assoc.f90
new file mode 100644
index 0000000000000..9844fd9913fd9
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-host-data-cuda-host-assoc.f90
@@ -0,0 +1,24 @@
+! RUN: bbc -fopenacc -fcuda -emit-hlfir %s -o - | FileCheck %s
+
+interface something 
+  subroutine proc_device(x) 
+    real(4), device :: x(100) 
+  end subroutine 
+  subroutine proc_host(x) 
+    real(4) :: x(100) 
+  end subroutine 
+end interface 
+
+real(4) :: a(100)  
+!$acc declare copy(a)  
+
+call test_simple() 
+contains  
+  subroutine test_simple  
+    !$acc host_data use_device(a)  
+    call something(a)  
+    !$acc end host_data  
+  end subroutine  
+end 
+
+! CHECK: fir.call @_QPproc_device


        


More information about the flang-commits mailing list