diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1805,6 +1805,7 @@ CHECK_SIMPLE_CLAUSE(Bind, OMPC_bind) CHECK_SIMPLE_CLAUSE(Align, OMPC_align) CHECK_SIMPLE_CLAUSE(Compare, OMPC_compare) +CHECK_SIMPLE_CLAUSE(CancelConstruct, OMPC_cancel_construct) CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize) CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks) diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -163,6 +163,25 @@ ]; } +def OMP_CANCEL_CONSTRUCT_Parallel : ClauseVal<"parallel", 1, 1> {} +def OMP_CANCEL_CONSTRUCT_Loop : ClauseVal<"loop", 2, 1> {} +def OMP_CANCEL_CONSTRUCT_Sections : ClauseVal<"sections", 3, 1> {} +def OMP_CANCEL_CONSTRUCT_Taskgroup : ClauseVal<"taskgroup", 4, 1> {} +def OMP_CANCEL_CONSTRUCT_None : ClauseVal<"none", 5, 0> { + let isDefault = 1; +} + +def OMPC_CancelConstruct : Clause<"cancel_construct"> { + let enumClauseValue = "CancelConstructKind"; + let allowedClauseValues = [ + OMP_CANCEL_CONSTRUCT_Parallel, + OMP_CANCEL_CONSTRUCT_Loop, + OMP_CANCEL_CONSTRUCT_Sections, + OMP_CANCEL_CONSTRUCT_Taskgroup, + OMP_CANCEL_CONSTRUCT_None + ]; +} + def OMPC_Ordered : Clause<"ordered"> { let clangClass = "OMPOrderedClause"; let flangClass = "ScalarIntConstantExpr"; diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -997,6 +997,38 @@ }]; } +//===----------------------------------------------------------------------===// +// 2.18.1 Cancel Construct +//===----------------------------------------------------------------------===// +def CancelOp : OpenMP_Op<"cancel"> { + let summary = "cancel directive"; + let description = [{ + The cancel construct activates cancellation of the innermost enclosing + region of the type specified. + }]; + let arguments = (ins CancelConstructKindAttr:$cancel_construct_val, + Optional:$if_expr); + let assemblyFormat = [{ `cancel_construct` `(` + custom($cancel_construct_val) `)` + ( `if` `(` $if_expr^ `)` )? attr-dict}]; +} + +//===----------------------------------------------------------------------===// +// 2.18.2 Cancellation Point Construct +//===----------------------------------------------------------------------===// +def CancellationPointOp : OpenMP_Op<"cancellationpoint"> { + let summary = "cancellation point directive"; + let description = [{ + The cancellation point construct introduces a user-defined cancellation + point at which implicit or explicit tasks check if cancellation of the + innermost enclosing region of the type specified has been activated. + }]; + let arguments = (ins CancelConstructKindAttr:$cancel_construct_val); + let assemblyFormat = [{ `cancel_construct` `(` + custom($cancel_construct_val) `)` + attr-dict}]; +} + //===----------------------------------------------------------------------===// // 2.19.5.7 declare reduction Directive //===----------------------------------------------------------------------===// diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir --- a/mlir/test/Dialect/OpenMP/ops.mlir +++ b/mlir/test/Dialect/OpenMP/ops.mlir @@ -1011,4 +1011,29 @@ return } +func @omp_cancel(%if_cond : i1) -> () { + // Test with optional operand; if_expr. + // CHECK: omp.cancel cancel_construct(parallel) if(%{{.*}}) + omp.cancel cancel_construct(parallel) if(%if_cond) + // CHECK: omp.cancel cancel_construct(loop) + omp.cancel cancel_construct(loop) + // CHECK: omp.cancel cancel_construct(sections) + omp.cancel cancel_construct(sections) + // CHECK: omp.cancel cancel_construct(taskgroup) + omp.cancel cancel_construct(taskgroup) + return +} + +func @omp_cancellationpoint() -> () { + // CHECK: omp.cancellationpoint cancel_construct(parallel) + omp.cancellationpoint cancel_construct(parallel) + // CHECK: omp.cancellationpoint cancel_construct(loop) + omp.cancellationpoint cancel_construct(loop) + // CHECK: omp.cancellationpoint cancel_construct(sections) + omp.cancellationpoint cancel_construct(sections) + // CHECK: omp.cancellationpoint cancel_construct(taskgroup) + omp.cancellationpoint cancel_construct(taskgroup) + return +} + llvm.mlir.global internal @_QFsubEx() : i32