[flang-commits] [flang] [flang][openacc] Skip data movement for managed operands (PR #206806)
via flang-commits
flang-commits at lists.llvm.org
Tue Jun 30 11:56:17 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Valentin Clement (バレンタイン クレメン) (clementval)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/206806.diff
2 Files Affected:
- (modified) flang/lib/Lower/OpenACC.cpp (+20)
- (added) flang/test/Lower/OpenACC/acc-enter-exit-data-cuda-managed.f90 (+38)
``````````diff
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}
``````````
</details>
https://github.com/llvm/llvm-project/pull/206806
More information about the flang-commits
mailing list