[flang-commits] [flang] bd62f93 - [flang][cuda] Allow CUDA variable for assumed-type dummy (#196135)
via flang-commits
flang-commits at lists.llvm.org
Wed May 6 11:55:49 PDT 2026
Author: Valentin Clement (バレンタイン クレメン)
Date: 2026-05-06T11:55:45-07:00
New Revision: bd62f9327279e7e2bcbc9c30476e1b868e4f0081
URL: https://github.com/llvm/llvm-project/commit/bd62f9327279e7e2bcbc9c30476e1b868e4f0081
DIFF: https://github.com/llvm/llvm-project/commit/bd62f9327279e7e2bcbc9c30476e1b868e4f0081.diff
LOG: [flang][cuda] Allow CUDA variable for assumed-type dummy (#196135)
Added:
Modified:
flang/include/flang/Semantics/tools.h
flang/lib/Semantics/check-call.cpp
flang/lib/Semantics/expression.cpp
flang/lib/Semantics/tools.cpp
flang/test/Semantics/cuf10.cuf
Removed:
################################################################################
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index 53248a2b358d6..c6e46359ffcb3 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -26,6 +26,10 @@
#include "llvm/ADT/ArrayRef.h"
#include <functional>
+namespace Fortran::evaluate::characteristics {
+struct DummyDataObject;
+}
+
namespace Fortran::semantics {
class DeclTypeSpec;
@@ -230,6 +234,8 @@ inline bool HasCUDAAttr(const Symbol &sym) {
}
bool HasCUDAComponent(const Symbol &sym);
+bool IsCUDAAddressSpaceAgnostic(
+ const evaluate::characteristics::DummyDataObject &);
inline bool IsCUDADevice(const Symbol &sym) {
if (const auto *details{sym.GetUltimate().detailsIf<ObjectEntityDetails>()}) {
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 2dd47508a0b3f..da8880482d4dc 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -1166,7 +1166,11 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
bool isHostDeviceProc{procedure.cudaSubprogramAttrs &&
*procedure.cudaSubprogramAttrs ==
common::CUDASubprogramAttrs::HostDevice};
- if (!common::AreCompatibleCUDADataAttrs(dummyDataAttr, actualDataAttr,
+ // TYPE(*) assumed-size/rank dummies are opaque buffers (e.g. MPI) and do
+ // not impose a CUDA address space on their actual argument.
+ bool skipCudaDataAttrCheck{IsCUDAAddressSpaceAgnostic(dummy)};
+ if (!skipCudaDataAttrCheck &&
+ !common::AreCompatibleCUDADataAttrs(dummyDataAttr, actualDataAttr,
dummy.ignoreTKR, /*allowUnifiedMatchingRule=*/true,
isHostDeviceProc, &context.languageFeatures())) {
auto toStr{[](std::optional<common::CUDADataAttr> x) {
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index ae6abff043741..8e09e6440a0b7 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -2875,14 +2875,24 @@ static int GetMatchingDistance(const common::LanguageFeatureControl &features,
}
}
+ bool dummyIsCudaAddressSpaceAgnostic{false};
common::visit(common::visitors{
[&](const characteristics::DummyDataObject &object) {
dummyDataAttr = object.cudaDataAttr;
+ dummyIsCudaAddressSpaceAgnostic =
+ semantics::IsCUDAAddressSpaceAgnostic(object);
},
[&](const auto &) {},
},
dummy.u);
+ if (actualDataAttr && dummyIsCudaAddressSpaceAgnostic) {
+ // TYPE(*) assumed-size/rank dummies model opaque buffers, so they can
+ // accept host or device storage. Keep a non-zero distance so an explicit
+ // DEVICE overload remains a better CUDA match.
+ return 3;
+ }
+
if (!dummyDataAttr) {
if (!actualDataAttr) {
if (isCudaUnified || isCudaManaged) {
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index f2d08302f839e..bd8002e8141b2 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -8,6 +8,7 @@
#include "flang/Parser/tools.h"
#include "flang/Common/indirection.h"
+#include "flang/Evaluate/characteristics.h"
#include "flang/Parser/dump-parse-tree.h"
#include "flang/Parser/message.h"
#include "flang/Parser/parse-tree.h"
@@ -1126,6 +1127,15 @@ bool HasCUDAComponent(const Symbol &symbol) {
return false;
}
+bool IsCUDAAddressSpaceAgnostic(
+ const evaluate::characteristics::DummyDataObject &dummy) {
+ return !dummy.cudaDataAttr && dummy.type.type().IsAssumedType() &&
+ (dummy.type.attrs().test(
+ evaluate::characteristics::TypeAndShape::Attr::AssumedSize) ||
+ dummy.type.attrs().test(
+ evaluate::characteristics::TypeAndShape::Attr::AssumedRank));
+}
+
UltimateComponentIterator::const_iterator
FindCUDADeviceAllocatableUltimateComponent(const DerivedTypeSpec &derived) {
UltimateComponentIterator ultimates{derived};
diff --git a/flang/test/Semantics/cuf10.cuf b/flang/test/Semantics/cuf10.cuf
index 86637a92b2196..df45f4324b2c2 100644
--- a/flang/test/Semantics/cuf10.cuf
+++ b/flang/test/Semantics/cuf10.cuf
@@ -72,3 +72,27 @@ module m
end subroutine
end
+
+module assumed_type_cuda_buffers
+ interface generic_recv
+ module procedure recv_assumed_size
+ end interface
+
+contains
+ subroutine recv_assumed_size(buf, count)
+ type(*) :: buf(1_8:*)
+ integer, intent(in) :: count
+ end subroutine
+
+ subroutine recv_assumed_rank(buf, count)
+ type(*) :: buf(..)
+ integer, intent(in) :: count
+ end subroutine
+
+ subroutine test
+ real, device :: d(10)
+ call recv_assumed_size(d, 10)
+ call recv_assumed_rank(d, 10)
+ call generic_recv(d, 10)
+ end subroutine
+end module
More information about the flang-commits
mailing list