319 lines · plain
1// RUN: mlir-translate --mlir-to-llvmir %s | FileCheck %s2 3llvm.func @cancel_parallel() {4 omp.parallel {5 omp.cancel cancellation_construct_type(parallel)6 omp.terminator7 }8 llvm.return9}10// CHECK-LABEL: define internal void @cancel_parallel..omp_par11// CHECK: omp.par.entry:12// CHECK: %[[VAL_5:.*]] = alloca i32, align 413// CHECK: %[[VAL_6:.*]] = load i32, ptr %[[VAL_7:.*]], align 414// CHECK: store i32 %[[VAL_6]], ptr %[[VAL_5]], align 415// CHECK: %[[VAL_8:.*]] = load i32, ptr %[[VAL_5]], align 416// CHECK: br label %[[VAL_9:.*]]17// CHECK: omp.region.after_alloca: ; preds = %[[VAL_10:.*]]18// CHECK: br label %[[VAL_11:.*]]19// CHECK: omp.par.region: ; preds = %[[VAL_9]]20// CHECK: br label %[[VAL_12:.*]]21// CHECK: omp.par.region1: ; preds = %[[VAL_11]]22// CHECK: %[[VAL_13:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)23// CHECK: %[[VAL_14:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_13]], i32 1)24// CHECK: %[[VAL_15:.*]] = icmp eq i32 %[[VAL_14]], 025// CHECK: br i1 %[[VAL_15]], label %[[VAL_16:.*]], label %[[VAL_17:.*]]26// CHECK: omp.par.region1.cncl: ; preds = %[[VAL_12]]27// CHECK: br label %[[VAL_20:.*]]28// CHECK: .fini:29// CHECK: %[[VAL_18:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)30// CHECK: %[[VAL_19:.*]] = call i32 @__kmpc_cancel_barrier(ptr @2, i32 %[[VAL_18]])31// CHECK: br label %[[EXIT_STUB:.*]]32// CHECK: omp.par.region1.split: ; preds = %[[VAL_12]]33// CHECK: br label %[[VAL_21:.*]]34// CHECK: omp.region.cont: ; preds = %[[VAL_16]]35// CHECK: br label %[[VAL_22:.*]]36// CHECK: omp.par.pre_finalize: ; preds = %[[VAL_21]]37// CHECK: br label %[[VAL_20]]38// CHECK: omp.par.exit.exitStub:39// CHECK: ret void40 41llvm.func @cancel_parallel_if(%arg0 : i1) {42 omp.parallel {43 omp.cancel cancellation_construct_type(parallel) if(%arg0)44 omp.terminator45 }46 llvm.return47}48// CHECK-LABEL: define internal void @cancel_parallel_if..omp_par49// CHECK: omp.par.entry:50// CHECK: %[[VAL_9:.*]] = getelementptr { ptr }, ptr %[[VAL_10:.*]], i32 0, i32 051// CHECK: %[[VAL_11:.*]] = load ptr, ptr %[[VAL_9]], align 852// CHECK: %[[VAL_12:.*]] = alloca i32, align 453// CHECK: %[[VAL_13:.*]] = load i32, ptr %[[VAL_14:.*]], align 454// CHECK: store i32 %[[VAL_13]], ptr %[[VAL_12]], align 455// CHECK: %[[VAL_15:.*]] = load i32, ptr %[[VAL_12]], align 456// CHECK: %[[VAL_16:.*]] = load i1, ptr %[[VAL_11]], align 157// CHECK: br label %[[VAL_17:.*]]58// CHECK: omp.region.after_alloca: ; preds = %[[VAL_18:.*]]59// CHECK: br label %[[VAL_19:.*]]60// CHECK: omp.par.region: ; preds = %[[VAL_17]]61// CHECK: br label %[[VAL_20:.*]]62// CHECK: omp.par.region1: ; preds = %[[VAL_19]]63// CHECK: br i1 %[[VAL_16]], label %[[SPLIT:.*]], label %[[VAL_22:.*]]64// CHECK: 3: ; preds = %[[VAL_20]]65// CHECK: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)66// CHECK: %[[NOT_CANCELLED:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 1)67// CHECK: %[[COND:.*]] = icmp eq i32 %[[NOT_CANCELLED]], 068// CHECK: br i1 %[[COND]], label %[[VAL_23:.*]], label %[[CNCL:.*]]69// CHECK: .cncl:70// CHECK: br label %[[FINI:.*]]71// CHECK: .fini:72// CHECK: %[[VAL_32:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)73// CHECK: %[[VAL_33:.*]] = call i32 @__kmpc_cancel_barrier(ptr @2, i32 %[[VAL_32]])74// CHECK: br label %[[EXIT_STUB:.*]]75// CHECK: .split:76// CHECK: br label %[[SEVEN:.*]]77// CHECK: 7:78// CHECK: br label %[[VAL_25:.*]]79// CHECK: omp.region.cont:80// CHECK: br label %[[VAL_26:.*]]81// CHECK: omp.par.pre_finalize: ; preds = %[[VAL_25]]82// CHECK: br label %[[VAL_27:.*]]83// CHECK: 8: ; preds = %[[VAL_20]]84// CHECK: %[[VAL_28:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)85// CHECK: %[[VAL_29:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_28]], i32 1)86// CHECK: %[[VAL_30:.*]] = icmp eq i32 %[[VAL_29]], 087// CHECK: br i1 %[[VAL_30]], label %[[SPLIT5:.*]], label %[[VAL_31:.*]]88// CHECK: .cncl{{.*}}:89// CHECK: br label %[[FINI]]90// CHECK: .split{{.*}}:91// CHECK: br label %[[SEVEN]]92// CHECK: omp.par.exit.exitStub:93// CHECK: ret void94 95llvm.func @cancel_sections_if(%cond : i1) {96 omp.sections {97 omp.section {98 omp.cancel cancellation_construct_type(sections) if(%cond)99 omp.terminator100 }101 omp.terminator102 }103 llvm.return104}105// CHECK-LABEL: define void @cancel_sections_if106// CHECK: %[[VAL_0:.*]] = alloca i32, align 4107// CHECK: %[[VAL_1:.*]] = alloca i32, align 4108// CHECK: %[[VAL_2:.*]] = alloca i32, align 4109// CHECK: %[[VAL_3:.*]] = alloca i32, align 4110// CHECK: br label %[[VAL_4:.*]]111// CHECK: entry: ; preds = %[[VAL_5:.*]]112// CHECK: br label %[[VAL_6:.*]]113// CHECK: omp_section_loop.preheader: ; preds = %[[VAL_4]]114// CHECK: store i32 0, ptr %[[VAL_1]], align 4115// CHECK: store i32 0, ptr %[[VAL_2]], align 4116// CHECK: store i32 1, ptr %[[VAL_3]], align 4117// CHECK: %[[VAL_7:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)118// CHECK: call void @__kmpc_for_static_init_4u(ptr @1, i32 %[[VAL_7]], i32 34, ptr %[[VAL_0]], ptr %[[VAL_1]], ptr %[[VAL_2]], ptr %[[VAL_3]], i32 1, i32 0)119// CHECK: %[[VAL_8:.*]] = load i32, ptr %[[VAL_1]], align 4120// CHECK: %[[VAL_9:.*]] = load i32, ptr %[[VAL_2]], align 4121// CHECK: %[[VAL_10:.*]] = sub i32 %[[VAL_9]], %[[VAL_8]]122// CHECK: %[[VAL_11:.*]] = add i32 %[[VAL_10]], 1123// CHECK: br label %[[VAL_12:.*]]124// CHECK: omp_section_loop.header: ; preds = %[[VAL_13:.*]], %[[VAL_6]]125// CHECK: %[[VAL_14:.*]] = phi i32 [ 0, %[[VAL_6]] ], [ %[[VAL_15:.*]], %[[VAL_13]] ]126// CHECK: br label %[[VAL_16:.*]]127// CHECK: omp_section_loop.cond: ; preds = %[[VAL_12]]128// CHECK: %[[VAL_17:.*]] = icmp ult i32 %[[VAL_14]], %[[VAL_11]]129// CHECK: br i1 %[[VAL_17]], label %[[VAL_18:.*]], label %[[VAL_19:.*]]130// CHECK: omp_section_loop.body: ; preds = %[[VAL_16]]131// CHECK: %[[VAL_20:.*]] = add i32 %[[VAL_14]], %[[VAL_8]]132// CHECK: %[[VAL_21:.*]] = mul i32 %[[VAL_20]], 1133// CHECK: %[[VAL_22:.*]] = add i32 %[[VAL_21]], 0134// CHECK: switch i32 %[[VAL_22]], label %[[VAL_23:.*]] [135// CHECK: i32 0, label %[[VAL_24:.*]]136// CHECK: ]137// CHECK: omp_section_loop.body.case: ; preds = %[[VAL_18]]138// CHECK: br label %[[VAL_25:.*]]139// CHECK: omp.section.region: ; preds = %[[VAL_24]]140// CHECK: br i1 %[[VAL_26:.*]], label %[[VAL_27:.*]], label %[[VAL_28:.*]]141// CHECK: 9: ; preds = %[[VAL_25]]142// CHECK: %[[VAL_29:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)143// CHECK: %[[VAL_30:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_29]], i32 3)144// CHECK: %[[VAL_31:.*]] = icmp eq i32 %[[VAL_30]], 0145// CHECK: br i1 %[[VAL_31]], label %[[VAL_32:.*]], label %[[VAL_33:.*]]146// CHECK: .split{{.*}}: ; preds = %[[VAL_27]]147// CHECK: br label %[[VAL_34:.*]]148// CHECK: 12: ; preds = %[[VAL_25]]149// CHECK: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)150// CHECK: %[[CANCEL_POINT:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 3)151// CHECK: %[[COND:.*]] = icmp eq i32 %13, 0152// CHECK: br i1 %[[COND]], label %[[SPLIT:.*]], label %[[CNCL:.*]]153// CHECK: .split{{.*}}:154// CHECK: br label %[[VAL_34]]155// CHECK: 15:156// CHECK: br label %[[VAL_35:.*]]157// CHECK: omp.region.cont: ; preds = %[[VAL_34]]158// CHECK: br label %[[VAL_23]]159// CHECK: omp_section_loop.body.sections.after: ; preds = %[[VAL_35]], %[[VAL_18]]160// CHECK: br label %[[VAL_13]]161// CHECK: omp_section_loop.inc: ; preds = %[[VAL_23]]162// CHECK: %[[VAL_15]] = add nuw i32 %[[VAL_14]], 1163// CHECK: br label %[[VAL_12]]164// CHECK: omp_section_loop.exit:165// CHECK: call void @__kmpc_for_static_fini(ptr @1, i32 %[[VAL_7]])166// CHECK: %[[VAL_36:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)167// CHECK: call void @__kmpc_barrier(ptr @2, i32 %[[VAL_36]])168// CHECK: br label %[[VAL_37:.*]]169// CHECK: omp_section_loop.after: ; preds = %[[VAL_19]]170// CHECK: ret void171// CHECK: .cncl:172// CHECK: br label %[[OMP_SECTION_LOOP_EXIT:.*]]173// CHECK: .cncl{{.*}}:174// CHECK: br label %[[OMP_SECTION_LOOP_EXIT:.*]]175 176llvm.func @cancel_wsloop_if(%lb : i32, %ub : i32, %step : i32, %cond : i1) {177 omp.wsloop {178 omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {179 omp.cancel cancellation_construct_type(loop) if(%cond)180 omp.yield181 }182 }183 llvm.return184}185// CHECK-LABEL: define void @cancel_wsloop_if186// CHECK: %[[VAL_0:.*]] = alloca i32, align 4187// CHECK: %[[VAL_1:.*]] = alloca i32, align 4188// CHECK: %[[VAL_2:.*]] = alloca i32, align 4189// CHECK: %[[VAL_3:.*]] = alloca i32, align 4190// CHECK: br label %[[VAL_4:.*]]191// CHECK: omp.region.after_alloca: ; preds = %[[VAL_5:.*]]192// CHECK: br label %[[VAL_6:.*]]193// CHECK: entry: ; preds = %[[VAL_4]]194// CHECK: br label %[[VAL_7:.*]]195// CHECK: omp.wsloop.region: ; preds = %[[VAL_6]]196// CHECK: %[[VAL_8:.*]] = icmp slt i32 %[[VAL_9:.*]], 0197// CHECK: %[[VAL_10:.*]] = sub i32 0, %[[VAL_9]]198// CHECK: %[[VAL_11:.*]] = select i1 %[[VAL_8]], i32 %[[VAL_10]], i32 %[[VAL_9]]199// CHECK: %[[VAL_12:.*]] = select i1 %[[VAL_8]], i32 %[[VAL_13:.*]], i32 %[[VAL_14:.*]]200// CHECK: %[[VAL_15:.*]] = select i1 %[[VAL_8]], i32 %[[VAL_14]], i32 %[[VAL_13]]201// CHECK: %[[VAL_16:.*]] = sub nsw i32 %[[VAL_15]], %[[VAL_12]]202// CHECK: %[[VAL_17:.*]] = icmp sle i32 %[[VAL_15]], %[[VAL_12]]203// CHECK: %[[VAL_18:.*]] = sub i32 %[[VAL_16]], 1204// CHECK: %[[VAL_19:.*]] = udiv i32 %[[VAL_18]], %[[VAL_11]]205// CHECK: %[[VAL_20:.*]] = add i32 %[[VAL_19]], 1206// CHECK: %[[VAL_21:.*]] = icmp ule i32 %[[VAL_16]], %[[VAL_11]]207// CHECK: %[[VAL_22:.*]] = select i1 %[[VAL_21]], i32 1, i32 %[[VAL_20]]208// CHECK: %[[VAL_23:.*]] = select i1 %[[VAL_17]], i32 0, i32 %[[VAL_22]]209// CHECK: br label %[[VAL_24:.*]]210// CHECK: omp_loop.preheader: ; preds = %[[VAL_7]]211// CHECK: store i32 0, ptr %[[VAL_1]], align 4212// CHECK: %[[VAL_25:.*]] = sub i32 %[[VAL_23]], 1213// CHECK: store i32 %[[VAL_25]], ptr %[[VAL_2]], align 4214// CHECK: store i32 1, ptr %[[VAL_3]], align 4215// CHECK: %[[VAL_26:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)216// CHECK: call void @__kmpc_for_static_init_4u(ptr @1, i32 %[[VAL_26]], i32 34, ptr %[[VAL_0]], ptr %[[VAL_1]], ptr %[[VAL_2]], ptr %[[VAL_3]], i32 1, i32 0)217// CHECK: %[[VAL_27:.*]] = load i32, ptr %[[VAL_1]], align 4218// CHECK: %[[VAL_28:.*]] = load i32, ptr %[[VAL_2]], align 4219// CHECK: %[[VAL_29:.*]] = sub i32 %[[VAL_28]], %[[VAL_27]]220// CHECK: %[[VAL_30:.*]] = add i32 %[[VAL_29]], 1221// CHECK: br label %[[VAL_31:.*]]222// CHECK: omp_loop.header: ; preds = %[[VAL_32:.*]], %[[VAL_24]]223// CHECK: %[[VAL_33:.*]] = phi i32 [ 0, %[[VAL_24]] ], [ %[[VAL_34:.*]], %[[VAL_32]] ]224// CHECK: br label %[[VAL_35:.*]]225// CHECK: omp_loop.cond: ; preds = %[[VAL_31]]226// CHECK: %[[VAL_36:.*]] = icmp ult i32 %[[VAL_33]], %[[VAL_30]]227// CHECK: br i1 %[[VAL_36]], label %[[VAL_37:.*]], label %[[VAL_38:.*]]228// CHECK: omp_loop.body: ; preds = %[[VAL_35]]229// CHECK: %[[VAL_39:.*]] = add i32 %[[VAL_33]], %[[VAL_27]]230// CHECK: %[[VAL_40:.*]] = mul i32 %[[VAL_39]], %[[VAL_9]]231// CHECK: %[[VAL_41:.*]] = add i32 %[[VAL_40]], %[[VAL_14]]232// CHECK: br label %[[VAL_42:.*]]233// CHECK: omp.loop_nest.region: ; preds = %[[VAL_37]]234// CHECK: br i1 %[[VAL_43:.*]], label %[[VAL_44:.*]], label %[[VAL_45:.*]]235// CHECK: 25: ; preds = %[[VAL_42]]236// CHECK: %[[VAL_46:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)237// CHECK: %[[VAL_47:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_46]], i32 2)238// CHECK: %[[VAL_48:.*]] = icmp eq i32 %[[VAL_47]], 0239// CHECK: br i1 %[[VAL_48]], label %[[VAL_49:.*]], label %[[VAL_50:.*]]240// CHECK: .split{{.*}}:241// CHECK: br label %[[VAL_51:.*]]242// CHECK: 28:243// CHECK: %[[GTN:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)244// CHECK: %[[CANCEL_POINT:.*]] = call i32 @__kmpc_cancellationpoint(ptr @1, i32 %[[GTN]], i32 2)245// CHECK: %[[COND:.*]] = icmp eq i32 %[[CANCEL_POINT]], 0246// CHECK: br i1 %[[COND]], label %[[SPLIT3:.*]], label %[[CNCL4:.*]]247// CHECK: .split{{.*}}:248// CHECK: br label %[[VAL_51]]249// CHECK: 31:250// CHECK: br label %[[VAL_52:.*]]251// CHECK: omp.region.cont1: ; preds = %[[VAL_51]]252// CHECK: br label %[[VAL_32]]253// CHECK: omp_loop.inc: ; preds = %[[VAL_52]]254// CHECK: %[[VAL_34]] = add nuw i32 %[[VAL_33]], 1255// CHECK: br label %[[VAL_31]]256// CHECK: omp_loop.exit:257// CHECK: call void @__kmpc_for_static_fini(ptr @1, i32 %[[VAL_26]])258// CHECK: %[[VAL_53:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)259// CHECK: call void @__kmpc_barrier(ptr @2, i32 %[[VAL_53]])260// CHECK: br label %[[VAL_54:.*]]261// CHECK: omp_loop.after: ; preds = %[[VAL_38]]262// CHECK: br label %[[VAL_55:.*]]263// CHECK: omp.region.cont: ; preds = %[[VAL_54]]264// CHECK: ret void265// CHECK: .cncl{{.*}}:266// CHECK: br label %[[FINI:.*]]267// CHECK: .fini:268// CHECK: br label %[[OMP_LOOP_EXIT:.*]]269// CHECK: .cncl{{.*}}:270// CHECK: br label %[[FINI:.*]]271 272omp.private {type = firstprivate} @i32_priv : i32 copy {273^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):274 %0 = llvm.load %arg0 : !llvm.ptr -> i32275 llvm.store %0, %arg1 : i32, !llvm.ptr276 omp.yield(%arg1 : !llvm.ptr)277}278 279llvm.func @do_something(!llvm.ptr)280 281llvm.func @cancel_taskgroup(%arg0: !llvm.ptr) {282 omp.taskgroup {283// Using firstprivate clause so we have some end of task cleanup to branch to284// after the cancellation.285 omp.task private(@i32_priv %arg0 -> %arg1 : !llvm.ptr) {286 omp.cancel cancellation_construct_type(taskgroup)287 llvm.call @do_something(%arg1) : (!llvm.ptr) -> ()288 omp.terminator289 }290 omp.terminator291 }292 llvm.return293}294// CHECK-LABEL: define internal void @cancel_taskgroup..omp_par(295// CHECK: task.alloca:296// CHECK: %[[VAL_21:.*]] = load ptr, ptr %[[VAL_22:.*]], align 8297// CHECK: %[[VAL_23:.*]] = getelementptr { ptr }, ptr %[[VAL_21]], i32 0, i32 0298// CHECK: %[[VAL_24:.*]] = load ptr, ptr %[[VAL_23]], align 8, !align !1299// CHECK: br label %[[VAL_25:.*]]300// CHECK: task.body: ; preds = %[[VAL_26:.*]]301// CHECK: %[[VAL_27:.*]] = getelementptr { i32 }, ptr %[[VAL_24]], i32 0, i32 0302// CHECK: br label %[[VAL_28:.*]]303// CHECK: omp.task.region: ; preds = %[[VAL_25]]304// CHECK: %[[VAL_29:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)305// CHECK: %[[VAL_30:.*]] = call i32 @__kmpc_cancel(ptr @1, i32 %[[VAL_29]], i32 4)306// CHECK: %[[VAL_31:.*]] = icmp eq i32 %[[VAL_30]], 0307// CHECK: br i1 %[[VAL_31]], label %omp.task.region.split, label %omp.task.region.cncl308// CHECK: omp.task.region.cncl:309// CHECK: br label %omp.region.cont2310// CHECK: omp.region.cont2:311// Both cancellation and normal paths reach the end-of-task cleanup:312// CHECK: tail call void @free(ptr %[[VAL_24]])313// CHECK: br label %task.exit.exitStub314// CHECK: omp.task.region.split:315// CHECK: call void @do_something(ptr %[[VAL_27]])316// CHECK: br label %omp.region.cont2317// CHECK: task.exit.exitStub:318// CHECK: ret void319