Hahnfeld created this revision. This resolves a deadlock with the cancel directive when there is no explicit cancellation point. In that case, the implicit barrier acts as cancellation point. After removing the barrier after cancel, the now unmatched barrier for the explicit cancellation point has to go as well.
This has probably worked before https://reviews.llvm.org/rL255992: With the calls for the explicit barrier, it was sure that all threads passed a barrier before exiting. Reported by Simon Convent and Joachim Protze! https://reviews.llvm.org/D30088 Files: lib/CodeGen/CGOpenMPRuntime.cpp test/OpenMP/cancel_codegen.cpp test/OpenMP/cancellation_point_codegen.cpp
Index: test/OpenMP/cancellation_point_codegen.cpp =================================================================== --- test/OpenMP/cancellation_point_codegen.cpp +++ test/OpenMP/cancellation_point_codegen.cpp @@ -26,7 +26,6 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label @@ -46,15 +45,13 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label // CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 3) // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label @@ -69,7 +66,6 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label @@ -116,7 +112,6 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]], // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label %[[RETURN:.+]] // CHECK: [[RETURN]] // CHECK: ret void @@ -126,7 +121,6 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]], // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label %[[RETURN:.+]] // CHECK: [[RETURN]] // CHECK: ret i32 0 @@ -137,7 +131,6 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label @@ -150,15 +143,13 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label // CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 3) // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label @@ -171,7 +162,6 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label Index: test/OpenMP/cancel_codegen.cpp =================================================================== --- test/OpenMP/cancel_codegen.cpp +++ test/OpenMP/cancel_codegen.cpp @@ -12,15 +12,16 @@ { #pragma omp cancel parallel if(flag) argv[0][0] = argc; +#pragma omp barrier + argv[0][0] += argc; } // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( #pragma omp sections { #pragma omp cancel sections } // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call i32 @__kmpc_cancel( -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: call void @__kmpc_for_static_fini( // CHECK: call void @__kmpc_barrier(%ident_t* #pragma omp sections @@ -36,15 +37,13 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label // CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 3) // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label @@ -62,7 +61,6 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label @@ -109,9 +107,10 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]], // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label %[[RETURN:.+]] // CHECK: [[ELSE]] +// The barrier directive should now call __kmpc_cancel_barrier +// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[RETURN]] // CHECK: ret void @@ -121,15 +120,13 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]], // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label %[[RETURN:.+]] // CHECK: [[RETURN]] // CHECK: ret i32 0 // CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}}) // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call i32 @__kmpc_cancel( -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: call void @__kmpc_for_static_fini( // CHECK: ret void @@ -139,15 +136,13 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label // CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 3) // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label @@ -160,7 +155,6 @@ // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] // CHECK: [[EXIT]] -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label Index: lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- lib/CodeGen/CGOpenMPRuntime.cpp +++ lib/CodeGen/CGOpenMPRuntime.cpp @@ -4721,16 +4721,13 @@ auto *Result = CGF.EmitRuntimeCall( createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args); // if (__kmpc_cancellationpoint()) { - // __kmpc_cancel_barrier(); // exit from construct; // } auto *ExitBB = CGF.createBasicBlock(".cancel.exit"); auto *ContBB = CGF.createBasicBlock(".cancel.continue"); auto *Cmp = CGF.Builder.CreateIsNotNull(Result); CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); CGF.EmitBlock(ExitBB); - // __kmpc_cancel_barrier(); - emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false); // exit from construct; auto CancelDest = CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind()); @@ -4759,16 +4756,13 @@ auto *Result = CGF.EmitRuntimeCall( RT.createRuntimeFunction(OMPRTL__kmpc_cancel), Args); // if (__kmpc_cancel()) { - // __kmpc_cancel_barrier(); // exit from construct; // } auto *ExitBB = CGF.createBasicBlock(".cancel.exit"); auto *ContBB = CGF.createBasicBlock(".cancel.continue"); auto *Cmp = CGF.Builder.CreateIsNotNull(Result); CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); CGF.EmitBlock(ExitBB); - // __kmpc_cancel_barrier(); - RT.emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false); // exit from construct; auto CancelDest = CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits