diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index fd8bf143a70d6..937815c8f947b 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -2400,20 +2400,33 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext &fctCtx, mlir::Location loc, const Fortran::parser::AccClauseList &accClauseList) { - llvm::SmallVector dataClauseOperands, copyEntryOperands; + llvm::SmallVector dataClauseOperands, copyEntryOperands, + createEntryOperands; Fortran::lower::StatementContext stmtCtx; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); for (const Fortran::parser::AccClause &clause : accClauseList.v) { if (const auto *copyClause = std::get_if(&clause.u)) { auto crtDataStart = dataClauseOperands.size(); - genDataOperandOperations( copyClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_copy, /*structured=*/true, /*setDeclareAttr=*/true); copyEntryOperands.append(dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); + } else if (const auto *createClause = + std::get_if(&clause.u)) { + const Fortran::parser::AccObjectListWithModifier &listWithModifier = + createClause->v; + const auto &accObjectList = + std::get(listWithModifier.t); + auto crtDataStart = dataClauseOperands.size(); + genDataOperandOperations( + accObjectList, converter, semanticsContext, stmtCtx, + dataClauseOperands, mlir::acc::DataClause::acc_create, + /*structured=*/true, /*setDeclareAttr=*/true); + createEntryOperands.append(dataClauseOperands.begin() + crtDataStart, + dataClauseOperands.end()); } else { mlir::Location clauseLocation = converter.genLocation(clause.source); TODO(clauseLocation, "clause on declare directive"); @@ -2422,10 +2435,13 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, builder.create(loc, dataClauseOperands); // Attach declare exit operation generation to function context. - fctCtx.attachCleanup([&builder, loc, copyEntryOperands]() { - builder.create(loc, copyEntryOperands); - genDataExitOperations( - builder, copyEntryOperands, /*structured=*/true, /*implicit=*/false); + fctCtx.attachCleanup([&builder, loc, dataClauseOperands, createEntryOperands, + copyEntryOperands]() { + builder.create(loc, dataClauseOperands); + genDataExitOperations( + builder, createEntryOperands, /*structured=*/true, /*implicit=*/false); + genDataExitOperations(builder, + copyEntryOperands, /*structured=*/true, /*implicit=*/false); }); } diff --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90 index c0ad91581e7e2..294f495fb36e0 100644 --- a/flang/test/Lower/OpenACC/acc-declare.f90 +++ b/flang/test/Lower/OpenACC/acc-declare.f90 @@ -95,4 +95,28 @@ subroutine acc_declare_copy() ! CHECK: return + subroutine acc_declare_create() + integer :: a(100), i + !$acc declare create(a) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_create() { + +! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32> {acc.declare = #acc.declare, bindc_name = "a", uniq_name = "_QMacc_declareFacc_declare_createEa"} +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1 : index) startIdx(%c1 : index) +! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[ALLOCA]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! CHECK: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) + +! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (index, i32) { +! CHECK: } + +! CHECK: acc.declare_exit dataOperands(%[[CREATE]] : !fir.ref>) +! CHECK: acc.delete accPtr(%[[CREATE]] : !fir.ref>) bounds(%[[BOUND]]) {dataClause = #acc, name = "a"} +! CHECK: return + + end module