diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 1c163e6de7e5a..872f31fe45cca 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -406,6 +406,11 @@ bool ClauseProcessor::processMergeable( return markClauseOccurrence(result.mergeable); } +bool ClauseProcessor::processNogroup( + mlir::omp::NogroupClauseOps &result) const { + return markClauseOccurrence(result.nogroup); +} + bool ClauseProcessor::processNowait(mlir::omp::NowaitClauseOps &result) const { return markClauseOccurrence(result.nowait); } diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index 6452e39b97551..d524b4ddc8ac4 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -89,6 +89,7 @@ class ClauseProcessor { bool processInclusive(mlir::Location currentLocation, mlir::omp::InclusiveClauseOps &result) const; bool processMergeable(mlir::omp::MergeableClauseOps &result) const; + bool processNogroup(mlir::omp::NogroupClauseOps &result) const; bool processNowait(mlir::omp::NowaitClauseOps &result) const; bool processNumTasks(lower::StatementContext &stmtCtx, mlir::omp::NumTasksClauseOps &result) const; diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp index 146a252b049ec..83c2eda0a2dc7 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp @@ -342,7 +342,8 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { if (!hasLastPrivate) return; - if (mlir::isa(op) || mlir::isa(op)) { + if (mlir::isa(op) || mlir::isa(op) || + mlir::isa(op)) { mlir::omp::LoopRelatedClauseOps result; llvm::SmallVector iv; collectLoopRelatedInfo(converter, converter.getCurrentLocation(), eval, @@ -408,7 +409,7 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { } else { TODO(converter.getCurrentLocation(), "lastprivate clause in constructs other than " - "simd/worksharing-loop"); + "simd/worksharing-loop/taskloop"); } } diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 99470d0bbd2bf..6e9f0716a02fe 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -1762,25 +1762,27 @@ static void genTaskgroupClauses( cp.processTaskReduction(loc, clauseOps, taskReductionSyms); } -static void genTaskloopClauses(lower::AbstractConverter &converter, - semantics::SemanticsContext &semaCtx, - lower::StatementContext &stmtCtx, - const List &clauses, mlir::Location loc, - mlir::omp::TaskloopOperands &clauseOps) { +static void genTaskloopClauses( + lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx, + lower::StatementContext &stmtCtx, const List &clauses, + mlir::Location loc, mlir::omp::TaskloopOperands &clauseOps, + llvm::SmallVectorImpl &reductionSyms, + llvm::SmallVectorImpl &inReductionSyms) { ClauseProcessor cp(converter, semaCtx, clauses); cp.processAllocate(clauseOps); cp.processFinal(stmtCtx, clauseOps); cp.processGrainsize(stmtCtx, clauseOps); cp.processIf(llvm::omp::Directive::OMPD_taskloop, clauseOps); + cp.processInReduction(loc, clauseOps, inReductionSyms); cp.processMergeable(clauseOps); + cp.processNogroup(clauseOps); cp.processNumTasks(stmtCtx, clauseOps); cp.processPriority(stmtCtx, clauseOps); + cp.processReduction(loc, clauseOps, reductionSyms); cp.processUntied(clauseOps); - cp.processTODO( - loc, llvm::omp::Directive::OMPD_taskloop); + cp.processTODO(loc, llvm::omp::Directive::OMPD_taskloop); } static void genTaskwaitClauses(lower::AbstractConverter &converter, @@ -2982,8 +2984,11 @@ static mlir::omp::TaskloopOp genStandaloneTaskloop( lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item) { mlir::omp::TaskloopOperands taskloopClauseOps; + llvm::SmallVector reductionSyms; + llvm::SmallVector inReductionSyms; + genTaskloopClauses(converter, semaCtx, stmtCtx, item->clauses, loc, - taskloopClauseOps); + taskloopClauseOps, reductionSyms, inReductionSyms); DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, enableDelayedPrivatization, symTable); @@ -2997,6 +3002,10 @@ static mlir::omp::TaskloopOp genStandaloneTaskloop( EntryBlockArgs taskloopArgs; taskloopArgs.priv.syms = dsp.getDelayedPrivSymbols(); taskloopArgs.priv.vars = taskloopClauseOps.privateVars; + taskloopArgs.reduction.syms = reductionSyms; + taskloopArgs.reduction.vars = taskloopClauseOps.reductionVars; + taskloopArgs.inReduction.syms = inReductionSyms; + taskloopArgs.inReduction.vars = taskloopClauseOps.inReductionVars; auto taskLoopOp = genWrapperOp( converter, loc, taskloopClauseOps, taskloopArgs); diff --git a/flang/test/Lower/OpenMP/Todo/taskloop-inreduction.f90 b/flang/test/Lower/OpenMP/Todo/taskloop-inreduction.f90 deleted file mode 100644 index 8acc399a92abe..0000000000000 --- a/flang/test/Lower/OpenMP/Todo/taskloop-inreduction.f90 +++ /dev/null @@ -1,13 +0,0 @@ -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s - -! CHECK: not yet implemented: Unhandled clause IN_REDUCTION in TASKLOOP construct -subroutine omp_taskloop_inreduction() - integer x - x = 0 - !$omp taskloop in_reduction(+:x) - do i = 1, 100 - x = x + 1 - end do - !$omp end taskloop -end subroutine omp_taskloop_inreduction diff --git a/flang/test/Lower/OpenMP/Todo/taskloop-lastprivate.f90 b/flang/test/Lower/OpenMP/Todo/taskloop-lastprivate.f90 deleted file mode 100644 index 54f2580daf283..0000000000000 --- a/flang/test/Lower/OpenMP/Todo/taskloop-lastprivate.f90 +++ /dev/null @@ -1,13 +0,0 @@ -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s - -! CHECK: not yet implemented: Unhandled clause LASTPRIVATE in TASKLOOP construct -subroutine omp_taskloop_lastprivate() - integer x - x = 0 - !$omp taskloop lastprivate(x) - do i = 1, 100 - x = x + 1 - end do - !$omp end taskloop -end subroutine omp_taskloop_lastprivate diff --git a/flang/test/Lower/OpenMP/Todo/taskloop-nogroup.f90 b/flang/test/Lower/OpenMP/Todo/taskloop-nogroup.f90 deleted file mode 100644 index 2a0c5985290e2..0000000000000 --- a/flang/test/Lower/OpenMP/Todo/taskloop-nogroup.f90 +++ /dev/null @@ -1,13 +0,0 @@ -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s - -! CHECK: not yet implemented: Unhandled clause NOGROUP in TASKLOOP construct -subroutine omp_taskloop_nogroup() - integer x - x = 0 - !$omp taskloop nogroup - do i = 1, 100 - x = x + 1 - end do - !$omp end taskloop -end subroutine omp_taskloop_nogroup diff --git a/flang/test/Lower/OpenMP/Todo/taskloop-reduction.f90 b/flang/test/Lower/OpenMP/Todo/taskloop-reduction.f90 deleted file mode 100644 index 0c16bd227257f..0000000000000 --- a/flang/test/Lower/OpenMP/Todo/taskloop-reduction.f90 +++ /dev/null @@ -1,13 +0,0 @@ -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s - -! CHECK: not yet implemented: Unhandled clause REDUCTION in TASKLOOP construct -subroutine omp_taskloop_reduction() - integer x - x = 0 - !$omp taskloop reduction(+:x) - do i = 1, 100 - x = x + 1 - end do - !$omp end taskloop -end subroutine omp_taskloop_reduction diff --git a/flang/test/Lower/OpenMP/taskloop.f90 b/flang/test/Lower/OpenMP/taskloop.f90 index 4a06e4def0c83..d23eef2d4ac2d 100644 --- a/flang/test/Lower/OpenMP/taskloop.f90 +++ b/flang/test/Lower/OpenMP/taskloop.f90 @@ -2,6 +2,15 @@ ! RUN: bbc -emit-hlfir %openmp_flags -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir %openmp_flags -o - %s 2>&1 | FileCheck %s +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[LAST_PRIVATE_I:.*]] : i32 + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[LAST_PRIVATE_X:.*]] : i32 + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[QFOMP_TASKLOOP_NOGROUPEI_PRIVATE_I32:.*]] : i32 + ! CHECK-LABEL: omp.private ! CHECK-SAME: {type = private} @[[OMP_TASKLOOP_UNTIEDEI_PRIVATE_I32:.*]] : i32 @@ -195,3 +204,46 @@ subroutine omp_taskloop_untied() end do !$omp end taskloop end subroutine + +!=============================================================================== +! `nogroup` clause +!=============================================================================== + +subroutine omp_taskloop_nogroup() + ! CHECK: omp.taskloop nogroup + !$omp taskloop nogroup + do i = 1, 10 + call foo() + end do + !$omp end taskloop +end subroutine + +!=============================================================================== +! `lastprivate` clause +!=============================================================================== + +! CHECK-LABEL: func.func @_QPomp_taskloop_lastprivate +! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloop_lastprivateEi"} +! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFomp_taskloop_lastprivateEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_taskloop_lastprivateEx"} +! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFomp_taskloop_lastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +subroutine omp_taskloop_lastprivate() + integer x + x = 0 + ! CHECK: omp.taskloop private(@[[LAST_PRIVATE_X]] %[[DECL_X]]#0 -> %[[ARG0]], @[[LAST_PRIVATE_I]] %[[DECL_I]]#0 -> %[[ARG1]] : !fir.ref, !fir.ref) { + !$omp taskloop lastprivate(x) + do i = 1, 100 + ! CHECK: %[[DECL_ARG0:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFomp_taskloop_lastprivateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) + ! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[DECL_ARG0]]#0 : !fir.ref + ! CHECK: %[[RES_ADD:.*]] = arith.addi %[[LOAD_ARG0]], %{{.*}} : i32 + ! CHECK: hlfir.assign %[[RES_ADD]] to %[[DECL_ARG0]]#0 : i32, !fir.ref + x = x + 1 + ! CHECK: %[[SELCT_RESULT:.*]] = arith.select %{{.*}}, %{{.*}}, %{{.*}} : i1 + ! CHECK: fir.if %[[SELCT_RESULT]] { + ! CHECK: %[[LOADED_SUM:.*]] = fir.load %[[DECL_ARG0]]#0 : !fir.ref + ! CHECK: hlfir.assign %[[LOADED_SUM]] to %[[DECL_X]]#0 : i32, !fir.ref + ! CHECK: } + ! CHECK: omp.yield + end do + !$omp end taskloop +end subroutine omp_taskloop_lastprivate diff --git a/flang/test/Lower/taskloop-inreduction.f90 b/flang/test/Lower/taskloop-inreduction.f90 new file mode 100644 index 0000000000000..e7d3f96115fbd --- /dev/null +++ b/flang/test/Lower/taskloop-inreduction.f90 @@ -0,0 +1,40 @@ +! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[PRIVATE_I:.*]] : i32 + +! CHECK-LABEL: omp.declare_reduction +! CHECK-SAME: @[[ADD_RED_I32:.*]] : i32 init { +! CHECK: ^bb0(%{{.*}}: i32): +! CHECK: %[[C0_I32:.*]] = arith.constant 0 : i32 +! CHECK: omp.yield(%[[C0_I32]] : i32) +! CHECK: } combiner { +! CHECK: ^bb0(%{{.*}}: i32, %{{.*}}: i32): +! CHECK: %[[RES:.*]] = arith.addi %{{.*}}, %{{.*}} : i32 +! CHECK: omp.yield(%[[RES]] : i32) +! CHECK: } + +! CHECK-LABEL: func.func @_QPomp_taskloop_inreduction +! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloop_inreductionEi"} +! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFomp_taskloop_inreductionEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_taskloop_inreductionEx"} +! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFomp_taskloop_inreductionEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[INIT_X:.*]] = arith.constant 0 : i32 +! CHECK: hlfir.assign %[[INIT_X]] to %[[DECL_X]]#0 : i32, !fir.ref +subroutine omp_taskloop_inreduction() + integer x + x = 0 + ! CHECK: omp.taskloop in_reduction(@[[ADD_RED_I32]] + ! CHECK: %[[DECL_X]]#0 -> %[[ARG0:.*]] : !fir.ref) private(@[[PRIVATE_I]] %[[DECL_I]]#0 -> %[[ARG1:.*]] : !fir.ref) { + ! CHECK: %[[VAL_ARG1:.*]]:2 = hlfir.declare %[[ARG0]] + ! CHECK-SAME: {uniq_name = "_QFomp_taskloop_inreductionEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) + !$omp taskloop in_reduction(+:x) + do i = 1, 100 + ! CHECK: %[[X_VAL:.*]] = fir.load %[[VAL_ARG1]]#0 : !fir.ref + ! CHECK: %[[ADD_VAL:.*]] = arith.addi %[[X_VAL]], %{{.*}} : i32 + x = x + 1 + ! CHECK: hlfir.assign %[[ADD_VAL]] to %[[VAL_ARG1]]#0 : i32, !fir.ref + end do + !$omp end taskloop +end subroutine omp_taskloop_inreduction diff --git a/flang/test/Lower/taskloop-reduction.f90 b/flang/test/Lower/taskloop-reduction.f90 new file mode 100644 index 0000000000000..e45c0181bcc8b --- /dev/null +++ b/flang/test/Lower/taskloop-reduction.f90 @@ -0,0 +1,39 @@ +! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[PRIVATE_I:.*]] : i32 + +! CHECK-LABEL: omp.declare_reduction +! CHECK-SAME: @[[ADD_RED_I32:.*]] : i32 init { +! CHECK: ^bb0(%{{.*}}: i32): +! CHECK: %[[C0_I32:.*]] = arith.constant 0 : i32 +! CHECK: omp.yield(%[[C0_I32]] : i32) +! CHECK: } combiner { +! CHECK: ^bb0(%{{.*}}: i32, %{{.*}}: i32): +! CHECK: %[[RES:.*]] = arith.addi %{{.*}}, %{{.*}} : i32 +! CHECK: omp.yield(%[[RES]] : i32) +! CHECK: } + +! CHECK-LABEL: func.func @_QPomp_taskloop_reduction +! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloop_reductionEi"} +! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFomp_taskloop_reductionEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_taskloop_reductionEx"} +! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFomp_taskloop_reductionEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[INIT_X:.*]] = arith.constant 0 : i32 +! CHECK: hlfir.assign %[[INIT_X]] to %[[DECL_X]]#0 : i32, !fir.ref +subroutine omp_taskloop_reduction() + integer x + x = 0 + ! CHECK: omp.taskloop private(@[[PRIVATE_I]] + ! CHECK-SAME: %[[DECL_I]]#0 -> %[[ARG0:.*]] : !fir.ref) reduction(@[[ADD_RED_I32]] %[[DECL_X]]#0 -> %[[ARG1:.*]] : !fir.ref) { + ! CHECK: %[[VAL_ARG1:.*]]:2 = hlfir.declare %[[ARG1]] + !$omp taskloop reduction(+:x) + do i = 1, 100 + ! CHECK: %[[X_VAL:.*]] = fir.load %[[VAL_ARG1]]#0 : !fir.ref + ! CHECK: %[[ADD_VAL:.*]] = arith.addi %[[X_VAL]], %{{.*}} : i32 + x = x + 1 + ! CHECK: hlfir.assign %[[ADD_VAL]] to %[[VAL_ARG1]]#0 : i32, !fir.ref + end do + !$omp end taskloop +end subroutine omp_taskloop_reduction