From ca2d920b4f8b78768c3b1ce833c88a2557037778 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Tue, 23 Sep 2025 16:09:48 +0000 Subject: [PATCH] [OMPIRBuilder] CANCEL IF(FALSE) is still a cancellation point 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. --- clang/test/OpenMP/cancel_codegen.cpp | 109 ++++++++++-------- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 14 ++- .../Frontend/OpenMPIRBuilderTest.cpp | 4 +- mlir/test/Target/LLVMIR/openmp-cancel.mlir | 71 ++++++++---- 4 files changed, 123 insertions(+), 75 deletions(-) diff --git a/clang/test/OpenMP/cancel_codegen.cpp b/clang/test/OpenMP/cancel_codegen.cpp index 150cdb9b2cc14..15bfd7dac8ace 100644 --- a/clang/test/OpenMP/cancel_codegen.cpp +++ b/clang/test/OpenMP/cancel_codegen.cpp @@ -776,8 +776,8 @@ for (int i = 0; i < argc; ++i) { // CHECK3: omp_section_loop.after: // CHECK3-NEXT: br label [[OMP_SECTION_LOOP_AFTERSECTIONS_FINI:%.*]] // CHECK3: omp_section_loop.aftersections.fini: -// 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 @@ -787,54 +787,54 @@ 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: br label [[OMP_SECTION_LOOP_AFTER19SECTIONS_FINI:%.*]] -// CHECK3: omp_section_loop.after19sections.fini: +// CHECK3: omp_section_loop.after22sections.fini: // 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 @@ -891,13 +891,17 @@ 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 [[FINI10:.*]] -// CHECK3: .fini25: -// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT18]] +// CHECK3-NEXT: br label [[FINI13:.*]] +// CHECK3: .fini13: +// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT:.*]] // CHECK3: omp_section_loop.body.case26.cncl: // CHECK3-NEXT: br label [[FINI29:.*]] -// CHECK3: .fini29: -// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT18]] +// CHECK3: .fini28: +// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT18:.*]] +// CHECK3: omp_section_loop.body.case29.cncl: +// CHECK3-NEXT: br label [[FINI32:.*]] +// CHECK3: .fini32: +// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT21:.*]] // CHECK3: .cancel.continue: // CHECK3-NEXT: br label [[OMP_IF_END:%.*]] // CHECK3: omp_if.else: @@ -956,8 +960,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 @@ -969,10 +982,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 @@ -988,16 +999,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 // diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index 9fe0c3f880480..112249ab3d8b8 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -1087,8 +1087,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 da1760a56d952..826b531e516b8 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(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 035e1f546bafa..b502963be0957 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]] @@ -158,8 +170,12 @@ llvm.func @cancel_sections_if(%cond : i1) { // CHECK: br label %[[VAL_38:.*]] // CHECK: omp_section_loop.aftersections.fini: ; preds = %[[VAL_37]] // CHECK: ret void -// CHECK: .cncl: ; preds = %[[VAL_27]] -// CHECK: br label %[[VAL_19]] +// CHECK: .cncl: +// CHECK: br label %[[FINI:.*]] +// CHECK: .fini: +// CHECK: br label %[[OMP_SECTION_LOOP_EXIT:.*]] +// CHECK: .cncl{{.*}}: +// CHECK: br label %[[FINI]] llvm.func @cancel_wsloop_if(%lb : i32, %ub : i32, %step : i32, %cond : i1) { omp.wsloop { @@ -225,11 +241,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]] @@ -245,8 +266,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):