[flang-commits] [flang] f6f08fa - [flang][cuda] Use managed allocation for saved locals (#210133)
via flang-commits
flang-commits at lists.llvm.org
Thu Jul 16 13:53:32 PDT 2026
Author: Matsu
Date: 2026-07-16T20:53:27Z
New Revision: f6f08fa7e5d56aa07f9ebc51500f2c9fd6df8e1b
URL: https://github.com/llvm/llvm-project/commit/f6f08fa7e5d56aa07f9ebc51500f2c9fd6df8e1b
DIFF: https://github.com/llvm/llvm-project/commit/f6f08fa7e5d56aa07f9ebc51500f2c9fd6df8e1b.diff
LOG: [flang][cuda] Use managed allocation for saved locals (#210133)
Example:
```fortran
subroutine work
real, allocatable, save :: q(:)
allocate(q(10))
end
```
`SAVE` gives the local allocatable descriptor static storage. Implicitly
attributing it as Unified causes allocation to look it up as a
registered CUDA global, but no device symbol is registered for the
descriptor.
Fix: use Managed attribution for saved subprogram-local allocatables and
pointers, avoiding the invalid CUDA symbol lookup.
Added:
Modified:
flang/lib/Semantics/resolve-names.cpp
flang/test/Lower/CUDA/cuda-implicit-managed-alloc.cuf
Removed:
################################################################################
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index cdf81e7871f36..e83fc179ecf40 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -10619,7 +10619,9 @@ void DeclarationVisitor::SetImplicitCUDADataAttr(Symbol &symbol) {
// COMMON objects may not carry managed/unified attributes.
if (cudaEnabled && (cudaManaged || cudaUnified) && !object->commonBlock()) {
const Scope &owner{symbol.owner()};
- const bool unifiedAllowed{!IsCUDADeviceContext(&owner) &&
+ const bool isSavedLocal{
+ owner.kind() == Scope::Kind::Subprogram && IsSaved(symbol)};
+ const bool unifiedAllowed{!isSavedLocal && !IsCUDADeviceContext(&owner) &&
(owner.IsDerivedType() || owner.kind() == Scope::Kind::MainProgram ||
owner.kind() == Scope::Kind::Subprogram)};
object->set_cudaDataAttr(cudaUnified && unifiedAllowed
diff --git a/flang/test/Lower/CUDA/cuda-implicit-managed-alloc.cuf b/flang/test/Lower/CUDA/cuda-implicit-managed-alloc.cuf
index 378eb8698d3c6..e3185ae81a843 100644
--- a/flang/test/Lower/CUDA/cuda-implicit-managed-alloc.cuf
+++ b/flang/test/Lower/CUDA/cuda-implicit-managed-alloc.cuf
@@ -20,6 +20,8 @@ contains
subroutine mod_sub()
real, allocatable :: loc_arr(:)
real, pointer :: loc_ptr(:)
+ real, allocatable, save :: saved_arr(:)
+ real, pointer, save :: saved_ptr(:)
end subroutine
subroutine common_sub()
real, pointer :: com_ptr(:)
@@ -38,6 +40,13 @@ end program
! MAN: hlfir.declare {{.*}} {data_attr = #cuf.cuda<managed>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMmFmod_subEloc_arr"}
! MAN: hlfir.declare {{.*}} {data_attr = #cuf.cuda<managed>, fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMmFmod_subEloc_ptr"}
+! Saved subprogram locals use Managed because their static descriptors cannot
+! be registered as Unified device symbols.
+! UNI: hlfir.declare {{.*}} {data_attr = #cuf.cuda<managed>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMmFmod_subEsaved_arr"}
+! UNI: hlfir.declare {{.*}} {data_attr = #cuf.cuda<managed>, fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMmFmod_subEsaved_ptr"}
+! MAN: hlfir.declare {{.*}} {data_attr = #cuf.cuda<managed>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMmFmod_subEsaved_arr"}
+! MAN: hlfir.declare {{.*}} {data_attr = #cuf.cuda<managed>, fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMmFmod_subEsaved_ptr"}
+
! COMMON-block pointer: unattributed, CUDA attributes may not appear in COMMON.
! UNI: hlfir.declare {{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMmFcommon_subEcom_ptr"}
! MAN: hlfir.declare {{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMmFcommon_subEcom_ptr"}
@@ -54,9 +63,18 @@ end program
! MAN: fir.global @_QMmEmod_arr {data_attr = #cuf.cuda<managed>}
! MAN: fir.global @_QMmEmod_ptr {data_attr = #cuf.cuda<managed>}
+! UNI: fir.global internal @_QMmFmod_subEsaved_arr {data_attr = #cuf.cuda<managed>}
+! UNI: fir.global internal @_QMmFmod_subEsaved_ptr {data_attr = #cuf.cuda<managed>}
+! MAN: fir.global internal @_QMmFmod_subEsaved_arr {data_attr = #cuf.cuda<managed>}
+! MAN: fir.global internal @_QMmFmod_subEsaved_ptr {data_attr = #cuf.cuda<managed>}
+
! Derived-type components: Unified under -gpu=unified, Managed under
! -gpu=managed. Checked via the symbol table.
! UNI-SYM: comp_arr, ALLOCATABLE {{.*}} cudaDataAttr: Unified
! UNI-SYM: comp_ptr, POINTER {{.*}} cudaDataAttr: Unified
! MAN-SYM: comp_arr, ALLOCATABLE {{.*}} cudaDataAttr: Managed
! MAN-SYM: comp_ptr, POINTER {{.*}} cudaDataAttr: Managed
+! UNI-SYM: saved_arr, ALLOCATABLE, SAVE {{.*}} cudaDataAttr: Managed
+! UNI-SYM: saved_ptr, POINTER, SAVE {{.*}} cudaDataAttr: Managed
+! MAN-SYM: saved_arr, ALLOCATABLE, SAVE {{.*}} cudaDataAttr: Managed
+! MAN-SYM: saved_ptr, POINTER, SAVE {{.*}} cudaDataAttr: Managed
More information about the flang-commits
mailing list