diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index a25d7b2b5dcba..692732a2a698a 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -1327,7 +1327,8 @@ static void genDataOperandOperationsWithModifier( Fortran::parser::AccDataModifier::Modifier mod, llvm::SmallVectorImpl &dataClauseOperands, const mlir::acc::DataClause clause, - const mlir::acc::DataClause clauseWithModifier) { + const mlir::acc::DataClause clauseWithModifier, + bool setDeclareAttr = false) { const Fortran::parser::AccObjectListWithModifier &listWithModifier = x->v; const auto &accObjectList = std::get(listWithModifier.t); @@ -1338,7 +1339,7 @@ static void genDataOperandOperationsWithModifier( (modifier && (*modifier).v == mod) ? clauseWithModifier : clause; genDataOperandOperations(accObjectList, converter, semanticsContext, stmtCtx, dataClauseOperands, dataClause, - /*structured=*/true); + /*structured=*/true, setDeclareAttr); } template @@ -2436,6 +2437,13 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, presentClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_present, /*structured=*/true, /*setDeclareAttr=*/true); + } else if (const auto *copyinClause = + std::get_if(&clause.u)) { + genDataOperandOperationsWithModifier( + copyinClause, converter, semanticsContext, stmtCtx, + Fortran::parser::AccDataModifier::Modifier::ReadOnly, + dataClauseOperands, mlir::acc::DataClause::acc_copyin, + mlir::acc::DataClause::acc_copyin_readonly, /*setDeclareAttr=*/true); } else { mlir::Location clauseLocation = converter.genLocation(clause.source); TODO(clauseLocation, "clause on declare directive"); diff --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90 index 6a0b8b71f7e73..c0c7c4ee1c606 100644 --- a/flang/test/Lower/OpenACC/acc-declare.f90 +++ b/flang/test/Lower/OpenACC/acc-declare.f90 @@ -133,6 +133,26 @@ subroutine acc_declare_present(a) ! CHECK: %[[PRESENT:.*]] = acc.present varPtr(%[[ARG0]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} ! CHECK: acc.declare_enter dataOperands(%[[PRESENT]] : !fir.ref>) ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! CHECK-NOT: acc.declare_exit + + subroutine acc_declare_copyin() + integer :: a(100), b(10), i + !$acc declare copyin(a) copyin(readonly: b) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_copyin() +! CHECK: %[[A:.*]] = fir.alloca !fir.array<100xi32> {acc.declare = #acc.declare, bindc_name = "a", uniq_name = "_QMacc_declareFacc_declare_copyinEa"} +! CHECK: %[[B:.*]] = fir.alloca !fir.array<10xi32> {acc.declare = #acc.declare, bindc_name = "b", uniq_name = "_QMacc_declareFacc_declare_copyinEb"} +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index) +! CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index) +! CHECK: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[B]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "b"} +! CHECK: acc.declare_enter dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref>, !fir.ref>) +! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) ! CHECK-NOT: acc.declare_exit end module