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 @@ -320,8 +320,12 @@ std::get(sectionsConstruct.t) .t); for (const Fortran::parser::OmpClause &clause : sectionsClauseList.v) { + + // Reduction Clause if (std::get_if(&clause.u)) { TODO(currentLocation, "OMPC_Reduction"); + + // Allocate clause } else if (const auto &allocateClause = std::get_if( &clause.u)) { @@ -334,16 +338,39 @@ const auto &clauseList = std::get(endSectionsClauseList.t); for (const auto &clause : clauseList.v) { + // Nowait clause if (std::get_if(&clause.u)) { noWaitClauseOperand = firOpBuilder.getUnitAttr(); } } - mlir::omp::SectionsOp sectionsOp = firOpBuilder.create( - currentLocation, reductionVars, /*reductions = */ nullptr, - allocateOperands, allocatorOperands, noWaitClauseOperand); + llvm::omp::Directive dir = + std::get( + std::get( + sectionsConstruct.t) + .t) + .v; - createBodyOfOp(sectionsOp, firOpBuilder, currentLocation); + // Parallel Sections Construct + if (dir == llvm::omp::Directive::OMPD_parallel_sections) { + auto parallelOp = firOpBuilder.create( + currentLocation, /*if_expr_var*/ nullptr, /*num_threads_var*/ nullptr, + allocateOperands, allocatorOperands, /*reduction_vars=*/ValueRange(), + /*reductions=*/nullptr, /*proc_bind_val*/ nullptr); + createBodyOfOp(parallelOp, firOpBuilder, currentLocation); + auto sectionsOp = firOpBuilder.create( + currentLocation, /*reduction_vars*/ ValueRange(), + /*reductions=*/nullptr, /*allocate_vars*/ ValueRange(), + /*allocators_vars*/ ValueRange(), /*nowait=*/nullptr); + createBodyOfOp(sectionsOp, firOpBuilder, currentLocation); + + // Sections Construct + } else if (dir == llvm::omp::Directive::OMPD_sections) { + auto sectionsOp = firOpBuilder.create( + currentLocation, reductionVars, /*reductions = */ nullptr, + allocateOperands, allocatorOperands, noWaitClauseOperand); + createBodyOfOp(sectionsOp, firOpBuilder, currentLocation); + } } void Fortran::lower::genOpenMPConstruct( diff --git a/flang/test/Lower/OpenMP/parallel-sections.f90 b/flang/test/Lower/OpenMP/parallel-sections.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/OpenMP/parallel-sections.f90 @@ -0,0 +1,57 @@ +!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect" +!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | fir-opt --cfg-conversion | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect,LLVMDialect" + +!=============================================================================== +! Parallel sections construct +!=============================================================================== + +!FIRDialect: func @_QPomp_parallel_sections +subroutine omp_parallel_sections(x, y) + integer, intent(inout) :: x, y + !OMPDialect: omp.parallel { + !OMPDialect: omp.sections { + !$omp parallel sections + !OMPDialect: omp.section { + !$omp section + !FIRDialect: fir.load + !FIRDialect: arith.addi + !FIRDialect: fir.store + x = x + 12 + !OMPDialect: omp.terminator + !OMPDialect: omp.section { + !$omp section + !FIRDialect: fir.load + !FIRDialect: arith.subi + !FIRDialect: fir.store + y = y - 5 + !OMPDialect: omp.terminator + !OMPDialect: omp.terminator + !OMPDialect: omp.terminator + !$omp end parallel sections +end subroutine omp_parallel_sections + +!=============================================================================== +! Parallel sections construct with allocate clause +!=============================================================================== + +!FIRDialect: func @_QPomp_parallel_sections +subroutine omp_parallel_sections_allocate(x, y) + use omp_lib + integer, intent(inout) :: x, y + !FIRDialect: %[[allocator:.*]] = arith.constant 1 : i32 + !LLVMDialect: %[[allocator:.*]] = llvm.mlir.constant(1 : i32) : i32 + !OMPDialect: omp.parallel allocate(%[[allocator]] : i32 -> %{{.*}} : !fir.ref) { + !OMPDialect: omp.sections { + !$omp parallel sections allocate(omp_high_bw_mem_alloc: x) + !OMPDialect: omp.section { + !$omp section + x = x + 12 + !OMPDialect: omp.terminator + !OMPDialect: omp.section { + !$omp section + y = y + 5 + !OMPDialect: omp.terminator + !OMPDialect: omp.terminator + !OMPDialect: omp.terminator + !$omp end parallel sections +end subroutine omp_parallel_sections_allocate