]> granicus.if.org Git - clang/commitdiff
[OpenMP] Remove barriers at cancel and cancellation point
authorJonas Hahnfeld <Hahnfeld@itc.rwth-aachen.de>
Fri, 17 Feb 2017 18:32:51 +0000 (18:32 +0000)
committerJonas Hahnfeld <Hahnfeld@itc.rwth-aachen.de>
Fri, 17 Feb 2017 18:32:51 +0000 (18:32 +0000)
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 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!

Differential Revision: https://reviews.llvm.org/D30088

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295473 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGOpenMPRuntime.cpp
test/OpenMP/cancel_codegen.cpp
test/OpenMP/cancellation_point_codegen.cpp

index e507b39e4008b2441847ebd8ee726a914947ce11..099fa5905b1fd38ba74299f5f2c64a9fb2c5b217 100644 (file)
@@ -4724,7 +4724,6 @@ void CGOpenMPRuntime::emitCancellationPointCall(
       auto *Result = CGF.EmitRuntimeCall(
           createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args);
       // if (__kmpc_cancellationpoint()) {
-      //  __kmpc_cancel_barrier();
       //   exit from construct;
       // }
       auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
@@ -4732,8 +4731,6 @@ void CGOpenMPRuntime::emitCancellationPointCall(
       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());
@@ -4762,7 +4759,6 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
       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");
@@ -4770,8 +4766,6 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
       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());
index 69acb3d4906ebfac812085c6c24eb7443744a24e..2ff9dcc186c99aa89c7850e1dbebe8f469a521a6 100644 (file)
@@ -12,6 +12,8 @@ int main (int argc, char **argv) {
 {
 #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
@@ -20,7 +22,6 @@ int main (int argc, char **argv) {
 }
 // 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,7 +37,6 @@ int main (int argc, char **argv) {
 // 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
@@ -44,7 +44,6 @@ int main (int argc, char **argv) {
 // 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 @@ for (int i = 0; i < argc; ++i) {
 // 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 @@ for (int i = 0; i < argc; ++i) {
 // 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,7 +120,6 @@ for (int i = 0; i < argc; ++i) {
 // 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
@@ -129,7 +127,6 @@ for (int i = 0; i < argc; ++i) {
 // 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,7 +136,6 @@ for (int i = 0; i < argc; ++i) {
 // 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
@@ -147,7 +143,6 @@ for (int i = 0; i < argc; ++i) {
 // 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 @@ for (int i = 0; i < argc; ++i) {
 // 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 c87d4015ef73766669fd3658f07be8c6a7b211f9..22969141af54a240f49481ec18e53f7e94dbd04d 100644 (file)
@@ -26,7 +26,6 @@ int main (int argc, char **argv) {
 // 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,7 +45,6 @@ int main (int argc, char **argv) {
 // 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
@@ -54,7 +52,6 @@ int main (int argc, char **argv) {
 // 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 @@ for (int i = 0; i < argc; ++i) {
 // 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 @@ for (int i = 0; i < argc; ++i) {
 // 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 @@ for (int i = 0; i < argc; ++i) {
 // 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 @@ for (int i = 0; i < argc; ++i) {
 // 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,7 +143,6 @@ for (int i = 0; i < argc; ++i) {
 // 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
@@ -158,7 +150,6 @@ for (int i = 0; i < argc; ++i) {
 // 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 @@ for (int i = 0; i < argc; ++i) {
 // 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