[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