[flang-commits] [flang] [Flang][OpenMP] DISTRIBUTE PARALLEL DO lowering (PR #106207)
Sergio Afonso via flang-commits
flang-commits at lists.llvm.org
Thu Aug 29 03:45:12 PDT 2024
https://github.com/skatrak updated https://github.com/llvm/llvm-project/pull/106207
>From e63b7abd8a05abfd707da8a2097e1cc974ebb1f3 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <safonsof at amd.com>
Date: Tue, 27 Aug 2024 11:14:14 +0100
Subject: [PATCH] [Flang][OpenMP] DISTRIBUTE PARALLEL DO lowering
This patch adds PFT to MLIR lowering support for `distribute parallel do`
composite constructs.
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 145 +++++++---
.../Lower/OpenMP/distribute-parallel-do.f90 | 79 ++++++
flang/test/Lower/OpenMP/if-clause.f90 | 260 +++++++++++++++++-
flang/test/Lower/OpenMP/loop-compound.f90 | 44 ++-
4 files changed, 493 insertions(+), 35 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/distribute-parallel-do.f90
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 3a48b370e6e150..756e977d82906e 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -519,6 +519,11 @@ struct OpWithBodyGenInfo {
return *this;
}
+ OpWithBodyGenInfo &setGenSkeletonOnly(bool value) {
+ genSkeletonOnly = value;
+ return *this;
+ }
+
/// [inout] converter to use for the clauses.
lower::AbstractConverter &converter;
/// [in] Symbol table
@@ -538,6 +543,9 @@ struct OpWithBodyGenInfo {
/// [in] if provided, emits the op's region entry. Otherwise, an emtpy block
/// is created in the region.
GenOMPRegionEntryCBFn genRegionEntryCB = nullptr;
+ /// [in] if set to `true`, skip generating nested evaluations and dispatching
+ /// any further leaf constructs.
+ bool genSkeletonOnly = false;
};
/// Create the body (block) for an OpenMP Operation.
@@ -600,20 +608,22 @@ static void createBodyOfOp(mlir::Operation &op, const OpWithBodyGenInfo &info,
}
}
- if (ConstructQueue::const_iterator next = std::next(item);
- next != queue.end()) {
- genOMPDispatch(info.converter, info.symTable, info.semaCtx, info.eval,
- info.loc, queue, next);
- } else {
- // genFIR(Evaluation&) tries to patch up unterminated blocks, causing
- // a lot of complications for our approach if the terminator generation
- // is delayed past this point. Insert a temporary terminator here, then
- // delete it.
- firOpBuilder.setInsertionPointToEnd(&op.getRegion(0).back());
- auto *temp = lower::genOpenMPTerminator(firOpBuilder, &op, info.loc);
- firOpBuilder.setInsertionPointAfter(marker);
- genNestedEvaluations(info.converter, info.eval);
- temp->erase();
+ if (!info.genSkeletonOnly) {
+ if (ConstructQueue::const_iterator next = std::next(item);
+ next != queue.end()) {
+ genOMPDispatch(info.converter, info.symTable, info.semaCtx, info.eval,
+ info.loc, queue, next);
+ } else {
+ // genFIR(Evaluation&) tries to patch up unterminated blocks, causing
+ // a lot of complications for our approach if the terminator generation
+ // is delayed past this point. Insert a temporary terminator here, then
+ // delete it.
+ firOpBuilder.setInsertionPointToEnd(&op.getRegion(0).back());
+ auto *temp = lower::genOpenMPTerminator(firOpBuilder, &op, info.loc);
+ firOpBuilder.setInsertionPointAfter(marker);
+ genNestedEvaluations(info.converter, info.eval);
+ temp->erase();
+ }
}
// Get or create a unique exiting block from the given region, or
@@ -1445,7 +1455,8 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
const ConstructQueue &queue, ConstructQueue::const_iterator item,
mlir::omp::ParallelOperands &clauseOps,
llvm::ArrayRef<const semantics::Symbol *> reductionSyms,
- llvm::ArrayRef<mlir::Type> reductionTypes) {
+ llvm::ArrayRef<mlir::Type> reductionTypes,
+ DataSharingProcessor *dsp, bool isComposite = false) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
auto reductionCallback = [&](mlir::Operation *op) {
@@ -1457,17 +1468,17 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
OpWithBodyGenInfo(converter, symTable, semaCtx, loc, eval,
llvm::omp::Directive::OMPD_parallel)
.setClauses(&item->clauses)
- .setGenRegionEntryCb(reductionCallback);
-
- if (!enableDelayedPrivatization)
- return genOpWithBody<mlir::omp::ParallelOp>(genInfo, queue, item,
- clauseOps);
-
- DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
- lower::omp::isLastItemInQueue(item, queue),
- /*useDelayedPrivatization=*/true, &symTable);
- dsp.processStep1(&clauseOps);
+ .setGenRegionEntryCb(reductionCallback)
+ .setGenSkeletonOnly(isComposite);
+
+ if (!enableDelayedPrivatization) {
+ auto parallelOp =
+ genOpWithBody<mlir::omp::ParallelOp>(genInfo, queue, item, clauseOps);
+ parallelOp.setComposite(isComposite);
+ return parallelOp;
+ }
+ assert(dsp && "expected valid DataSharingProcessor");
auto genRegionEntryCB = [&](mlir::Operation *op) {
auto parallelOp = llvm::cast<mlir::omp::ParallelOp>(op);
@@ -1491,8 +1502,8 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
allRegionArgLocs);
llvm::SmallVector<const semantics::Symbol *> allSymbols(reductionSyms);
- allSymbols.append(dsp.getDelayedPrivSymbols().begin(),
- dsp.getDelayedPrivSymbols().end());
+ allSymbols.append(dsp->getDelayedPrivSymbols().begin(),
+ dsp->getDelayedPrivSymbols().end());
unsigned argIdx = 0;
for (const semantics::Symbol *arg : allSymbols) {
@@ -1519,8 +1530,11 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
return allSymbols;
};
- genInfo.setGenRegionEntryCb(genRegionEntryCB).setDataSharingProcessor(&dsp);
- return genOpWithBody<mlir::omp::ParallelOp>(genInfo, queue, item, clauseOps);
+ genInfo.setGenRegionEntryCb(genRegionEntryCB).setDataSharingProcessor(dsp);
+ auto parallelOp =
+ genOpWithBody<mlir::omp::ParallelOp>(genInfo, queue, item, clauseOps);
+ parallelOp.setComposite(isComposite);
+ return parallelOp;
}
/// This breaks the normal prototype of the gen*Op functions: adding the
@@ -2005,8 +2019,16 @@ static void genStandaloneParallel(lower::AbstractConverter &converter,
genParallelClauses(converter, semaCtx, stmtCtx, item->clauses, loc, clauseOps,
reductionTypes, reductionSyms);
+ std::optional<DataSharingProcessor> dsp;
+ if (enableDelayedPrivatization) {
+ dsp.emplace(converter, semaCtx, item->clauses, eval,
+ lower::omp::isLastItemInQueue(item, queue),
+ /*useDelayedPrivatization=*/true, &symTable);
+ dsp->processStep1(&clauseOps);
+ }
genParallelOp(converter, symTable, semaCtx, eval, loc, queue, item, clauseOps,
- reductionSyms, reductionTypes);
+ reductionSyms, reductionTypes,
+ enableDelayedPrivatization ? &dsp.value() : nullptr);
}
static void genStandaloneSimd(lower::AbstractConverter &converter,
@@ -2058,8 +2080,69 @@ static void genCompositeDistributeParallelDo(
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
mlir::Location loc, const ConstructQueue &queue,
ConstructQueue::const_iterator item) {
+ lower::StatementContext stmtCtx;
+
assert(std::distance(item, queue.end()) == 3 && "Invalid leaf constructs");
- TODO(loc, "Composite DISTRIBUTE PARALLEL DO");
+ ConstructQueue::const_iterator distributeItem = item;
+ ConstructQueue::const_iterator parallelItem = std::next(distributeItem);
+ ConstructQueue::const_iterator doItem = std::next(parallelItem);
+
+ // Create parent omp.parallel first.
+ mlir::omp::ParallelOperands parallelClauseOps;
+ llvm::SmallVector<const semantics::Symbol *> parallelReductionSyms;
+ llvm::SmallVector<mlir::Type> parallelReductionTypes;
+ genParallelClauses(converter, semaCtx, stmtCtx, parallelItem->clauses, loc,
+ parallelClauseOps, parallelReductionTypes,
+ parallelReductionSyms);
+
+ DataSharingProcessor dsp(converter, semaCtx, doItem->clauses, eval,
+ /*shouldCollectPreDeterminedSymbols=*/true,
+ /*useDelayedPrivatization=*/true, &symTable);
+ dsp.processStep1(¶llelClauseOps);
+
+ genParallelOp(converter, symTable, semaCtx, eval, loc, queue, parallelItem,
+ parallelClauseOps, parallelReductionSyms,
+ parallelReductionTypes, &dsp, /*isComposite=*/true);
+
+ // Clause processing.
+ mlir::omp::DistributeOperands distributeClauseOps;
+ genDistributeClauses(converter, semaCtx, stmtCtx, distributeItem->clauses,
+ loc, distributeClauseOps);
+
+ mlir::omp::WsloopOperands wsloopClauseOps;
+ llvm::SmallVector<const semantics::Symbol *> wsloopReductionSyms;
+ llvm::SmallVector<mlir::Type> wsloopReductionTypes;
+ genWsloopClauses(converter, semaCtx, stmtCtx, doItem->clauses, loc,
+ wsloopClauseOps, wsloopReductionTypes, wsloopReductionSyms);
+
+ mlir::omp::LoopNestOperands loopNestClauseOps;
+ llvm::SmallVector<const semantics::Symbol *> iv;
+ genLoopNestClauses(converter, semaCtx, eval, doItem->clauses, loc,
+ loopNestClauseOps, iv);
+
+ // Operation creation.
+ // TODO: Populate entry block arguments with private variables.
+ auto distributeOp = genWrapperOp<mlir::omp::DistributeOp>(
+ converter, loc, distributeClauseOps, /*blockArgTypes=*/{});
+ distributeOp.setComposite(/*val=*/true);
+
+ // TODO: Add private variables to entry block arguments.
+ auto wsloopOp = genWrapperOp<mlir::omp::WsloopOp>(
+ converter, loc, wsloopClauseOps, wsloopReductionTypes);
+ wsloopOp.setComposite(/*val=*/true);
+
+ // Construct wrapper entry block list and associated symbols. It is important
+ // that the symbol order and the block argument order match, so that the
+ // symbol-value bindings created are correct.
+ auto &wrapperSyms = wsloopReductionSyms;
+
+ auto wrapperArgs = llvm::to_vector(
+ llvm::concat<mlir::BlockArgument>(distributeOp.getRegion().getArguments(),
+ wsloopOp.getRegion().getArguments()));
+
+ genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, doItem,
+ loopNestClauseOps, iv, wrapperSyms, wrapperArgs,
+ llvm::omp::Directive::OMPD_distribute_parallel_do, dsp);
}
static void genCompositeDistributeParallelDoSimd(
diff --git a/flang/test/Lower/OpenMP/distribute-parallel-do.f90 b/flang/test/Lower/OpenMP/distribute-parallel-do.f90
new file mode 100644
index 00000000000000..91940acceb12e7
--- /dev/null
+++ b/flang/test/Lower/OpenMP/distribute-parallel-do.f90
@@ -0,0 +1,79 @@
+! This test checks lowering of OpenMP DISTRIBUTE PARALLEL DO composite
+! constructs.
+
+! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func.func @_QPdistribute_parallel_do_num_threads(
+subroutine distribute_parallel_do_num_threads()
+ !$omp teams
+
+ ! CHECK: omp.parallel num_threads({{.*}}) private({{.*}}) {
+ ! CHECK: omp.distribute {
+ ! CHECK-NEXT: omp.wsloop {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp distribute parallel do num_threads(10)
+ do index_ = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ !$omp end teams
+end subroutine distribute_parallel_do_num_threads
+
+! CHECK-LABEL: func.func @_QPdistribute_parallel_do_dist_schedule(
+subroutine distribute_parallel_do_dist_schedule()
+ !$omp teams
+
+ ! CHECK: omp.parallel private({{.*}}) {
+ ! CHECK: omp.distribute dist_schedule_static dist_schedule_chunk_size({{.*}}) {
+ ! CHECK-NEXT: omp.wsloop {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp distribute parallel do dist_schedule(static, 4)
+ do index_ = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ !$omp end teams
+end subroutine distribute_parallel_do_dist_schedule
+
+! CHECK-LABEL: func.func @_QPdistribute_parallel_do_ordered(
+subroutine distribute_parallel_do_ordered()
+ !$omp teams
+
+ ! CHECK: omp.parallel private({{.*}}) {
+ ! CHECK: omp.distribute {
+ ! CHECK-NEXT: omp.wsloop ordered(1) {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp distribute parallel do ordered(1)
+ do index_ = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ !$omp end teams
+end subroutine distribute_parallel_do_ordered
+
+! CHECK-LABEL: func.func @_QPdistribute_parallel_do_private(
+subroutine distribute_parallel_do_private()
+ ! CHECK: %[[INDEX_ALLOC:.*]] = fir.alloca i32
+ ! CHECK: %[[INDEX:.*]]:2 = hlfir.declare %[[INDEX_ALLOC]]
+ ! CHECK: %[[X_ALLOC:.*]] = fir.alloca i64
+ ! CHECK: %[[X:.*]]:2 = hlfir.declare %[[X_ALLOC]]
+ integer(8) :: x
+
+ ! CHECK: omp.teams {
+ !$omp teams
+
+ ! CHECK: omp.parallel private(@{{.*}} %[[X]]#0 -> %[[X_ARG:.*]] : !fir.ref<i64>,
+ ! CHECK-SAME: @{{.*}} %[[INDEX]]#0 -> %[[INDEX_ARG:.*]] : !fir.ref<i32>) {
+ ! CHECK: %[[X_PRIV:.*]]:2 = hlfir.declare %[[X_ARG]]
+ ! CHECK: %[[INDEX_PRIV:.*]]:2 = hlfir.declare %[[INDEX_ARG]]
+ ! CHECK: omp.distribute {
+ ! CHECK-NEXT: omp.wsloop {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp distribute parallel do private(x)
+ do index_ = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ !$omp end teams
+end subroutine distribute_parallel_do_private
diff --git a/flang/test/Lower/OpenMP/if-clause.f90 b/flang/test/Lower/OpenMP/if-clause.f90
index f10a6b008cddfc..fce4efc7a5c2e2 100644
--- a/flang/test/Lower/OpenMP/if-clause.f90
+++ b/flang/test/Lower/OpenMP/if-clause.f90
@@ -9,18 +9,65 @@ program main
integer :: i
! TODO When they are supported, add tests for:
- ! - DISTRIBUTE PARALLEL DO
! - DISTRIBUTE PARALLEL DO SIMD
! - PARALLEL SECTIONS
! - PARALLEL WORKSHARE
- ! - TARGET TEAMS DISTRIBUTE PARALLEL DO
! - TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD
! - TARGET UPDATE
! - TASKLOOP
! - TASKLOOP SIMD
- ! - TEAMS DISTRIBUTE PARALLEL DO
! - TEAMS DISTRIBUTE PARALLEL DO SIMD
+ ! ----------------------------------------------------------------------------
+ ! DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ !$omp teams
+
+ ! CHECK: omp.parallel
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp distribute parallel do
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp distribute parallel do if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp distribute parallel do if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ !$omp end teams
+
! ----------------------------------------------------------------------------
! DISTRIBUTE SIMD
! ----------------------------------------------------------------------------
@@ -661,6 +708,126 @@ program main
end do
!$omp end target teams distribute
+ ! ----------------------------------------------------------------------------
+ ! TARGET TEAMS DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ ! CHECK: omp.target
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.teams
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.parallel
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute parallel do
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
+ ! CHECK: omp.target
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute parallel do if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
+ ! CHECK: omp.target
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute parallel do if(target: .true.) if(teams: .false.) if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
+ ! CHECK: omp.target
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.teams
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.parallel
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute parallel do if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
+ ! CHECK: omp.target
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.parallel
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute parallel do if(teams: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
+ ! CHECK: omp.target
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.teams
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute parallel do if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
! ----------------------------------------------------------------------------
! TARGET TEAMS DISTRIBUTE SIMD
! ----------------------------------------------------------------------------
@@ -866,6 +1033,93 @@ program main
end do
!$omp end teams distribute
+ ! ----------------------------------------------------------------------------
+ ! TEAMS DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ ! CHECK: omp.teams
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.parallel
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute parallel do
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do
+
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute parallel do if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do
+
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute parallel do if(teams: .true.) if(parallel: .false.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do
+
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.parallel
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute parallel do if(teams: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do
+
+ ! CHECK: omp.teams
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute parallel do if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do
+
! ----------------------------------------------------------------------------
! TEAMS DISTRIBUTE SIMD
! ----------------------------------------------------------------------------
diff --git a/flang/test/Lower/OpenMP/loop-compound.f90 b/flang/test/Lower/OpenMP/loop-compound.f90
index bbdfcb8d04dae2..fb61621e10f0ac 100644
--- a/flang/test/Lower/OpenMP/loop-compound.f90
+++ b/flang/test/Lower/OpenMP/loop-compound.f90
@@ -9,13 +9,28 @@ program main
! TODO When composite constructs are supported add:
! - DISTRIBUTE PARALLEL DO SIMD
- ! - DISTRIBUTE PARALLEL DO
! - TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD
! - TARGET TEAMS DISTRIBUTE PARALLEL DO
! - TASKLOOP SIMD
! - TEAMS DISTRIBUTE PARALLEL DO SIMD
! - TEAMS DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ ! DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ !$omp teams
+
+ ! CHECK: omp.parallel
+ ! CHECK: omp.distribute
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp distribute parallel do
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ !$omp end teams
+
! ----------------------------------------------------------------------------
! DISTRIBUTE SIMD
! ----------------------------------------------------------------------------
@@ -113,6 +128,20 @@ program main
end do
!$omp end target teams distribute
+ ! ----------------------------------------------------------------------------
+ ! TARGET TEAMS DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ ! CHECK: omp.target
+ ! CHECK: omp.teams
+ ! CHECK: omp.parallel
+ ! CHECK: omp.distribute
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute parallel do
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
! ----------------------------------------------------------------------------
! TARGET TEAMS DISTRIBUTE SIMD
! ----------------------------------------------------------------------------
@@ -137,6 +166,19 @@ program main
end do
!$omp end teams distribute
+ ! ----------------------------------------------------------------------------
+ ! TEAMS DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ ! CHECK: omp.teams
+ ! CHECK: omp.parallel
+ ! CHECK: omp.distribute
+ ! CHECK-NEXT: omp.wsloop
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute parallel do
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do
+
! ----------------------------------------------------------------------------
! TEAMS DISTRIBUTE SIMD
! ----------------------------------------------------------------------------
More information about the flang-commits
mailing list