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 @@ -802,37 +802,43 @@ }; auto addMapClause = [&](const auto &mapClause, mlir::Location &location) { - auto mapType = std::get( - std::get>(mapClause->v.t) - ->t); + const auto &oMapType = + std::get>(mapClause->v.t); llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE; - switch (mapType) { - case Fortran::parser::OmpMapType::Type::To: - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO; - break; - case Fortran::parser::OmpMapType::Type::From: - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; - break; - case Fortran::parser::OmpMapType::Type::Tofrom: + // If the map type is specified, then process it else Tofrom is the default. + if (oMapType) { + const Fortran::parser::OmpMapType::Type &mapType = + std::get(oMapType->t); + switch (mapType) { + case Fortran::parser::OmpMapType::Type::To: + mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO; + break; + case Fortran::parser::OmpMapType::Type::From: + mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; + break; + case Fortran::parser::OmpMapType::Type::Tofrom: + mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO | + llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; + break; + case Fortran::parser::OmpMapType::Type::Alloc: + case Fortran::parser::OmpMapType::Type::Release: + // alloc and release is the default map_type for the Target Data Ops, + // i.e. if no bits for map_type is supplied then alloc/release is + // implicitly assumed based on the target directive. Default value for + // Target Data and Enter Data is alloc and for Exit Data it is release. + break; + case Fortran::parser::OmpMapType::Type::Delete: + mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE; + } + + if (std::get>( + oMapType->t)) + mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS; + } else { mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO | llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; - break; - case Fortran::parser::OmpMapType::Type::Alloc: - case Fortran::parser::OmpMapType::Type::Release: - // alloc and release is the default map_type for the Target Data Ops, i.e. - // if no bits for map_type is supplied then alloc/release is implicitly - // assumed based on the target directive. Default value for Target Data - // and Enter Data is alloc and for Exit Data it is release. - break; - case Fortran::parser::OmpMapType::Type::Delete: - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE; } - if (std::get>( - std::get>(mapClause->v.t) - ->t) - .has_value()) - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS; // TODO: Add support MapTypeModifiers close, mapper, present, iterator diff --git a/flang/test/Lower/OpenMP/target.f90 b/flang/test/Lower/OpenMP/target.f90 --- a/flang/test/Lower/OpenMP/target.f90 +++ b/flang/test/Lower/OpenMP/target.f90 @@ -125,6 +125,24 @@ !CHECK: } end subroutine omp_target_data +!CHECK-LABEL: func.func @_QPomp_target_data_mt +subroutine omp_target_data_mt + integer :: a(1024) + integer :: b(1024) + !CHECK: %[[VAR_A:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_data_mtEa"} + !CHECK: %[[VAR_B:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "b", uniq_name = "_QFomp_target_data_mtEb"} + !CHECK: omp.target_data map((tofrom -> %[[VAR_A]] : !fir.ref>)) + !$omp target data map(a) + !CHECK: omp.terminator + !$omp end target data + !CHECK: } + !CHECK: omp.target_data map((always, from -> %[[VAR_B]] : !fir.ref>)) + !$omp target data map(always, from : b) + !CHECK: omp.terminator + !$omp end target data + !CHECK: } +end subroutine omp_target_data_mt + !=============================================================================== ! Target with region !===============================================================================