[flang-commits] [flang] [llvm] [Flang][OpenMP] Add Lowering support for taskloop reductions (PR #166582)
via flang-commits
flang-commits at lists.llvm.org
Wed Nov 5 08:34:22 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp
Author: Jack Styles (Stylie777)
<details>
<summary>Changes</summary>
Support for lowering the Reduction clause support already exists, so we can extend the support for taskloop to include reduction.
As support for Reduction in taskloop was only added in OpenMP 5.0, the use of the Clause has been restricted to that version of OpenMP or greater.
---
Full diff: https://github.com/llvm/llvm-project/pull/166582.diff
4 Files Affected:
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+12-8)
- (removed) flang/test/Lower/OpenMP/Todo/taskloop-reduction.f90 (-13)
- (added) flang/test/Lower/OpenMP/taskloop-reduction.f90 (+30)
- (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+10-11)
``````````diff
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index ad456d89bc432..51170a39d272b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1763,21 +1763,22 @@ static void genTaskgroupClauses(
cp.processTaskReduction(loc, clauseOps, taskReductionSyms);
}
-static void genTaskloopClauses(lower::AbstractConverter &converter,
- semantics::SemanticsContext &semaCtx,
- lower::StatementContext &stmtCtx,
- const List<Clause> &clauses, mlir::Location loc,
- mlir::omp::TaskloopOperands &clauseOps) {
+static void genTaskloopClauses(
+ lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
+ lower::StatementContext &stmtCtx, const List<Clause> &clauses,
+ mlir::Location loc, mlir::omp::TaskloopOperands &clauseOps,
+ llvm::SmallVectorImpl<const semantics::Symbol *> &taskReductionSyms) {
ClauseProcessor cp(converter, semaCtx, clauses);
cp.processGrainsize(stmtCtx, clauseOps);
cp.processNumTasks(stmtCtx, clauseOps);
+ cp.processReduction(loc, clauseOps, taskReductionSyms);
cp.processTODO<clause::Allocate, clause::Collapse, clause::Default,
clause::Final, clause::If, clause::InReduction,
clause::Lastprivate, clause::Mergeable, clause::Nogroup,
- clause::Priority, clause::Reduction, clause::Shared,
- clause::Untied>(loc, llvm::omp::Directive::OMPD_taskloop);
+ clause::Priority, clause::Shared, clause::Untied>(
+ loc, llvm::omp::Directive::OMPD_taskloop);
}
static void genTaskwaitClauses(lower::AbstractConverter &converter,
@@ -2979,8 +2980,9 @@ 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<const semantics::Symbol *> taskReductionSyms;
genTaskloopClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
- taskloopClauseOps);
+ taskloopClauseOps, taskReductionSyms);
DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
/*shouldCollectPreDeterminedSymbols=*/true,
enableDelayedPrivatization, symTable);
@@ -2994,6 +2996,8 @@ static mlir::omp::TaskloopOp genStandaloneTaskloop(
EntryBlockArgs taskloopArgs;
taskloopArgs.priv.syms = dsp.getDelayedPrivSymbols();
taskloopArgs.priv.vars = taskloopClauseOps.privateVars;
+ taskloopArgs.reduction.syms = taskReductionSyms;
+ taskloopArgs.reduction.vars = taskloopClauseOps.reductionVars;
auto taskLoopOp = genWrapperOp<mlir::omp::TaskloopOp>(
converter, loc, taskloopClauseOps, taskloopArgs);
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-reduction.f90 b/flang/test/Lower/OpenMP/taskloop-reduction.f90
new file mode 100644
index 0000000000000..4185a927366e7
--- /dev/null
+++ b/flang/test/Lower/OpenMP/taskloop-reduction.f90
@@ -0,0 +1,30 @@
+! This test checks the lowering of the reduction clause in the taskloop construct
+! 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
+! RUN %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=45 -o - %s 2>&1 | FileCheck %s --check-prefix=CHECK-VERSION
+
+! CHECK-VERSION: error: REDUCTION clause is not allowed on directive TASKLOOP in OpenMP v4.5, try -fopenmp-version=50
+
+! CHECK-LABEL: omp.private
+! CHECK-SAME: {type = private} @[[I_PRIVATE:.*]] : i32
+
+! CHECK-LABEL: func.func @_QPtest_reduction()
+! CHECK: %[[ALLOCA_A:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "a", uniq_name = "_QFtest_reductionEa"}
+! CHECK: %[[DECLARE_A:.*]]:2 = hlfir.declare %[[ALLOCA_A]](%2) {uniq_name = "_QFtest_reductionEa"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_reductionEi"}
+! CHECK: %[[DECLARE_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFtest_reductionEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[ALLOCA_SUM_I:.*]] = fir.alloca i32 {bindc_name = "sum_i", uniq_name = "_QFtest_reductionEsum_i"}
+! CHECK: %[[DECLARE_SUM_I:.*]]:2 = hlfir.declare %[[ALLOCA_SUM_I]] {uniq_name = "_QFtest_reductionEsum_i"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+
+subroutine test_reduction
+ integer :: i, a(10), sum_i
+
+ ! CHECK: omp.taskloop
+ ! CHECK-SAME: private(@[[I_PRIVATE]] %[[DECLARE_I]]#0 -> %arg0 : !fir.ref<i32>) reduction(@add_reduction_i32 %[[DECLARE_SUM_I]]#0 -> %arg1 : !fir.ref<i32>) {
+ !$omp taskloop reduction (+:sum_i)
+ do i = 1,10
+ sum_i = sum_i + i
+ end do
+ !$omp end taskloop
+
+end subroutine
\ No newline at end of file
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 208609f64f418..0afae8a013bd6 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -1284,17 +1284,16 @@ def OMP_TaskGroup : Directive<[Spelling<"taskgroup">]> {
let category = CA_Executable;
}
def OMP_TaskLoop : Directive<[Spelling<"taskloop">]> {
- let allowedClauses = [
- VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_FirstPrivate>,
- VersionedClause<OMPC_InReduction>,
- VersionedClause<OMPC_LastPrivate>,
- VersionedClause<OMPC_Mergeable>,
- VersionedClause<OMPC_NoGroup>,
- VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_Shared>,
- VersionedClause<OMPC_Untied>,
+ let allowedClauses = [VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_InReduction>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Mergeable>,
+ VersionedClause<OMPC_NoGroup>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction, 50>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Untied>,
];
let allowedOnceClauses = [
VersionedClause<OMPC_Collapse>,
``````````
</details>
https://github.com/llvm/llvm-project/pull/166582
More information about the flang-commits
mailing list