[flang-commits] [flang] [flang][openacc] Skip data movement for managed operands (PR #206806)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Tue Jun 30 11:55:43 PDT 2026


https://github.com/clementval created https://github.com/llvm/llvm-project/pull/206806

Skip OpenACC enter/exit data lowering for managed operands and elide the directive when no data operands remain. This avoids invalid empty acc.enter_data/acc.exit_data ops and prevents incorrect managed-memory mappings.

>From e8ba8f660c691fc014f3ec028208487987560202 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Tue, 30 Jun 2026 11:53:41 -0700
Subject: [PATCH] [flang][openacc] Skip data movement for managed operand

---
 flang/lib/Lower/OpenACC.cpp                   | 20 ++++++++++
 .../acc-enter-exit-data-cuda-managed.f90      | 38 +++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 flang/test/Lower/OpenACC/acc-enter-exit-data-cuda-managed.f90

diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 3d21a545382e7..79e4788fa5ca7 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -730,6 +730,14 @@ extractComponentFromDesignator(
   return componentRef;
 }
 
+static bool isOperandManaged(const Fortran::semantics::Symbol &symbol) {
+  const auto cudaAttr =
+      Fortran::semantics::GetCUDADataAttr(&symbol.GetUltimate());
+  if (cudaAttr && *cudaAttr == Fortran::common::CUDADataAttr::Managed)
+    return true;
+  return false;
+}
+
 template <typename Op>
 static void
 genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
@@ -753,6 +761,12 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
 
     Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject);
 
+    // Enter/exit data movement for managed objects is redundant and
+    // can cause mismatched descriptor/data mappings with managed-memory mode.
+    // Treat these operands as no-ops.
+    if (isOperandManaged(symbol))
+      continue;
+
     Fortran::semantics::MaybeExpr designator = Fortran::common::visit(
         [&](auto &&s) { return ea.Analyze(s); }, accObject.u);
     std::optional<Fortran::evaluate::Component> componentRef =
@@ -3415,6 +3429,9 @@ genACCEnterDataOp(Fortran::lower::AbstractConverter &converter,
     }
   }
 
+  if (dataClauseOperands.empty())
+    return;
+
   // Prepare the operand segment size attribute and the operands value range.
   llvm::SmallVector<mlir::Value, 16> operands;
   llvm::SmallVector<int32_t, 8> operandSegments;
@@ -3519,6 +3536,9 @@ genACCExitDataOp(Fortran::lower::AbstractConverter &converter,
   dataClauseOperands.append(deleteOperands);
   dataClauseOperands.append(detachOperands);
 
+  if (dataClauseOperands.empty())
+    return;
+
   // Prepare the operand segment size attribute and the operands value range.
   llvm::SmallVector<mlir::Value, 14> operands;
   llvm::SmallVector<int32_t, 7> operandSegments;
diff --git a/flang/test/Lower/OpenACC/acc-enter-exit-data-cuda-managed.f90 b/flang/test/Lower/OpenACC/acc-enter-exit-data-cuda-managed.f90
new file mode 100644
index 0000000000000..9fd66cb2a79b3
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-enter-exit-data-cuda-managed.f90
@@ -0,0 +1,38 @@
+! Test that OpenACC enter/exit data clauses are skipped for explicit CUDA
+! managed objects, while non-managed objects in the same clause are
+! still lowered.
+!
+! RUN: bbc -fcuda -fopenacc -emit-hlfir -gpu=managed %s -o - | FileCheck %s
+
+subroutine managed_only()
+  real, allocatable :: m(:)
+  allocate(m(10))
+  !$acc enter data copyin(m)
+  !$acc exit data copyout(m)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPmanaged_only()
+! CHECK-NOT: acc.copyin
+! CHECK-NOT: acc.enter_data
+! CHECK-NOT: acc.getdeviceptr
+! CHECK-NOT: acc.exit_data
+! CHECK-NOT: acc.copyout
+
+subroutine mixed_managed_and_regular()
+  real, allocatable :: m(:)
+  real :: h(10)
+  !$acc enter data copyin(m) copyin(h)
+  !$acc exit data copyout(m) copyout(h)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPmixed_managed_and_regular()
+! CHECK: %[[H_COPYIN:.*]] = acc.copyin
+! CHECK-SAME: {name = "h", structured = false}
+! CHECK-NOT: {name = "m", structured = false}
+! CHECK: acc.enter_data dataOperands(%[[H_COPYIN]]
+! CHECK: %[[H_DEVPTR:.*]] = acc.getdeviceptr
+! CHECK-SAME: {dataClause = #acc<data_clause acc_copyout>, name = "h", structured = false}
+! CHECK-NOT: {dataClause = #acc<data_clause acc_copyout>, name = "m", structured = false}
+! CHECK: acc.exit_data dataOperands(%[[H_DEVPTR]]
+! CHECK: acc.copyout accPtr(%[[H_DEVPTR]]
+! CHECK-SAME: {name = "h", structured = false}



More information about the flang-commits mailing list