[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