diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -2404,7 +2404,7 @@ mlir::Location loc, const Fortran::parser::AccClauseList &accClauseList) { llvm::SmallVector dataClauseOperands, copyEntryOperands, - createEntryOperands, copyoutEntryOperands; + createEntryOperands, copyoutEntryOperands, deviceResidentEntryOperands; Fortran::lower::StatementContext stmtCtx; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); for (const Fortran::parser::AccClause &clause : accClauseList.v) { @@ -2471,6 +2471,17 @@ linkClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_declare_link, /*structured=*/true); + } else if (const auto *deviceResidentClause = + std::get_if( + &clause.u)) { + auto crtDataStart = dataClauseOperands.size(); + genDataOperandOperations( + deviceResidentClause->v, converter, semanticsContext, stmtCtx, + dataClauseOperands, + mlir::acc::DataClause::acc_declare_device_resident, + /*structured=*/true); + deviceResidentEntryOperands.append( + dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); } else { mlir::Location clauseLocation = converter.genLocation(clause.source); TODO(clauseLocation, "clause on declare directive"); @@ -2479,15 +2490,19 @@ builder.create(loc, dataClauseOperands); if (!createEntryOperands.empty() || !copyEntryOperands.empty() || - !copyoutEntryOperands.empty()) { + !copyoutEntryOperands.empty() || !deviceResidentEntryOperands.empty()) { // Attach declare exit operation generation to function context. fctCtx.attachCleanup([&builder, loc, dataClauseOperands, createEntryOperands, copyEntryOperands, - copyoutEntryOperands]() { + copyoutEntryOperands, deviceResidentEntryOperands]() { builder.create(loc, dataClauseOperands); genDataExitOperations( builder, createEntryOperands, /*structured=*/true, /*implicit=*/false); + genDataExitOperations( + builder, deviceResidentEntryOperands, /*structured=*/true, + /*implicit=*/false); genDataExitOperations( builder, copyEntryOperands, /*structured=*/true, /*implicit=*/false); genDataExitOperations( diff --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90 --- a/flang/test/Lower/OpenACC/acc-declare.f90 +++ b/flang/test/Lower/OpenACC/acc-declare.f90 @@ -205,4 +205,21 @@ ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) ! CHECK-NOT: acc.declare_exit + subroutine acc_declare_device_resident(a) + integer :: a(100), i + !$acc declare device_resident(a) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_device_resident( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) +! CHECK: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[ARG0]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} +! CHECK: acc.declare_enter dataOperands(%[[DEVICERES]] : !fir.ref>) +! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! CHECK: acc.declare_exit dataOperands(%[[DEVICERES]] : !fir.ref>) +! CHECK: acc.delete accPtr(%[[DEVICERES]] : !fir.ref>) bounds(%{{.*}}) {dataClause = #acc, name = "a"} + end module