[flang-commits] [flang] [flang][CUDA] Preserve data attrs on assignment RHS (PR #207849)
Andre Kuhlenschmidt via flang-commits
flang-commits at lists.llvm.org
Wed Jul 8 17:10:07 PDT 2026
https://github.com/akuhlens updated https://github.com/llvm/llvm-project/pull/207849
>From 399739ffead78424596b0b112b305e9217da255c Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Thu, 2 Jul 2026 17:49:01 -0700
Subject: [PATCH] [flang][CUDA] Preserve data attrs on assignment RHS
Treat a parenthesized variable as a source of CUDA data attributes when checking dummy/actual argument compatibility. Defined assignment parenthesizes non-VALUE RHS actuals to preserve value semantics, but the CUDA address space of the referenced data is unchanged by that materialization.
Add CUDA semantics coverage for a device RHS selected through defined assignment.
---
flang/lib/Semantics/check-call.cpp | 35 ++++++++++++++++++-
.../CUDA/cuf-defined-assignment-rhs.cuf | 34 ++++++++++++++++++
2 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 flang/test/Semantics/CUDA/cuf-defined-assignment-rhs.cuf
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 16c1e166ded66..060459ea0d495 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -27,6 +27,37 @@ namespace characteristics = Fortran::evaluate::characteristics;
namespace Fortran::semantics {
+template <typename A> static bool IsParenthesizedVariable(const A &) {
+ return false;
+}
+
+template <typename T>
+static bool IsParenthesizedVariable(const evaluate::Expr<T> &expr) {
+ if (const auto *parens{
+ evaluate::UnwrapExpr<evaluate::Parentheses<T>>(expr)}) {
+ return evaluate::IsVariable(parens->left());
+ }
+ return false;
+}
+
+template <evaluate::TypeCategory CAT>
+static bool IsParenthesizedVariable(
+ const evaluate::Expr<evaluate::SomeKind<CAT>> &expr) {
+ return common::visit(
+ [](const auto &x) { return IsParenthesizedVariable(x); }, expr.u);
+}
+
+static bool IsParenthesizedVariable(
+ const evaluate::Expr<evaluate::SomeType> &expr) {
+ return common::visit(
+ [](const auto &x) { return IsParenthesizedVariable(x); }, expr.u);
+}
+
+static bool IsVariableOrParenthesizedVariable(
+ const evaluate::Expr<evaluate::SomeType> &expr) {
+ return evaluate::IsVariable(expr) || IsParenthesizedVariable(expr);
+}
+
void CheckImplicitInterfaceArgKeywords(
const evaluate::ActualArgument &arg, parser::ContextualMessages &messages) {
auto restorer{
@@ -1124,7 +1155,9 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
!FindOpenACCConstructContaining(scope)) {
std::optional<common::CUDADataAttr> actualDataAttr, dummyDataAttr;
// For a%b%c, the last symbol with a CUDA data attribute wins
- if (actualIsVariable) {
+ // Parentheses here mean expression/copy semantics, but CUDA address space
+ // attributes remain stable when a variable is materialized as a copy.
+ if (IsVariableOrParenthesizedVariable(actual)) {
for (const Symbol &s : evaluate::GetSymbolVector(actual)) {
if (const auto *object{s.detailsIf<ObjectEntityDetails>()}) {
if (auto cudaAttr{object->cudaDataAttr()}) {
diff --git a/flang/test/Semantics/CUDA/cuf-defined-assignment-rhs.cuf b/flang/test/Semantics/CUDA/cuf-defined-assignment-rhs.cuf
new file mode 100644
index 0000000000000..bd0ab5f7c3068
--- /dev/null
+++ b/flang/test/Semantics/CUDA/cuf-defined-assignment-rhs.cuf
@@ -0,0 +1,34 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1
+
+module m
+ type box
+ integer :: n
+ end type
+
+ interface assignment(=)
+ module procedure assign_host
+ module procedure assign_device
+ end interface
+
+contains
+ subroutine assign_host(lhs, rhs)
+ type(box), intent(inout) :: lhs
+ real, intent(in) :: rhs(:)
+ end subroutine
+
+ subroutine assign_device(lhs, rhs)
+ type(box), intent(inout) :: lhs
+ real, device, intent(in) :: rhs(:)
+ end subroutine
+end module
+
+subroutine test
+ use m
+ type(box) :: lhs
+ real :: host(4)
+ real, device, allocatable :: dev(:)
+ allocate(dev(4))
+
+ lhs = host
+ lhs = dev
+end subroutine
More information about the flang-commits
mailing list