[flang-commits] [flang] [llvm] [Flang][OpenMP] Add Lowering support for taskloop reductions (PR #166582)
Jack Styles via flang-commits
flang-commits at lists.llvm.org
Wed Nov 5 08:33:47 PST 2025
https://github.com/Stylie777 created https://github.com/llvm/llvm-project/pull/166582
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.
>From 3e135046c82c546797d966e70c430981a8a4563d Mon Sep 17 00:00:00 2001
From: Jack Styles <jack.styles at arm.com>
Date: Wed, 5 Nov 2025 14:25:07 +0000
Subject: [PATCH] [Flang][OpenMP] Add Lowering support for taskloop reductions
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.
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 20 ++++++++-----
.../Lower/OpenMP/Todo/taskloop-reduction.f90 | 13 --------
.../test/Lower/OpenMP/taskloop-reduction.f90 | 30 +++++++++++++++++++
llvm/include/llvm/Frontend/OpenMP/OMP.td | 21 +++++++------
4 files changed, 52 insertions(+), 32 deletions(-)
delete mode 100644 flang/test/Lower/OpenMP/Todo/taskloop-reduction.f90
create mode 100644 flang/test/Lower/OpenMP/taskloop-reduction.f90
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>,
More information about the flang-commits
mailing list