[flang-commits] [flang] c15ae96 - [flang][CUDA] Better analysis of actual argument CUDA data attrs (#179569)

via flang-commits flang-commits at lists.llvm.org
Fri Feb 6 09:30:56 PST 2026


Author: Peter Klausler
Date: 2026-02-06T09:30:50-08:00
New Revision: c15ae96dc7fef09a342a5d0d11df74237600b9a6

URL: https://github.com/llvm/llvm-project/commit/c15ae96dc7fef09a342a5d0d11df74237600b9a6
DIFF: https://github.com/llvm/llvm-project/commit/c15ae96dc7fef09a342a5d0d11df74237600b9a6.diff

LOG: [flang][CUDA] Better analysis of actual argument CUDA data attrs (#179569)

When checking an actual argument for any CUDA data attributes, be sure
to check the symbols in a designator like a%b%c in order, taking the
last symbol that has a CUDA attribute. And be sure to interpret a
function result symbol of a device function as a device object, at least
for generic interface resolution for defined assignments and operators.

This patch exposed errors in flang/test/Semantics/bug1214.cuf, which
have been fixed.

Added: 
    flang/test/Semantics/bug2131b.cuf

Modified: 
    flang/lib/Semantics/check-call.cpp
    flang/test/Semantics/bug1214.cuf

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index f041cab64686c..f0837e1f2ec61 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -1064,9 +1064,9 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
 
   // Warn about dubious actual argument association with a TARGET dummy
   // argument
+  bool actualIsVariable{evaluate::IsVariable(actual)};
   if (dummy.attrs.test(characteristics::DummyDataObject::Attr::Target) &&
       context.ShouldWarn(common::UsageWarning::NonTargetPassedToTarget)) {
-    bool actualIsVariable{evaluate::IsVariable(actual)};
     bool actualIsTemp{
         !actualIsVariable || HasVectorSubscript(actual) || actualCoarrayRef};
     if (actualIsTemp) {
@@ -1090,10 +1090,15 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
       !dummy.attrs.test(characteristics::DummyDataObject::Attr::Value) &&
       !FindOpenACCConstructContaining(scope)) {
     std::optional<common::CUDADataAttr> actualDataAttr, dummyDataAttr;
-    if (const auto *actualObject{actualLastSymbol
-                ? actualLastSymbol->detailsIf<ObjectEntityDetails>()
-                : nullptr}) {
-      actualDataAttr = actualObject->cudaDataAttr();
+    // For a%b%c, the last symbol with a CUDA data attribute wins
+    if (actualIsVariable) {
+      for (const Symbol &s : evaluate::GetSymbolVector(actual)) {
+        if (const auto *object{s.detailsIf<ObjectEntityDetails>()}) {
+          if (auto cudaAttr{object->cudaDataAttr()}) {
+            actualDataAttr = *cudaAttr;
+          }
+        }
+      }
     }
     dummyDataAttr = dummy.cudaDataAttr;
     // Treat MANAGED like DEVICE for nonallocatable nonpointer arguments to
@@ -1113,9 +1118,10 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
         actualDataAttr = common::CUDADataAttr::Device;
       }
       // For device procedures, treat actual arguments with VALUE attribute as
-      // device data; also constant actual arguments.
+      // device data; also constant actual arguments and the function result.
       if (!actualDataAttr &&
-          (!actualLastSymbol || IsValue(*actualLastSymbol)) &&
+          (!actualFirstSymbol || IsValue(*actualFirstSymbol) ||
+              IsFunctionResult(*actualFirstSymbol)) &&
           (*procedure.cudaSubprogramAttrs ==
               common::CUDASubprogramAttrs::Device)) {
         actualDataAttr = common::CUDADataAttr::Device;

diff  --git a/flang/test/Semantics/bug1214.cuf b/flang/test/Semantics/bug1214.cuf
index 114fad15ea500..71dc6b14f887a 100644
--- a/flang/test/Semantics/bug1214.cuf
+++ b/flang/test/Semantics/bug1214.cuf
@@ -14,13 +14,13 @@ module overrides
     real, intent(in) :: x
     real, intent(in), device :: y
     type(realResult) result
-    result%a = x * y
+    result%a = x * (y)
   end
   elemental function multDeviceHost(x, y) result(result)
     real, intent(in), device :: x
     real, intent(in) :: y
     type(realResult) result
-    result%a = x * y
+    result%a = (x) * y
   end
   elemental subroutine assignHostResult(lhs, rhs)
     real, intent(out) :: lhs

diff  --git a/flang/test/Semantics/bug2131b.cuf b/flang/test/Semantics/bug2131b.cuf
new file mode 100644
index 0000000000000..87886b7a02e90
--- /dev/null
+++ b/flang/test/Semantics/bug2131b.cuf
@@ -0,0 +1,33 @@
+!RUN: %flang_fc1 -fdebug-unparse %s | FileCheck %s
+module rgbCUDA
+  type rgb
+    real v(3)
+  end type
+  interface assignment (=)
+     module procedure rgbEqR3
+  end interface
+  interface operator(*)
+     module procedure rgbTimesR
+  end interface
+contains
+  attributes(device) subroutine rgbEqR3(rgbout, rin)
+    type(rgb), intent(out) :: rgbout
+    real(4), intent(in) :: rin(3)
+    rgbout%v = rin
+  end
+  attributes(device) function rgbTimesR(rgbin, rin) result(res)
+    type(rgb), intent(in) :: rgbin
+    real(4), intent(in) :: rin
+    real(4) :: res(3)
+    res = rgbin%v * rin
+  end
+  attributes(device) function color() result(res)
+    type(rgb) :: res
+    real :: attenuation
+!CHECK: CALL rgbeqr3(res,[REAL(4)::0._4,0._4,0._4])
+    res = [0.0, 0.0, 0.0]
+    attenuation = 0.5
+!CHECK: CALL rgbeqr3(res,rgbtimesr(res,attenuation))
+    res = res * attenuation
+  end
+end


        


More information about the flang-commits mailing list