diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -623,7 +623,8 @@ static void createTargetDataOp(Fortran::lower::AbstractConverter &converter, const Fortran::parser::OmpClauseList &opClauseList, - const llvm::omp::Directive &directive) { + const llvm::omp::Directive &directive, + Fortran::lower::pft::Evaluation *eval = nullptr) { Fortran::lower::StatementContext stmtCtx; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); @@ -728,9 +729,10 @@ mlir::Location currentLocation = converter.getCurrentLocation(); if (directive == llvm::omp::Directive::OMPD_target_data) { - firOpBuilder.create( + auto dataOp = firOpBuilder.create( currentLocation, ifClauseOperand, deviceOperand, useDevicePtrOperand, useDeviceAddrOperand, mapOperands, mapTypesArrayAttr); + createBodyOfOp(dataOp, converter, currentLocation, *eval, &opClauseList); } else if (directive == llvm::omp::Directive::OMPD_target_enter_data) { firOpBuilder.create(currentLocation, ifClauseOperand, deviceOperand, nowaitAttr, @@ -982,6 +984,10 @@ } else if (std::get_if(&clause.u)) { // Nothing needs to be done for threads clause. continue; + } else if (std::get_if(&clause.u)) { + // Map clause is exclusive to Target Data directives. It is handled + // as part of the DataOp creation. + continue; } else if (const auto &finalClause = std::get_if(&clause.u)) { mlir::Value finalVal = fir::getBase(converter.genExprValue( @@ -1049,6 +1055,8 @@ /*task_reductions=*/nullptr, allocateOperands, allocatorOperands); createBodyOfOp(taskGroupOp, converter, currentLocation, eval, &opClauseList); + } else if (blockDirective.v == llvm::omp::OMPD_target_data) { + createTargetDataOp(converter, opClauseList, blockDirective.v, &eval); } else { TODO(converter.getCurrentLocation(), "Unhandled block directive"); } diff --git a/flang/test/Lower/OpenMP/target_data.f90 b/flang/test/Lower/OpenMP/target_data.f90 --- a/flang/test/Lower/OpenMP/target_data.f90 +++ b/flang/test/Lower/OpenMP/target_data.f90 @@ -4,7 +4,6 @@ ! Target_Enter Simple !=============================================================================== - !CHECK-LABEL: func.func @_QPomp_target_enter_simple() { subroutine omp_target_enter_simple integer :: a(1024) @@ -48,8 +47,8 @@ i = 5 !CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1:.*]] : !fir.ref !CHECK: %[[VAL_4:.*]] = arith.constant 10 : i32 - !CHECK: %[[VAL_5:.*]] = arith.cmpi slt, %[[VAL_3:.*]], %[[VAL_4:.*]] : i32 - !CHECK: omp.target_enter_data if(%[[VAL_5:.*]] : i1) map((to -> {{.*}} : !fir.ref>)) + !CHECK: %[[VAL_5:.*]] = arith.cmpi slt, %[[VAL_3]], %[[VAL_4]] : i32 + !CHECK: omp.target_enter_data if(%[[VAL_5]] : i1) map((to -> {{.*}} : !fir.ref>)) !$omp target enter data if(i<10) map(to: a) end subroutine omp_target_enter_if @@ -61,7 +60,7 @@ subroutine omp_target_enter_device integer :: a(1024) !CHECK: %[[VAL_1:.*]] = arith.constant 2 : i32 - !CHECK: omp.target_enter_data device(%[[VAL_1:.*]] : i32) map((to -> {{.*}} : !fir.ref>)) + !CHECK: omp.target_enter_data device(%[[VAL_1]] : i32) map((to -> {{.*}} : !fir.ref>)) !$omp target enter data map(to: a) device(2) end subroutine omp_target_enter_device @@ -100,6 +99,28 @@ integer :: a(1024) integer :: d !CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1:.*]] : !fir.ref - !CHECK: omp.target_exit_data device(%[[VAL_2:.*]] : i32) map((from -> {{.*}} : !fir.ref>)) + !CHECK: omp.target_exit_data device(%[[VAL_2]] : i32) map((from -> {{.*}} : !fir.ref>)) !$omp target exit data map(from: a) device(d) end subroutine omp_target_exit_device + +!=============================================================================== +! Target_Data with region +!=============================================================================== + +!CHECK-LABEL: func.func @_QPomp_target_data() { +subroutine omp_target_data + !CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_dataEa"} + integer :: a(1024) + !CHECK: omp.target_data map((tofrom -> %[[VAL_0]] : !fir.ref>)) { + !$omp target data map(tofrom: a) + !CHECK: %[[VAL_1:.*]] = arith.constant 10 : i32 + !CHECK: %[[VAL_2:.*]] = arith.constant 1 : i64 + !CHECK: %[[VAL_3:.*]] = arith.constant 1 : i64 + !CHECK: %[[VAL_4:.*]] = arith.subi %[[VAL_2]], %[[VAL_3]] : i64 + !CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_4]] : (!fir.ref>, i64) -> !fir.ref + !CHECK: fir.store %[[VAL_1]] to %[[VAL_5]] : !fir.ref + a(1) = 10 + !CHECK: omp.terminator + !$omp end target data + !CHECK: } +end subroutine omp_target_data