[flang-commits] [flang] [flang][cuda] Apply implicit managed attribute to pointer variables under -gpu=mem:managed (PR #204634)

Zhen Wang via flang-commits flang-commits at lists.llvm.org
Thu Jun 18 09:52:00 PDT 2026


https://github.com/wangzpgi created https://github.com/llvm/llvm-project/pull/204634

When -gpu=mem:managed is active with CUDA Fortran enabled, only allocatable variables were implicitly given the managed CUDA data attribute. Pointer variables were left without it, causing their allocations to use host memory instead of cudaMallocManaged.

This patch extends the implicit managed attribute in FinishSpecificationPart to also cover pointer symbols. A LanguageFeature::CUDA guard is added so the attribute is only applied when CUDA Fortran semantics are active. The implicit pinned attribute (-gpu=mem:pinned) remains allocatable-only.

>From 4005fe8fb7899fc02584301d0a8597c30926da77 Mon Sep 17 00:00:00 2001
From: Zhen Wang <zhenw at nvidia.com>
Date: Wed, 17 Jun 2026 16:52:48 -0700
Subject: [PATCH] Apply implicit managed attribute to pointers under
 -gpu=mem:managed

---
 flang/lib/Semantics/resolve-names.cpp      | 12 +++++++-----
 flang/test/Lower/CUDA/cuda-gpu-managed.cuf | 13 ++++++-------
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 6d2d0bf24b194..cee230f38499a 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -10397,10 +10397,11 @@ void ResolveNamesVisitor::FinishSpecificationPart(
     }
 
     if (auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
-      if (IsAllocatable(symbol) && !object->cudaDataAttr()) {
-        // Implicitly treat allocatable arrays as managed when feature is
-        // enabled. This is done after all explicit CUDA attributes have been
-        // processed. Only applies when CUDA Fortran is enabled; otherwise
+      if ((IsAllocatable(symbol) || IsPointer(symbol)) &&
+          !object->cudaDataAttr()) {
+        // Implicitly treat allocatable/pointer arrays as managed when feature
+        // is enabled. This is done after all explicit CUDA attributes have
+        // been processed. Only applies when CUDA Fortran is enabled; otherwise
         // -gpu=mem:managed on a non-CUDA-Fortran translation unit (e.g. pure
         // OpenACC) would incorrectly route every allocatable through the CUDA
         // Fortran managed descriptor pipeline.
@@ -10411,7 +10412,8 @@ void ResolveNamesVisitor::FinishSpecificationPart(
           object->set_cudaDataAttr(common::CUDADataAttr::Managed);
         // Implicitly treat allocatable arrays as pinned when feature is
         // enabled.
-        else if (context().languageFeatures().IsEnabled(
+        else if (IsAllocatable(symbol) &&
+                 context().languageFeatures().IsEnabled(
                      common::LanguageFeature::CudaPinned))
           object->set_cudaDataAttr(common::CUDADataAttr::Pinned);
       }
diff --git a/flang/test/Lower/CUDA/cuda-gpu-managed.cuf b/flang/test/Lower/CUDA/cuda-gpu-managed.cuf
index a9ae310978e19..e9b2df1d71ed5 100644
--- a/flang/test/Lower/CUDA/cuda-gpu-managed.cuf
+++ b/flang/test/Lower/CUDA/cuda-gpu-managed.cuf
@@ -65,20 +65,19 @@ end subroutine
 ! CHECK: %[[BOX_DECL:.*]]:2 = hlfir.declare %[[BOX]] {data_attr = #cuf.cuda<managed>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_explicit_managedEm"}
 
 ! -----------------------------------------------------------------------------
-! Test 5: Pointer variables are NOT affected by -gpu=managed
+! Test 5: Pointer variables are also implicitly managed with -gpu=managed
 ! -----------------------------------------------------------------------------
-subroutine test_pointer_not_managed()
+subroutine test_pointer_managed()
   real, pointer :: ptr(:)
   allocate(ptr(100))
   ptr = 1.0
   deallocate(ptr)
 end subroutine
 
-! CHECK-LABEL: func.func @_QPtest_pointer_not_managed()
-! CHECK: %[[BOX:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>> {bindc_name = "ptr", uniq_name = "_QFtest_pointer_not_managedEptr"}
-! CHECK-NOT: data_attr = #cuf.cuda<managed>
-! CHECK: %[[BOX_DECL:.*]]:2 = hlfir.declare %[[BOX]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_pointer_not_managedEptr"}
-! CHECK: fir.call @_FortranAPointerAllocate
+! CHECK-LABEL: func.func @_QPtest_pointer_managed()
+! CHECK: %[[BOX:.*]] = cuf.alloc !fir.box<!fir.ptr<!fir.array<?xf32>>> {bindc_name = "ptr", data_attr = #cuf.cuda<managed>, uniq_name = "_QFtest_pointer_managedEptr"}
+! CHECK: %[[BOX_DECL:.*]]:2 = hlfir.declare %[[BOX]] {data_attr = #cuf.cuda<managed>, fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_pointer_managedEptr"}
+! CHECK: cuf.allocate %[[BOX_DECL]]#0 : {{.*}} {data_attr = #cuf.cuda<managed>, pointer}
 
 ! -----------------------------------------------------------------------------
 ! Test 6: Multiple allocatables - mix of implicit and explicit



More information about the flang-commits mailing list