-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[OMPIRBuilder] CANCEL IF(FALSE) is still a cancellation point #170095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
From OpenMP 4.0: > When an if clause is present on a cancel construct and the if expression > evaluates to false, the cancel construct does not activate cancellation. > The cancellation point associated with the cancel construct is always > encountered regardless of the value of the if expression. This wording is retained unmodified in OpenMP 6.0. This re-opens the already approved PR llvm#164587, which was closed by accident. The only changes are a rebase.
|
@llvm/pr-subscribers-mlir @llvm/pr-subscribers-flang-openmp Author: Tom Eccles (tblah) ChangesFrom OpenMP 4.0: > When an if clause is present on a cancel construct and the if expression This wording is retained unmodified in OpenMP 6.0. This re-opens the already approved PR #164587, which was closed by accident. The only changes are a rebase. Full diff: https://github.com/llvm/llvm-project/pull/170095.diff 4 Files Affected:
diff --git a/clang/test/OpenMP/cancel_codegen.cpp b/clang/test/OpenMP/cancel_codegen.cpp
index 6090a91b6a3d9..600aae211087a 100644
--- a/clang/test/OpenMP/cancel_codegen.cpp
+++ b/clang/test/OpenMP/cancel_codegen.cpp
@@ -774,8 +774,8 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM12]])
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_AFTER:%.*]]
// CHECK3: omp_section_loop.after:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_PREHEADER13:%.*]]
-// CHECK3: omp_section_loop.preheader13:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_PREHEADER16:%.*]]
+// CHECK3: omp_section_loop.preheader16:
// CHECK3-NEXT: store i32 0, ptr [[P_LOWERBOUND29]], align 4
// CHECK3-NEXT: store i32 1, ptr [[P_UPPERBOUND30]], align 4
// CHECK3-NEXT: store i32 1, ptr [[P_STRIDE31]], align 4
@@ -785,52 +785,52 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[P_UPPERBOUND30]], align 4
// CHECK3-NEXT: [[TMP11:%.*]] = sub i32 [[TMP10]], [[TMP9]]
// CHECK3-NEXT: [[TMP12:%.*]] = add i32 [[TMP11]], 1
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_HEADER14:%.*]]
-// CHECK3: omp_section_loop.header14:
-// CHECK3-NEXT: [[OMP_SECTION_LOOP_IV20:%.*]] = phi i32 [ 0, [[OMP_SECTION_LOOP_PREHEADER13]] ], [ [[OMP_SECTION_LOOP_NEXT22:%.*]], [[OMP_SECTION_LOOP_INC17:%.*]] ]
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_COND15:%.*]]
-// CHECK3: omp_section_loop.cond15:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_HEADER17:%.*]]
+// CHECK3: omp_section_loop.header17:
+// CHECK3-NEXT: [[OMP_SECTION_LOOP_IV20:%.*]] = phi i32 [ 0, [[OMP_SECTION_LOOP_PREHEADER16]] ], [ [[OMP_SECTION_LOOP_NEXT22:%.*]], [[OMP_SECTION_LOOP_INC17:%.*]] ]
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_COND18:%.*]]
+// CHECK3: omp_section_loop.cond18:
// CHECK3-NEXT: [[OMP_SECTION_LOOP_CMP21:%.*]] = icmp ult i32 [[OMP_SECTION_LOOP_IV20]], [[TMP12]]
-// CHECK3-NEXT: br i1 [[OMP_SECTION_LOOP_CMP21]], label [[OMP_SECTION_LOOP_BODY16:%.*]], label [[OMP_SECTION_LOOP_EXIT18:%.*]]
-// CHECK3: omp_section_loop.body16:
+// CHECK3-NEXT: br i1 [[OMP_SECTION_LOOP_CMP21]], label [[OMP_SECTION_LOOP_BODY19:%.*]], label [[OMP_SECTION_LOOP_EXIT21:%.*]]
+// CHECK3: omp_section_loop.body19:
// CHECK3-NEXT: [[TMP13:%.*]] = add i32 [[OMP_SECTION_LOOP_IV20]], [[TMP9]]
// CHECK3-NEXT: [[TMP14:%.*]] = mul i32 [[TMP13]], 1
// CHECK3-NEXT: [[TMP15:%.*]] = add i32 [[TMP14]], 0
// CHECK3-NEXT: switch i32 [[TMP15]], label [[OMP_SECTION_LOOP_BODY16_SECTIONS_AFTER:%.*]] [
-// CHECK3-NEXT: i32 0, label [[OMP_SECTION_LOOP_BODY_CASE23:%.*]]
-// CHECK3-NEXT: i32 1, label [[OMP_SECTION_LOOP_BODY_CASE25:%.*]]
+// CHECK3-NEXT: i32 0, label [[OMP_SECTION_LOOP_BODY_CASE26:%.*]]
+// CHECK3-NEXT: i32 1, label [[OMP_SECTION_LOOP_BODY_CASE29:%.*]]
// CHECK3-NEXT: ]
-// CHECK3: omp_section_loop.body.case23:
+// CHECK3: omp_section_loop.body.case26:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM24:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancel(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM24]], i32 3)
// CHECK3-NEXT: [[TMP17:%.*]] = icmp eq i32 [[TMP16]], 0
-// CHECK3-NEXT: br i1 [[TMP17]], label [[OMP_SECTION_LOOP_BODY_CASE23_SPLIT:%.*]], label [[OMP_SECTION_LOOP_BODY_CASE23_CNCL:%.*]]
-// CHECK3: omp_section_loop.body.case23.split:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE23_SECTION_AFTER:%.*]]
-// CHECK3: omp_section_loop.body.case23.section.after:
+// CHECK3-NEXT: br i1 [[TMP17]], label [[OMP_SECTION_LOOP_BODY_CASE26_SPLIT:%.*]], label [[OMP_SECTION_LOOP_BODY_CASE26_CNCL:%.*]]
+// CHECK3: omp_section_loop.body.case26.split:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE26_SECTION_AFTER:%.*]]
+// CHECK3: omp_section_loop.body.case26.section.after:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY16_SECTIONS_AFTER]]
-// CHECK3: omp_section_loop.body.case26:
+// CHECK3: omp_section_loop.body.case29:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM27:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__kmpc_cancel(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM27]], i32 3)
// CHECK3-NEXT: [[TMP19:%.*]] = icmp eq i32 [[TMP18]], 0
-// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_SECTION_LOOP_BODY_CASE25_SPLIT:%.*]], label [[OMP_SECTION_LOOP_BODY_CASE25_CNCL:%.*]]
-// CHECK3: omp_section_loop.body.case26.split:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE25_SECTION_AFTER26:%.*]]
-// CHECK3: omp_section_loop.body.case26.section.after27:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE25_SECTION_AFTER:%.*]]
-// CHECK3: omp_section_loop.body.case26.section.after:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY16_SECTIONS_AFTER]]
-// CHECK3: omp_section_loop.body16.sections.after:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_INC17]]
-// CHECK3: omp_section_loop.inc17:
+// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_SECTION_LOOP_BODY_CASE29_SPLIT:%.*]], label [[OMP_SECTION_LOOP_BODY_CASE29_CNCL:%.*]]
+// CHECK3: omp_section_loop.body.case29.split:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE25_SECTION_AFTER29:%.*]]
+// CHECK3: omp_section_loop.body.case29.section.after30:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE29_SECTION_AFTER:%.*]]
+// CHECK3: omp_section_loop.body.case29.section.after:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY19_SECTIONS_AFTER:.*]]
+// CHECK3: omp_section_loop.body19.sections.after:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_INC20:.*]]
+// CHECK3: omp_section_loop.inc20:
// CHECK3-NEXT: [[OMP_SECTION_LOOP_NEXT22]] = add nuw i32 [[OMP_SECTION_LOOP_IV20]], 1
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_HEADER14]]
-// CHECK3: omp_section_loop.exit18:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_HEADER17]]
+// CHECK3: omp_section_loop.exit21:
// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM32]])
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM33:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM33]])
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_AFTER19:%.*]]
-// CHECK3: omp_section_loop.after19:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_AFTER22:%.*]]
+// CHECK3: omp_section_loop.after22:
// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARGC_ADDR]], align 4
// CHECK3-NEXT: store i32 [[TMP20]], ptr [[DOTCAPTURE_EXPR_]], align 4
// CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
@@ -887,11 +887,11 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: .cancel.exit:
// CHECK3-NEXT: br label [[CANCEL_EXIT:%.*]]
// CHECK3: omp_section_loop.body.case.cncl:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT]]
-// CHECK3: omp_section_loop.body.case23.cncl:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT18]]
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT:.*]]
// CHECK3: omp_section_loop.body.case26.cncl:
-// CHECK3-NEXT: br label [[OMP_REGION_FINALIZE:.*]]
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT18:.*]]
+// CHECK3: omp_section_loop.body.case29.cncl:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT21:.*]]
// CHECK3: .cancel.continue:
// CHECK3-NEXT: br label [[OMP_IF_END:%.*]]
// CHECK3: omp_if.else:
@@ -950,8 +950,17 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: [[TOBOOL:%.*]] = fcmp une float [[TMP2]], 0.000000e+00
// CHECK3-NEXT: br i1 [[TOBOOL]], label [[TMP14:%.*]], label [[TMP3:%.*]]
// CHECK3: 3:
-// CHECK3-NEXT: br label [[TMP4:%.*]]
-// CHECK3: 4:
+// CHECK3-NEXT: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK3-NEXT: %[[CANCEL_POINT:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 1)
+// CHECK3-NEXT: %[[COND:.*]] = icmp eq i32 %[[CANCEL_POINT]], 0
+// CHECK3-NEXT: br i1 %[[COND]], label %[[SPLIT:.*]], label %[[CNCL:.*]]
+// CHECK3: .cncl:
+// CHECK3-NEXT: br label %[[FINI:.*]]
+// CHECK3: .fini:
+// CHECK3-NEXT: br label %[[EXIT_STUB:omp.par.exit.exitStub]]
+// CHECK3: .split:
+// CHECK3-NEXT: br label [[TMP6:%.*]]
+// CHECK3: 6:
// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[LOADGEP_ARGC_ADDR]], align 4
// CHECK3-NEXT: [[CONV:%.*]] = trunc i32 [[TMP5]] to i8
// CHECK3-NEXT: [[TMP6:%.*]] = load ptr, ptr [[LOADGEP_ARGV_ADDR]], align 8
@@ -963,10 +972,8 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: [[TMP8:%.*]] = call i32 @__kmpc_cancel_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM4]])
// CHECK3-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
// CHECK3-NEXT: br i1 [[TMP9]], label [[DOTCONT:%.*]], label [[DOTCNCL5:%.*]]
-// CHECK3: .cncl4:
-// CHECK3-NEXT: br label [[FINI:%.*]]
-// CHECK3: .fini
-// CHECK3-NEXT: br label %[[EXIT_STUB:omp.par.exit.exitStub]]
+// CHECK3: .cncl7:
+// CHECK3-NEXT: br label %[[FINI]]
// CHECK3: .cont:
// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[LOADGEP_ARGC_ADDR]], align 4
// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[LOADGEP_ARGV_ADDR]], align 8
@@ -982,16 +989,16 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: omp.par.region.parallel.after:
// CHECK3-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
// CHECK3: omp.par.pre_finalize:
-// CHECK3-NEXT: br label [[FINI]]
-// CHECK3: 14:
+// CHECK3-NEXT: br label %[[FINI]]
+// CHECK3: 16:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_cancel(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM1]], i32 1)
// CHECK3-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0
// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTSPLIT:%.*]], label [[DOTCNCL:%.*]]
-// CHECK3: .cncl:
-// CHECK3-NEXT: br label [[FINI]]
-// CHECK3: .split:
-// CHECK3-NEXT: br label [[TMP4]]
+// CHECK3: .cncl4:
+// CHECK3-NEXT: br label %[[FINI]]
+// CHECK3: .split3:
+// CHECK3-NEXT: br label {{.+}}
// CHECK3: omp.par.exit.exitStub:
// CHECK3-NEXT: ret void
//
@@ -1160,7 +1167,7 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: .omp.sections.case2.split:
// CHECK3-NEXT: br label [[DOTOMP_SECTIONS_CASE2_SECTION_AFTER:%.*]]
// CHECK3: .omp.sections.case2.section.after:
-// CHECK3-NEXT: br label [[OMP_REGION_FINALIZE]]
+// CHECK3-NEXT: br label [[OMP_REGION_FINALIZE:.*]]
// CHECK3: omp_region.finalize:
// CHECK3-NEXT: br label [[OMP_SECTIONS_EXIT:.*]]
// CHECK3: .omp.sections.case2.cncl:
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 0d196be2ee696..0c0caf80d2573 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -1149,8 +1149,20 @@ OpenMPIRBuilder::createCancel(const LocationDescription &Loc,
auto *UI = Builder.CreateUnreachable();
Instruction *ThenTI = UI, *ElseTI = nullptr;
- if (IfCondition)
+ if (IfCondition) {
SplitBlockAndInsertIfThenElse(IfCondition, UI, &ThenTI, &ElseTI);
+
+ // Even if the if condition evaluates to false, this should count as a
+ // cancellation point
+ Builder.SetInsertPoint(ElseTI);
+ auto ElseIP = Builder.saveIP();
+
+ InsertPointOrErrorTy IPOrErr = createCancellationPoint(
+ LocationDescription{ElseIP, Loc.DL}, CanceledDirective);
+ if (!IPOrErr)
+ return IPOrErr;
+ }
+
Builder.SetInsertPoint(ThenTI);
Value *CancelKind = nullptr;
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
index dab0a46eeb3bc..4595590a083d3 100644
--- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -490,8 +490,8 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelIfCond) {
OMPBuilder.createCancel(Loc, Builder.getTrue(), OMPD_parallel));
Builder.restoreIP(NewIP);
EXPECT_FALSE(M->global_empty());
- EXPECT_EQ(M->size(), 3U);
- EXPECT_EQ(F->size(), 8U);
+ EXPECT_EQ(M->size(), 4U);
+ EXPECT_EQ(F->size(), 10U);
EXPECT_EQ(BB->size(), 1U);
ASSERT_TRUE(isa<BranchInst>(BB->getTerminator()));
ASSERT_EQ(BB->getTerminator()->getNumSuccessors(), 2U);
diff --git a/mlir/test/Target/LLVMIR/openmp-cancel.mlir b/mlir/test/Target/LLVMIR/openmp-cancel.mlir
index 5e20b8793f499..a6911f80d43b7 100644
--- a/mlir/test/Target/LLVMIR/openmp-cancel.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-cancel.mlir
@@ -60,28 +60,35 @@ llvm.func @cancel_parallel_if(%arg0 : i1) {
// CHECK: omp.par.region: ; preds = %[[VAL_17]]
// CHECK: br label %[[VAL_20:.*]]
// CHECK: omp.par.region1: ; preds = %[[VAL_19]]
-// CHECK: br i1 %[[VAL_16]], label %[[VAL_21:.*]], label %[[VAL_22:.*]]
+// CHECK: br i1 %[[VAL_16]], label %[[SPLIT:.*]], label %[[VAL_22:.*]]
// CHECK: 3: ; preds = %[[VAL_20]]
-// CHECK: br label %[[VAL_23:.*]]
-// CHECK: 4: ; preds = %[[VAL_22]], %[[VAL_24:.*]]
-// CHECK: br label %[[VAL_25:.*]]
-// CHECK: omp.region.cont: ; preds = %[[VAL_23]]
-// CHECK: br label %[[VAL_26:.*]]
-// CHECK: omp.par.pre_finalize: ; preds = %[[VAL_25]]
-// CHECK: br label %[[VAL_27:.*]]
+// CHECK: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK: %[[NOT_CANCELLED:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 1)
+// CHECK: %[[COND:.*]] = icmp eq i32 %[[NOT_CANCELLED]], 0
+// CHECK: br i1 %[[COND]], label %[[VAL_23:.*]], label %[[CNCL:.*]]
+// CHECK: .cncl:
+// CHECK: br label %[[FINI:.*]]
// CHECK: .fini:
// CHECK: %[[VAL_32:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
// CHECK: %[[VAL_33:.*]] = call i32 @__kmpc_cancel_barrier(ptr @2, i32 %[[VAL_32]])
// CHECK: br label %[[EXIT_STUB:.*]]
-// CHECK: 6: ; preds = %[[VAL_20]]
+// CHECK: .split:
+// CHECK: br label %[[SEVEN:.*]]
+// CHECK: 7:
+// CHECK: br label %[[VAL_25:.*]]
+// CHECK: omp.region.cont:
+// CHECK: br label %[[VAL_26:.*]]
+// CHECK: omp.par.pre_finalize: ; preds = %[[VAL_25]]
+// CHECK: br label %[[VAL_27:.*]]
+// CHECK: 8: ; preds = %[[VAL_20]]
// CHECK: %[[VAL_28:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
// CHECK: %[[VAL_29:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_28]], i32 1)
// CHECK: %[[VAL_30:.*]] = icmp eq i32 %[[VAL_29]], 0
-// CHECK: br i1 %[[VAL_30]], label %[[VAL_24]], label %[[VAL_31:.*]]
-// CHECK: .cncl: ; preds = %[[VAL_21]]
-// CHECK: br label %[[VAL_27]]
-// CHECK: .split: ; preds = %[[VAL_21]]
-// CHECK: br label %[[VAL_23]]
+// CHECK: br i1 %[[VAL_30]], label %[[SPLIT5:.*]], label %[[VAL_31:.*]]
+// CHECK: .cncl{{.*}}:
+// CHECK: br label %[[FINI]]
+// CHECK: .split{{.*}}:
+// CHECK: br label %[[SEVEN]]
// CHECK: omp.par.exit.exitStub:
// CHECK: ret void
@@ -136,11 +143,16 @@ llvm.func @cancel_sections_if(%cond : i1) {
// CHECK: %[[VAL_30:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_29]], i32 3)
// CHECK: %[[VAL_31:.*]] = icmp eq i32 %[[VAL_30]], 0
// CHECK: br i1 %[[VAL_31]], label %[[VAL_32:.*]], label %[[VAL_33:.*]]
-// CHECK: .split: ; preds = %[[VAL_27]]
+// CHECK: .split{{.*}}: ; preds = %[[VAL_27]]
// CHECK: br label %[[VAL_34:.*]]
// CHECK: 12: ; preds = %[[VAL_25]]
+// CHECK: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK: %[[CANCEL_POINT:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 3)
+// CHECK: %[[COND:.*]] = icmp eq i32 %13, 0
+// CHECK: br i1 %[[COND]], label %[[SPLIT:.*]], label %[[CNCL:.*]]
+// CHECK: .split{{.*}}:
// CHECK: br label %[[VAL_34]]
-// CHECK: 13: ; preds = %[[VAL_28]], %[[VAL_32]]
+// CHECK: 15:
// CHECK: br label %[[VAL_35:.*]]
// CHECK: omp.region.cont: ; preds = %[[VAL_34]]
// CHECK: br label %[[VAL_23]]
@@ -156,8 +168,10 @@ llvm.func @cancel_sections_if(%cond : i1) {
// CHECK: br label %[[VAL_37:.*]]
// CHECK: omp_section_loop.after: ; preds = %[[VAL_19]]
// CHECK: ret void
-// CHECK: .cncl: ; preds = %[[VAL_27]]
-// CHECK: br label %[[VAL_19]]
+// CHECK: .cncl:
+// CHECK: br label %[[OMP_SECTION_LOOP_EXIT:.*]]
+// CHECK: .cncl{{.*}}:
+// CHECK: br label %[[OMP_SECTION_LOOP_EXIT:.*]]
llvm.func @cancel_wsloop_if(%lb : i32, %ub : i32, %step : i32, %cond : i1) {
omp.wsloop {
@@ -223,11 +237,16 @@ llvm.func @cancel_wsloop_if(%lb : i32, %ub : i32, %step : i32, %cond : i1) {
// CHECK: %[[VAL_47:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_46]], i32 2)
// CHECK: %[[VAL_48:.*]] = icmp eq i32 %[[VAL_47]], 0
// CHECK: br i1 %[[VAL_48]], label %[[VAL_49:.*]], label %[[VAL_50:.*]]
-// CHECK: .split: ; preds = %[[VAL_44]]
+// CHECK: .split{{.*}}:
// CHECK: br label %[[VAL_51:.*]]
-// CHECK: 28: ; preds = %[[VAL_42]]
+// CHECK: 28:
+// CHECK: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK: %[[CANCEL_POINT:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 2)
+// CHECK: %[[COND:.*]] = icmp eq i32 %[[CANCEL_POINT]], 0
+// CHECK: br i1 %[[COND]], label %[[SPLIT3:.*]], label %[[CNCL4:.*]]
+// CHECK: .split{{.*}}:
// CHECK: br label %[[VAL_51]]
-// CHECK: 29: ; preds = %[[VAL_45]], %[[VAL_49]]
+// CHECK: 31:
// CHECK: br label %[[VAL_52:.*]]
// CHECK: omp.region.cont1: ; preds = %[[VAL_51]]
// CHECK: br label %[[VAL_32]]
@@ -243,8 +262,12 @@ llvm.func @cancel_wsloop_if(%lb : i32, %ub : i32, %step : i32, %cond : i1) {
// CHECK: br label %[[VAL_55:.*]]
// CHECK: omp.region.cont: ; preds = %[[VAL_54]]
// CHECK: ret void
-// CHECK: .cncl: ; preds = %[[VAL_44]]
-// CHECK: br label %[[VAL_38]]
+// CHECK: .cncl{{.*}}:
+// CHECK: br label %[[FINI:.*]]
+// CHECK: .fini:
+// CHECK: br label %[[OMP_LOOP_EXIT:.*]]
+// CHECK: .cncl{{.*}}:
+// CHECK: br label %[[FINI:.*]]
omp.private {type = firstprivate} @i32_priv : i32 copy {
^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):
|
|
@llvm/pr-subscribers-mlir-llvm Author: Tom Eccles (tblah) ChangesFrom OpenMP 4.0: > When an if clause is present on a cancel construct and the if expression This wording is retained unmodified in OpenMP 6.0. This re-opens the already approved PR #164587, which was closed by accident. The only changes are a rebase. Full diff: https://github.com/llvm/llvm-project/pull/170095.diff 4 Files Affected:
diff --git a/clang/test/OpenMP/cancel_codegen.cpp b/clang/test/OpenMP/cancel_codegen.cpp
index 6090a91b6a3d9..600aae211087a 100644
--- a/clang/test/OpenMP/cancel_codegen.cpp
+++ b/clang/test/OpenMP/cancel_codegen.cpp
@@ -774,8 +774,8 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM12]])
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_AFTER:%.*]]
// CHECK3: omp_section_loop.after:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_PREHEADER13:%.*]]
-// CHECK3: omp_section_loop.preheader13:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_PREHEADER16:%.*]]
+// CHECK3: omp_section_loop.preheader16:
// CHECK3-NEXT: store i32 0, ptr [[P_LOWERBOUND29]], align 4
// CHECK3-NEXT: store i32 1, ptr [[P_UPPERBOUND30]], align 4
// CHECK3-NEXT: store i32 1, ptr [[P_STRIDE31]], align 4
@@ -785,52 +785,52 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[P_UPPERBOUND30]], align 4
// CHECK3-NEXT: [[TMP11:%.*]] = sub i32 [[TMP10]], [[TMP9]]
// CHECK3-NEXT: [[TMP12:%.*]] = add i32 [[TMP11]], 1
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_HEADER14:%.*]]
-// CHECK3: omp_section_loop.header14:
-// CHECK3-NEXT: [[OMP_SECTION_LOOP_IV20:%.*]] = phi i32 [ 0, [[OMP_SECTION_LOOP_PREHEADER13]] ], [ [[OMP_SECTION_LOOP_NEXT22:%.*]], [[OMP_SECTION_LOOP_INC17:%.*]] ]
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_COND15:%.*]]
-// CHECK3: omp_section_loop.cond15:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_HEADER17:%.*]]
+// CHECK3: omp_section_loop.header17:
+// CHECK3-NEXT: [[OMP_SECTION_LOOP_IV20:%.*]] = phi i32 [ 0, [[OMP_SECTION_LOOP_PREHEADER16]] ], [ [[OMP_SECTION_LOOP_NEXT22:%.*]], [[OMP_SECTION_LOOP_INC17:%.*]] ]
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_COND18:%.*]]
+// CHECK3: omp_section_loop.cond18:
// CHECK3-NEXT: [[OMP_SECTION_LOOP_CMP21:%.*]] = icmp ult i32 [[OMP_SECTION_LOOP_IV20]], [[TMP12]]
-// CHECK3-NEXT: br i1 [[OMP_SECTION_LOOP_CMP21]], label [[OMP_SECTION_LOOP_BODY16:%.*]], label [[OMP_SECTION_LOOP_EXIT18:%.*]]
-// CHECK3: omp_section_loop.body16:
+// CHECK3-NEXT: br i1 [[OMP_SECTION_LOOP_CMP21]], label [[OMP_SECTION_LOOP_BODY19:%.*]], label [[OMP_SECTION_LOOP_EXIT21:%.*]]
+// CHECK3: omp_section_loop.body19:
// CHECK3-NEXT: [[TMP13:%.*]] = add i32 [[OMP_SECTION_LOOP_IV20]], [[TMP9]]
// CHECK3-NEXT: [[TMP14:%.*]] = mul i32 [[TMP13]], 1
// CHECK3-NEXT: [[TMP15:%.*]] = add i32 [[TMP14]], 0
// CHECK3-NEXT: switch i32 [[TMP15]], label [[OMP_SECTION_LOOP_BODY16_SECTIONS_AFTER:%.*]] [
-// CHECK3-NEXT: i32 0, label [[OMP_SECTION_LOOP_BODY_CASE23:%.*]]
-// CHECK3-NEXT: i32 1, label [[OMP_SECTION_LOOP_BODY_CASE25:%.*]]
+// CHECK3-NEXT: i32 0, label [[OMP_SECTION_LOOP_BODY_CASE26:%.*]]
+// CHECK3-NEXT: i32 1, label [[OMP_SECTION_LOOP_BODY_CASE29:%.*]]
// CHECK3-NEXT: ]
-// CHECK3: omp_section_loop.body.case23:
+// CHECK3: omp_section_loop.body.case26:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM24:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancel(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM24]], i32 3)
// CHECK3-NEXT: [[TMP17:%.*]] = icmp eq i32 [[TMP16]], 0
-// CHECK3-NEXT: br i1 [[TMP17]], label [[OMP_SECTION_LOOP_BODY_CASE23_SPLIT:%.*]], label [[OMP_SECTION_LOOP_BODY_CASE23_CNCL:%.*]]
-// CHECK3: omp_section_loop.body.case23.split:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE23_SECTION_AFTER:%.*]]
-// CHECK3: omp_section_loop.body.case23.section.after:
+// CHECK3-NEXT: br i1 [[TMP17]], label [[OMP_SECTION_LOOP_BODY_CASE26_SPLIT:%.*]], label [[OMP_SECTION_LOOP_BODY_CASE26_CNCL:%.*]]
+// CHECK3: omp_section_loop.body.case26.split:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE26_SECTION_AFTER:%.*]]
+// CHECK3: omp_section_loop.body.case26.section.after:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY16_SECTIONS_AFTER]]
-// CHECK3: omp_section_loop.body.case26:
+// CHECK3: omp_section_loop.body.case29:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM27:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__kmpc_cancel(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM27]], i32 3)
// CHECK3-NEXT: [[TMP19:%.*]] = icmp eq i32 [[TMP18]], 0
-// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_SECTION_LOOP_BODY_CASE25_SPLIT:%.*]], label [[OMP_SECTION_LOOP_BODY_CASE25_CNCL:%.*]]
-// CHECK3: omp_section_loop.body.case26.split:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE25_SECTION_AFTER26:%.*]]
-// CHECK3: omp_section_loop.body.case26.section.after27:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE25_SECTION_AFTER:%.*]]
-// CHECK3: omp_section_loop.body.case26.section.after:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY16_SECTIONS_AFTER]]
-// CHECK3: omp_section_loop.body16.sections.after:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_INC17]]
-// CHECK3: omp_section_loop.inc17:
+// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_SECTION_LOOP_BODY_CASE29_SPLIT:%.*]], label [[OMP_SECTION_LOOP_BODY_CASE29_CNCL:%.*]]
+// CHECK3: omp_section_loop.body.case29.split:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE25_SECTION_AFTER29:%.*]]
+// CHECK3: omp_section_loop.body.case29.section.after30:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE29_SECTION_AFTER:%.*]]
+// CHECK3: omp_section_loop.body.case29.section.after:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY19_SECTIONS_AFTER:.*]]
+// CHECK3: omp_section_loop.body19.sections.after:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_INC20:.*]]
+// CHECK3: omp_section_loop.inc20:
// CHECK3-NEXT: [[OMP_SECTION_LOOP_NEXT22]] = add nuw i32 [[OMP_SECTION_LOOP_IV20]], 1
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_HEADER14]]
-// CHECK3: omp_section_loop.exit18:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_HEADER17]]
+// CHECK3: omp_section_loop.exit21:
// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM32]])
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM33:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM33]])
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_AFTER19:%.*]]
-// CHECK3: omp_section_loop.after19:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_AFTER22:%.*]]
+// CHECK3: omp_section_loop.after22:
// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARGC_ADDR]], align 4
// CHECK3-NEXT: store i32 [[TMP20]], ptr [[DOTCAPTURE_EXPR_]], align 4
// CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
@@ -887,11 +887,11 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: .cancel.exit:
// CHECK3-NEXT: br label [[CANCEL_EXIT:%.*]]
// CHECK3: omp_section_loop.body.case.cncl:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT]]
-// CHECK3: omp_section_loop.body.case23.cncl:
-// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT18]]
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT:.*]]
// CHECK3: omp_section_loop.body.case26.cncl:
-// CHECK3-NEXT: br label [[OMP_REGION_FINALIZE:.*]]
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT18:.*]]
+// CHECK3: omp_section_loop.body.case29.cncl:
+// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT21:.*]]
// CHECK3: .cancel.continue:
// CHECK3-NEXT: br label [[OMP_IF_END:%.*]]
// CHECK3: omp_if.else:
@@ -950,8 +950,17 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: [[TOBOOL:%.*]] = fcmp une float [[TMP2]], 0.000000e+00
// CHECK3-NEXT: br i1 [[TOBOOL]], label [[TMP14:%.*]], label [[TMP3:%.*]]
// CHECK3: 3:
-// CHECK3-NEXT: br label [[TMP4:%.*]]
-// CHECK3: 4:
+// CHECK3-NEXT: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK3-NEXT: %[[CANCEL_POINT:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 1)
+// CHECK3-NEXT: %[[COND:.*]] = icmp eq i32 %[[CANCEL_POINT]], 0
+// CHECK3-NEXT: br i1 %[[COND]], label %[[SPLIT:.*]], label %[[CNCL:.*]]
+// CHECK3: .cncl:
+// CHECK3-NEXT: br label %[[FINI:.*]]
+// CHECK3: .fini:
+// CHECK3-NEXT: br label %[[EXIT_STUB:omp.par.exit.exitStub]]
+// CHECK3: .split:
+// CHECK3-NEXT: br label [[TMP6:%.*]]
+// CHECK3: 6:
// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[LOADGEP_ARGC_ADDR]], align 4
// CHECK3-NEXT: [[CONV:%.*]] = trunc i32 [[TMP5]] to i8
// CHECK3-NEXT: [[TMP6:%.*]] = load ptr, ptr [[LOADGEP_ARGV_ADDR]], align 8
@@ -963,10 +972,8 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: [[TMP8:%.*]] = call i32 @__kmpc_cancel_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM4]])
// CHECK3-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
// CHECK3-NEXT: br i1 [[TMP9]], label [[DOTCONT:%.*]], label [[DOTCNCL5:%.*]]
-// CHECK3: .cncl4:
-// CHECK3-NEXT: br label [[FINI:%.*]]
-// CHECK3: .fini
-// CHECK3-NEXT: br label %[[EXIT_STUB:omp.par.exit.exitStub]]
+// CHECK3: .cncl7:
+// CHECK3-NEXT: br label %[[FINI]]
// CHECK3: .cont:
// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[LOADGEP_ARGC_ADDR]], align 4
// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[LOADGEP_ARGV_ADDR]], align 8
@@ -982,16 +989,16 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: omp.par.region.parallel.after:
// CHECK3-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
// CHECK3: omp.par.pre_finalize:
-// CHECK3-NEXT: br label [[FINI]]
-// CHECK3: 14:
+// CHECK3-NEXT: br label %[[FINI]]
+// CHECK3: 16:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_cancel(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM1]], i32 1)
// CHECK3-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0
// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTSPLIT:%.*]], label [[DOTCNCL:%.*]]
-// CHECK3: .cncl:
-// CHECK3-NEXT: br label [[FINI]]
-// CHECK3: .split:
-// CHECK3-NEXT: br label [[TMP4]]
+// CHECK3: .cncl4:
+// CHECK3-NEXT: br label %[[FINI]]
+// CHECK3: .split3:
+// CHECK3-NEXT: br label {{.+}}
// CHECK3: omp.par.exit.exitStub:
// CHECK3-NEXT: ret void
//
@@ -1160,7 +1167,7 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: .omp.sections.case2.split:
// CHECK3-NEXT: br label [[DOTOMP_SECTIONS_CASE2_SECTION_AFTER:%.*]]
// CHECK3: .omp.sections.case2.section.after:
-// CHECK3-NEXT: br label [[OMP_REGION_FINALIZE]]
+// CHECK3-NEXT: br label [[OMP_REGION_FINALIZE:.*]]
// CHECK3: omp_region.finalize:
// CHECK3-NEXT: br label [[OMP_SECTIONS_EXIT:.*]]
// CHECK3: .omp.sections.case2.cncl:
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 0d196be2ee696..0c0caf80d2573 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -1149,8 +1149,20 @@ OpenMPIRBuilder::createCancel(const LocationDescription &Loc,
auto *UI = Builder.CreateUnreachable();
Instruction *ThenTI = UI, *ElseTI = nullptr;
- if (IfCondition)
+ if (IfCondition) {
SplitBlockAndInsertIfThenElse(IfCondition, UI, &ThenTI, &ElseTI);
+
+ // Even if the if condition evaluates to false, this should count as a
+ // cancellation point
+ Builder.SetInsertPoint(ElseTI);
+ auto ElseIP = Builder.saveIP();
+
+ InsertPointOrErrorTy IPOrErr = createCancellationPoint(
+ LocationDescription{ElseIP, Loc.DL}, CanceledDirective);
+ if (!IPOrErr)
+ return IPOrErr;
+ }
+
Builder.SetInsertPoint(ThenTI);
Value *CancelKind = nullptr;
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
index dab0a46eeb3bc..4595590a083d3 100644
--- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -490,8 +490,8 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelIfCond) {
OMPBuilder.createCancel(Loc, Builder.getTrue(), OMPD_parallel));
Builder.restoreIP(NewIP);
EXPECT_FALSE(M->global_empty());
- EXPECT_EQ(M->size(), 3U);
- EXPECT_EQ(F->size(), 8U);
+ EXPECT_EQ(M->size(), 4U);
+ EXPECT_EQ(F->size(), 10U);
EXPECT_EQ(BB->size(), 1U);
ASSERT_TRUE(isa<BranchInst>(BB->getTerminator()));
ASSERT_EQ(BB->getTerminator()->getNumSuccessors(), 2U);
diff --git a/mlir/test/Target/LLVMIR/openmp-cancel.mlir b/mlir/test/Target/LLVMIR/openmp-cancel.mlir
index 5e20b8793f499..a6911f80d43b7 100644
--- a/mlir/test/Target/LLVMIR/openmp-cancel.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-cancel.mlir
@@ -60,28 +60,35 @@ llvm.func @cancel_parallel_if(%arg0 : i1) {
// CHECK: omp.par.region: ; preds = %[[VAL_17]]
// CHECK: br label %[[VAL_20:.*]]
// CHECK: omp.par.region1: ; preds = %[[VAL_19]]
-// CHECK: br i1 %[[VAL_16]], label %[[VAL_21:.*]], label %[[VAL_22:.*]]
+// CHECK: br i1 %[[VAL_16]], label %[[SPLIT:.*]], label %[[VAL_22:.*]]
// CHECK: 3: ; preds = %[[VAL_20]]
-// CHECK: br label %[[VAL_23:.*]]
-// CHECK: 4: ; preds = %[[VAL_22]], %[[VAL_24:.*]]
-// CHECK: br label %[[VAL_25:.*]]
-// CHECK: omp.region.cont: ; preds = %[[VAL_23]]
-// CHECK: br label %[[VAL_26:.*]]
-// CHECK: omp.par.pre_finalize: ; preds = %[[VAL_25]]
-// CHECK: br label %[[VAL_27:.*]]
+// CHECK: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK: %[[NOT_CANCELLED:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 1)
+// CHECK: %[[COND:.*]] = icmp eq i32 %[[NOT_CANCELLED]], 0
+// CHECK: br i1 %[[COND]], label %[[VAL_23:.*]], label %[[CNCL:.*]]
+// CHECK: .cncl:
+// CHECK: br label %[[FINI:.*]]
// CHECK: .fini:
// CHECK: %[[VAL_32:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
// CHECK: %[[VAL_33:.*]] = call i32 @__kmpc_cancel_barrier(ptr @2, i32 %[[VAL_32]])
// CHECK: br label %[[EXIT_STUB:.*]]
-// CHECK: 6: ; preds = %[[VAL_20]]
+// CHECK: .split:
+// CHECK: br label %[[SEVEN:.*]]
+// CHECK: 7:
+// CHECK: br label %[[VAL_25:.*]]
+// CHECK: omp.region.cont:
+// CHECK: br label %[[VAL_26:.*]]
+// CHECK: omp.par.pre_finalize: ; preds = %[[VAL_25]]
+// CHECK: br label %[[VAL_27:.*]]
+// CHECK: 8: ; preds = %[[VAL_20]]
// CHECK: %[[VAL_28:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
// CHECK: %[[VAL_29:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_28]], i32 1)
// CHECK: %[[VAL_30:.*]] = icmp eq i32 %[[VAL_29]], 0
-// CHECK: br i1 %[[VAL_30]], label %[[VAL_24]], label %[[VAL_31:.*]]
-// CHECK: .cncl: ; preds = %[[VAL_21]]
-// CHECK: br label %[[VAL_27]]
-// CHECK: .split: ; preds = %[[VAL_21]]
-// CHECK: br label %[[VAL_23]]
+// CHECK: br i1 %[[VAL_30]], label %[[SPLIT5:.*]], label %[[VAL_31:.*]]
+// CHECK: .cncl{{.*}}:
+// CHECK: br label %[[FINI]]
+// CHECK: .split{{.*}}:
+// CHECK: br label %[[SEVEN]]
// CHECK: omp.par.exit.exitStub:
// CHECK: ret void
@@ -136,11 +143,16 @@ llvm.func @cancel_sections_if(%cond : i1) {
// CHECK: %[[VAL_30:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_29]], i32 3)
// CHECK: %[[VAL_31:.*]] = icmp eq i32 %[[VAL_30]], 0
// CHECK: br i1 %[[VAL_31]], label %[[VAL_32:.*]], label %[[VAL_33:.*]]
-// CHECK: .split: ; preds = %[[VAL_27]]
+// CHECK: .split{{.*}}: ; preds = %[[VAL_27]]
// CHECK: br label %[[VAL_34:.*]]
// CHECK: 12: ; preds = %[[VAL_25]]
+// CHECK: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK: %[[CANCEL_POINT:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 3)
+// CHECK: %[[COND:.*]] = icmp eq i32 %13, 0
+// CHECK: br i1 %[[COND]], label %[[SPLIT:.*]], label %[[CNCL:.*]]
+// CHECK: .split{{.*}}:
// CHECK: br label %[[VAL_34]]
-// CHECK: 13: ; preds = %[[VAL_28]], %[[VAL_32]]
+// CHECK: 15:
// CHECK: br label %[[VAL_35:.*]]
// CHECK: omp.region.cont: ; preds = %[[VAL_34]]
// CHECK: br label %[[VAL_23]]
@@ -156,8 +168,10 @@ llvm.func @cancel_sections_if(%cond : i1) {
// CHECK: br label %[[VAL_37:.*]]
// CHECK: omp_section_loop.after: ; preds = %[[VAL_19]]
// CHECK: ret void
-// CHECK: .cncl: ; preds = %[[VAL_27]]
-// CHECK: br label %[[VAL_19]]
+// CHECK: .cncl:
+// CHECK: br label %[[OMP_SECTION_LOOP_EXIT:.*]]
+// CHECK: .cncl{{.*}}:
+// CHECK: br label %[[OMP_SECTION_LOOP_EXIT:.*]]
llvm.func @cancel_wsloop_if(%lb : i32, %ub : i32, %step : i32, %cond : i1) {
omp.wsloop {
@@ -223,11 +237,16 @@ llvm.func @cancel_wsloop_if(%lb : i32, %ub : i32, %step : i32, %cond : i1) {
// CHECK: %[[VAL_47:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_46]], i32 2)
// CHECK: %[[VAL_48:.*]] = icmp eq i32 %[[VAL_47]], 0
// CHECK: br i1 %[[VAL_48]], label %[[VAL_49:.*]], label %[[VAL_50:.*]]
-// CHECK: .split: ; preds = %[[VAL_44]]
+// CHECK: .split{{.*}}:
// CHECK: br label %[[VAL_51:.*]]
-// CHECK: 28: ; preds = %[[VAL_42]]
+// CHECK: 28:
+// CHECK: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK: %[[CANCEL_POINT:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 2)
+// CHECK: %[[COND:.*]] = icmp eq i32 %[[CANCEL_POINT]], 0
+// CHECK: br i1 %[[COND]], label %[[SPLIT3:.*]], label %[[CNCL4:.*]]
+// CHECK: .split{{.*}}:
// CHECK: br label %[[VAL_51]]
-// CHECK: 29: ; preds = %[[VAL_45]], %[[VAL_49]]
+// CHECK: 31:
// CHECK: br label %[[VAL_52:.*]]
// CHECK: omp.region.cont1: ; preds = %[[VAL_51]]
// CHECK: br label %[[VAL_32]]
@@ -243,8 +262,12 @@ llvm.func @cancel_wsloop_if(%lb : i32, %ub : i32, %step : i32, %cond : i1) {
// CHECK: br label %[[VAL_55:.*]]
// CHECK: omp.region.cont: ; preds = %[[VAL_54]]
// CHECK: ret void
-// CHECK: .cncl: ; preds = %[[VAL_44]]
-// CHECK: br label %[[VAL_38]]
+// CHECK: .cncl{{.*}}:
+// CHECK: br label %[[FINI:.*]]
+// CHECK: .fini:
+// CHECK: br label %[[OMP_LOOP_EXIT:.*]]
+// CHECK: .cncl{{.*}}:
+// CHECK: br label %[[FINI:.*]]
omp.private {type = firstprivate} @i32_priv : i32 copy {
^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):
|
…70095) From OpenMP 4.0: > When an if clause is present on a cancel construct and the if expression > evaluates to false, the cancel construct does not activate cancellation. > The cancellation point associated with the cancel construct is always > encountered regardless of the value of the if expression. This wording is retained unmodified in OpenMP 6.0. This re-opens the already approved PR llvm#164587, which was closed by accident. The only changes are a rebase.
From OpenMP 4.0:
This wording is retained unmodified in OpenMP 6.0.
This re-opens the already approved PR #164587, which was closed by accident. The only changes are a rebase.