[flang-commits] [flang] [flang][OpenMP] Lowering for CANCEL and CANCALLATIONPOINT (PR #134248)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Thu Apr 3 06:25:09 PDT 2025
https://github.com/tblah created https://github.com/llvm/llvm-project/pull/134248
These will still hit TODOs in OpenMPToLLVMIRConversion.cpp
>From 7f1e7b7d6f4001765931234788e3348403ea097a Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Thu, 3 Apr 2025 13:04:15 +0000
Subject: [PATCH] [flang][OpenMP] Lowering for CANCEL and CANCALLATIONPOINT
These will still hit TODOs in OpenMPToLLVMIRConversion.cpp
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 33 ++++
flang/lib/Lower/OpenMP/ClauseProcessor.h | 2 +
flang/lib/Lower/OpenMP/Clauses.cpp | 19 +-
flang/lib/Lower/OpenMP/Clauses.h | 4 +-
flang/lib/Lower/OpenMP/OpenMP.cpp | 64 ++++++-
flang/test/Lower/OpenMP/cancel.f90 | 176 ++++++++++++++++++
flang/test/Lower/OpenMP/cancellationpoint.f90 | 77 ++++++++
7 files changed, 370 insertions(+), 5 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/cancel.f90
create mode 100644 flang/test/Lower/OpenMP/cancellationpoint.f90
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 12ac6b3285575..04b8f7ec5372f 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -18,6 +18,7 @@
#include "flang/Lower/PFTBuilder.h"
#include "flang/Parser/tools.h"
#include "flang/Semantics/tools.h"
+#include "llvm/Frontend/OpenMP/OMP.h.inc"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
namespace Fortran {
@@ -220,6 +221,38 @@ bool ClauseProcessor::processBind(mlir::omp::BindClauseOps &result) const {
return false;
}
+bool ClauseProcessor::processCancelDirectiveName(
+ mlir::omp::CancelDirectiveNameClauseOps &result) const {
+ using ConstructType = mlir::omp::ClauseCancellationConstructType;
+ mlir::MLIRContext *context = &converter.getMLIRContext();
+
+ ConstructType directive;
+ if (auto *clause = findUniqueClause<omp::CancellationConstructType>())
+ switch (clause->v) {
+ case llvm::omp::OMP_CANCELLATION_CONSTRUCT_Parallel:
+ directive = mlir::omp::ClauseCancellationConstructType::Parallel;
+ break;
+ case llvm::omp::OMP_CANCELLATION_CONSTRUCT_Loop:
+ directive = mlir::omp::ClauseCancellationConstructType::Loop;
+ break;
+ case llvm::omp::OMP_CANCELLATION_CONSTRUCT_Sections:
+ directive = mlir::omp::ClauseCancellationConstructType::Sections;
+ break;
+ case llvm::omp::OMP_CANCELLATION_CONSTRUCT_Taskgroup:
+ directive = mlir::omp::ClauseCancellationConstructType::Taskgroup;
+ break;
+ case llvm::omp::OMP_CANCELLATION_CONSTRUCT_None:
+ llvm_unreachable("OMP_CANCELLATION_CONSTRUCT_None");
+ break;
+ }
+ else
+ llvm_unreachable("cancel construct missing cancellation construct type");
+
+ result.cancelDirective =
+ mlir::omp::ClauseCancellationConstructTypeAttr::get(context, directive);
+ return true;
+}
+
bool ClauseProcessor::processCollapse(
mlir::Location currentLocation, lower::pft::Evaluation &eval,
mlir::omp::LoopRelatedClauseOps &result,
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 6b1f7a31c7aac..bdddeb145b496 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -56,6 +56,8 @@ class ClauseProcessor {
// 'Unique' clauses: They can appear at most once in the clause list.
bool processBare(mlir::omp::BareClauseOps &result) const;
bool processBind(mlir::omp::BindClauseOps &result) const;
+ bool processCancelDirectiveName(
+ mlir::omp::CancelDirectiveNameClauseOps &result) const;
bool
processCollapse(mlir::Location currentLocation, lower::pft::Evaluation &eval,
mlir::omp::LoopRelatedClauseOps &result,
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 5b6e099967df5..4a0105d2659f6 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -249,7 +249,6 @@ MAKE_EMPTY_CLASS(Weak, Weak);
MAKE_EMPTY_CLASS(Write, Write);
// Artificial clauses
-MAKE_EMPTY_CLASS(CancellationConstructType, CancellationConstructType);
MAKE_EMPTY_CLASS(Depobj, Depobj);
MAKE_EMPTY_CLASS(Flush, Flush);
MAKE_EMPTY_CLASS(MemoryOrder, MemoryOrder);
@@ -524,7 +523,23 @@ Bind make(const parser::OmpClause::Bind &inp,
return Bind{/*Binding=*/convert(inp.v.v)};
}
-// CancellationConstructType: empty
+CancellationConstructType
+make(const parser::OmpClause::CancellationConstructType &inp,
+ semantics::SemanticsContext &semaCtx) {
+ auto name = std::get<parser::OmpDirectiveName>(inp.v.t);
+ CLAUSET_ENUM_CONVERT( //
+ convert, llvm::omp::Directive, llvm::omp::CancellationConstructType,
+ // clang-format off
+ MS(OMPD_parallel, OMP_CANCELLATION_CONSTRUCT_Parallel)
+ MS(OMPD_do, OMP_CANCELLATION_CONSTRUCT_Loop)
+ MS(OMPD_sections, OMP_CANCELLATION_CONSTRUCT_Sections)
+ MS(OMPD_taskgroup, OMP_CANCELLATION_CONSTRUCT_Taskgroup)
+ // clang-format on
+ );
+
+ return CancellationConstructType{convert(name.v)};
+}
+
// Capture: empty
Collapse make(const parser::OmpClause::Collapse &inp,
diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h
index e0a642036a58f..d7ab21d428e32 100644
--- a/flang/lib/Lower/OpenMP/Clauses.h
+++ b/flang/lib/Lower/OpenMP/Clauses.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Frontend/OpenMP/ClauseT.h"
+#include "llvm/Frontend/OpenMP/OMP.h.inc"
#include <optional>
#include <type_traits>
@@ -306,7 +307,8 @@ using Write = tomp::clause::WriteT<TypeTy, IdTy, ExprTy>;
using tomp::type::operator==;
struct CancellationConstructType {
- using EmptyTrait = std::true_type;
+ using WrapperTrait = std::true_type;
+ llvm::omp::CancellationConstructType v;
};
struct Depobj {
using EmptyTrait = std::true_type;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index ab90b4609e855..eb4795deb5668 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1526,6 +1526,24 @@ static OpTy genWrapperOp(lower::AbstractConverter &converter,
// Code generation functions for clauses
//===----------------------------------------------------------------------===//
+static void genCancelClauses(lower::AbstractConverter &converter,
+ semantics::SemanticsContext &semaCtx,
+ const List<Clause> &clauses, mlir::Location loc,
+ mlir::omp::CancelOperands &clauseOps) {
+ ClauseProcessor cp(converter, semaCtx, clauses);
+ cp.processCancelDirectiveName(clauseOps);
+ cp.processIf(llvm::omp::Directive::OMPD_cancel, clauseOps);
+}
+
+static void
+genCancellationPointClauses(lower::AbstractConverter &converter,
+ semantics::SemanticsContext &semaCtx,
+ const List<Clause> &clauses, mlir::Location loc,
+ mlir::omp::CancellationPointOperands &clauseOps) {
+ ClauseProcessor cp(converter, semaCtx, clauses);
+ cp.processCancelDirectiveName(clauseOps);
+}
+
static void genCriticalDeclareClauses(
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
const List<Clause> &clauses, mlir::Location loc,
@@ -1843,6 +1861,31 @@ genBarrierOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
return converter.getFirOpBuilder().create<mlir::omp::BarrierOp>(loc);
}
+static mlir::omp::CancelOp genCancelOp(lower::AbstractConverter &converter,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval,
+ mlir::Location loc,
+ const ConstructQueue &queue,
+ ConstructQueue::const_iterator item) {
+ mlir::omp::CancelOperands clauseOps;
+ genCancelClauses(converter, semaCtx, item->clauses, loc, clauseOps);
+
+ return converter.getFirOpBuilder().create<mlir::omp::CancelOp>(loc,
+ clauseOps);
+}
+
+static mlir::omp::CancellationPointOp genCancellationPointOp(
+ lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const ConstructQueue &queue, ConstructQueue::const_iterator item) {
+ mlir::omp::CancellationPointOperands clauseOps;
+ genCancellationPointClauses(converter, semaCtx, item->clauses, loc,
+ clauseOps);
+
+ return converter.getFirOpBuilder().create<mlir::omp::CancellationPointOp>(
+ loc, clauseOps);
+}
+
static mlir::omp::CriticalOp
genCriticalOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
@@ -3342,7 +3385,15 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPCancelConstruct &cancelConstruct) {
- TODO(converter.getCurrentLocation(), "OpenMPCancelConstruct");
+ List<Clause> clauses = makeList(cancelConstruct.v.Clauses().v, [&](auto &&s) {
+ return makeClause(s, semaCtx);
+ });
+ mlir::Location loc = converter.genLocation(cancelConstruct.source);
+
+ ConstructQueue queue{buildConstructQueue(
+ converter.getFirOpBuilder().getModule(), semaCtx, eval,
+ cancelConstruct.source, llvm::omp::Directive::OMPD_cancel, clauses)};
+ genCancelOp(converter, semaCtx, eval, loc, queue, queue.begin());
}
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
@@ -3350,7 +3401,16 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
lower::pft::Evaluation &eval,
const parser::OpenMPCancellationPointConstruct
&cancellationPointConstruct) {
- TODO(converter.getCurrentLocation(), "OpenMPCancelConstruct");
+ List<Clause> clauses =
+ makeList(cancellationPointConstruct.v.Clauses().v,
+ [&](auto &&s) { return makeClause(s, semaCtx); });
+ mlir::Location loc = converter.genLocation(cancellationPointConstruct.source);
+
+ ConstructQueue queue{
+ buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,
+ eval, cancellationPointConstruct.source,
+ llvm::omp::Directive::OMPD_cancel, clauses)};
+ genCancellationPointOp(converter, semaCtx, eval, loc, queue, queue.begin());
}
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
diff --git a/flang/test/Lower/OpenMP/cancel.f90 b/flang/test/Lower/OpenMP/cancel.f90
new file mode 100644
index 0000000000000..fd1f110e5804c
--- /dev/null
+++ b/flang/test/Lower/OpenMP/cancel.f90
@@ -0,0 +1,176 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+subroutine cancel_parallel()
+ !$omp parallel
+ !$omp cancel parallel
+ !$omp end parallel
+end subroutine
+! CHECK-LABEL: func.func @_QPcancel_parallel() {
+! CHECK: omp.parallel {
+! CHECK: omp.cancel cancellation_construct_type(parallel)
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancel_do()
+ !$omp parallel do
+ do i = 1,100
+ !$omp cancel do
+ enddo
+ !$omp end parallel do
+end subroutine
+! CHECK-LABEL: func.func @_QPcancel_do() {
+! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFcancel_doEi"}
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFcancel_doEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: omp.parallel {
+! CHECK: %[[VAL_2:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_3:.*]] = arith.constant 100 : i32
+! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32
+! CHECK: omp.wsloop private(@_QFcancel_doEi_private_i32 %[[VAL_1]]#0 -> %[[VAL_5:.*]] : !fir.ref<i32>) {
+! CHECK: omp.loop_nest (%[[VAL_6:.*]]) : i32 = (%[[VAL_2]]) to (%[[VAL_3]]) inclusive step (%[[VAL_4]]) {
+! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5]] {uniq_name = "_QFcancel_doEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_7]]#0 : i32, !fir.ref<i32>
+! CHECK: omp.cancel cancellation_construct_type(loop)
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancel_sections()
+ !$omp sections
+ !$omp section
+ !$omp cancel sections
+ !$omp end sections
+end subroutine
+! CHECK-LABEL: func.func @_QPcancel_sections() {
+! CHECK: omp.sections {
+! CHECK: omp.section {
+! CHECK: omp.cancel cancellation_construct_type(sections)
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancel_taskgroup()
+ !$omp taskgroup
+ !$omp task
+ !$omp cancel taskgroup
+ !$omp end task
+ !$omp end taskgroup
+end subroutine
+! CHECK-LABEL: func.func @_QPcancel_taskgroup() {
+! CHECK: omp.taskgroup {
+! CHECK: omp.task {
+! CHECK: omp.cancel cancellation_construct_type(taskgroup)
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancel_parallel_if(cond)
+ logical :: cond
+ !$omp parallel
+ !$omp cancel parallel if(cond)
+ !$omp end parallel
+end subroutine
+! CHECK-LABEL: func.func @_QPcancel_parallel_if(
+! CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "cond"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFcancel_parallel_ifEcond"} : (!fir.ref<!fir.logical<4>>, !fir.dscope) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+! CHECK: omp.parallel {
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.logical<4>) -> i1
+! CHECK: omp.cancel cancellation_construct_type(parallel) if(%[[VAL_4]])
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancel_do_if(cond)
+ logical :: cond
+ !$omp parallel do
+ do i = 1,100
+ !$omp cancel do if (cond)
+ enddo
+ !$omp end parallel do
+end subroutine
+! CHECK-LABEL: func.func @_QPcancel_do_if(
+! CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "cond"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFcancel_do_ifEcond"} : (!fir.ref<!fir.logical<4>>, !fir.dscope) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+! CHECK: %[[VAL_3:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFcancel_do_ifEi"}
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = "_QFcancel_do_ifEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: omp.parallel {
+! CHECK: %[[VAL_5:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_6:.*]] = arith.constant 100 : i32
+! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32
+! CHECK: omp.wsloop private(@_QFcancel_do_ifEi_private_i32 %[[VAL_4]]#0 -> %[[VAL_8:.*]] : !fir.ref<i32>) {
+! CHECK: omp.loop_nest (%[[VAL_9:.*]]) : i32 = (%[[VAL_5]]) to (%[[VAL_6]]) inclusive step (%[[VAL_7]]) {
+! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]] {uniq_name = "_QFcancel_do_ifEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: hlfir.assign %[[VAL_9]] to %[[VAL_10]]#0 : i32, !fir.ref<i32>
+! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.logical<4>) -> i1
+! CHECK: omp.cancel cancellation_construct_type(loop) if(%[[VAL_12]])
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancel_sections_if(cond)
+ logical :: cond
+ !$omp sections
+ !$omp section
+ !$omp cancel sections if(cond)
+ !$omp end sections
+end subroutine
+! CHECK-LABEL: func.func @_QPcancel_sections_if(
+! CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "cond"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFcancel_sections_ifEcond"} : (!fir.ref<!fir.logical<4>>, !fir.dscope) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+! CHECK: omp.sections {
+! CHECK: omp.section {
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.logical<4>) -> i1
+! CHECK: omp.cancel cancellation_construct_type(sections) if(%[[VAL_4]])
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancel_taskgroup_if(cond)
+ logical :: cond
+ !$omp taskgroup
+ !$omp task
+ !$omp cancel taskgroup if(cond)
+ !$omp end task
+ !$omp end taskgroup
+end subroutine
+! CHECK-LABEL: func.func @_QPcancel_taskgroup_if(
+! CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "cond"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFcancel_taskgroup_ifEcond"} : (!fir.ref<!fir.logical<4>>, !fir.dscope) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+! CHECK: omp.taskgroup {
+! CHECK: omp.task {
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.logical<4>) -> i1
+! CHECK: omp.cancel cancellation_construct_type(taskgroup) if(%[[VAL_4]])
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
diff --git a/flang/test/Lower/OpenMP/cancellationpoint.f90 b/flang/test/Lower/OpenMP/cancellationpoint.f90
new file mode 100644
index 0000000000000..a00f8cddf3824
--- /dev/null
+++ b/flang/test/Lower/OpenMP/cancellationpoint.f90
@@ -0,0 +1,77 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+subroutine cancellationpoint_parallel()
+ !$omp parallel
+ !$omp cancellationpoint parallel
+ !$omp end parallel
+end subroutine
+! CHECK-LABEL: func.func @_QPcancellationpoint_parallel() {
+! CHECK: omp.parallel {
+! CHECK: omp.cancellation_point cancellation_construct_type(parallel)
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancellationpoint_do()
+ !$omp parallel do
+ do i = 1,100
+ !$omp cancellationpoint do
+ enddo
+ !$omp end parallel do
+end subroutine
+! CHECK-LABEL: func.func @_QPcancellationpoint_do() {
+! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFcancellationpoint_doEi"}
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFcancellationpoint_doEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: omp.parallel {
+! CHECK: %[[VAL_2:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_3:.*]] = arith.constant 100 : i32
+! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32
+! CHECK: omp.wsloop private(@_QFcancellationpoint_doEi_private_i32 %[[VAL_1]]#0 -> %[[VAL_5:.*]] : !fir.ref<i32>) {
+! CHECK: omp.loop_nest (%[[VAL_6:.*]]) : i32 = (%[[VAL_2]]) to (%[[VAL_3]]) inclusive step (%[[VAL_4]]) {
+! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5]] {uniq_name = "_QFcancellationpoint_doEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_7]]#0 : i32, !fir.ref<i32>
+! CHECK: omp.cancellation_point cancellation_construct_type(loop)
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancellationpoint_sections()
+ !$omp sections
+ !$omp section
+ !$omp cancellationpoint sections
+ !$omp end sections
+end subroutine
+! CHECK-LABEL: func.func @_QPcancellationpoint_sections() {
+! CHECK: omp.sections {
+! CHECK: omp.section {
+! CHECK: omp.cancellation_point cancellation_construct_type(sections)
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
+
+subroutine cancellationpoint_taskgroup()
+ !$omp taskgroup
+ !$omp task
+ !$omp cancellationpoint taskgroup
+ !$omp end task
+ !$omp end taskgroup
+end subroutine
+! CHECK-LABEL: func.func @_QPcancellationpoint_taskgroup() {
+! CHECK: omp.taskgroup {
+! CHECK: omp.task {
+! CHECK: omp.cancellation_point cancellation_construct_type(taskgroup)
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
More information about the flang-commits
mailing list