[flang-commits] [flang] [flang][CUDA] Only apply implicit managed attribute when CUDA Fortran is enabled (PR #195353)

via flang-commits flang-commits at lists.llvm.org
Fri May 1 13:50:52 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: Zhen Wang (wangzpgi)

<details>
<summary>Changes</summary>

The implicit-managed tagging added in #<!-- -->175648 was intended for CUDA Fortran allocatables. However, the gate was just LanguageFeature::CudaManaged, so the tagging also fires on non-CUDA-Fortran translation units when -gpu=mem:managed is in effect.

This patch adds a LanguageFeature::CUDA check so the implicit tagging only fires for CUDA Fortran TUs (driver-set -fcuda or .cuf/.CUF source). Adds a regression test that bbc -gpu=managed without -fcuda on a .f90 source must not produce any cuf.* ops or #cuf.cuda<managed> attributes.

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


2 Files Affected:

- (modified) flang/lib/Semantics/resolve-names.cpp (+6-1) 
- (added) flang/test/Lower/CUDA/cuda-gpu-managed-without-fcuda.f90 (+59) 


``````````diff
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 86eefc57f9749..562126766e6eb 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -10157,8 +10157,13 @@ void ResolveNamesVisitor::FinishSpecificationPart(
     }
     // 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 -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.
     if (context().languageFeatures().IsEnabled(
-            common::LanguageFeature::CudaManaged))
+            common::LanguageFeature::CudaManaged) &&
+        context().languageFeatures().IsEnabled(common::LanguageFeature::CUDA))
       if (auto *object{symbol.detailsIf<ObjectEntityDetails>()})
         if (IsAllocatable(symbol) && !object->cudaDataAttr())
           object->set_cudaDataAttr(common::CUDADataAttr::Managed);
diff --git a/flang/test/Lower/CUDA/cuda-gpu-managed-without-fcuda.f90 b/flang/test/Lower/CUDA/cuda-gpu-managed-without-fcuda.f90
new file mode 100644
index 0000000000000..eb767bdfcad3d
--- /dev/null
+++ b/flang/test/Lower/CUDA/cuda-gpu-managed-without-fcuda.f90
@@ -0,0 +1,59 @@
+! RUN: bbc -emit-hlfir -gpu=managed %s -o - | FileCheck %s
+! RUN: bbc -emit-hlfir -gpu=mem:managed %s -o - | FileCheck %s
+
+! Test that -gpu=managed (a.k.a. -gpu=mem:managed) does NOT implicitly tag
+! plain Fortran allocatables as CUDA managed when CUDA Fortran is not
+! enabled. The implicit-managed tagging is a CUDA Fortran convenience and
+! should only fire when -fcuda is also in effect (or the source is .cuf).
+! Otherwise, a non-CUDA-Fortran translation unit (e.g. pure OpenACC code
+! compiled with -gpu=mem:managed by the driver) would route every
+! allocatable through the CUDA Fortran managed descriptor pipeline and
+! crash at runtime in cudaGetSymbolAddress.
+
+subroutine test_no_implicit_managed()
+  real, allocatable :: a(:)
+  allocate(a(100))
+  a = 1.0
+  deallocate(a)
+end subroutine
+
+subroutine test_no_implicit_managed_multidim()
+  real, allocatable :: arr(:,:,:)
+  allocate(arr(10,20,30))
+  arr = 0.0
+  deallocate(arr)
+end subroutine
+
+module mod_no_managed
+  real, allocatable :: g(:)
+end module
+
+subroutine test_no_implicit_managed_module()
+  use mod_no_managed
+  allocate(g(50))
+  deallocate(g)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_no_implicit_managed()
+! CHECK-NOT:     cuf.alloc
+! CHECK-NOT:     data_attr = #cuf.cuda<managed>
+! CHECK-NOT:     allocator_idx = 3
+! CHECK-NOT:     cuf.allocate
+! CHECK-NOT:     cuf.deallocate
+! CHECK-NOT:     cuf.free
+
+! CHECK-LABEL: func.func @_QPtest_no_implicit_managed_multidim()
+! CHECK-NOT:     cuf.alloc
+! CHECK-NOT:     data_attr = #cuf.cuda<managed>
+! CHECK-NOT:     allocator_idx = 3
+
+! CHECK-LABEL: func.func @_QPtest_no_implicit_managed_module()
+! CHECK-NOT:     cuf.allocate
+! CHECK-NOT:     cuf.deallocate
+! CHECK-NOT:     data_attr = #cuf.cuda<managed>
+! CHECK-NOT:     allocator_idx = 3
+
+! Module global must not be tagged as managed either.
+! CHECK:     fir.global @_QMmod_no_managedEg
+! CHECK-NOT: data_attr = #cuf.cuda<managed>
+! CHECK-NOT: allocator_idx = 3

``````````

</details>


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


More information about the flang-commits mailing list