Author: erichkeane
Date: Thu Jul 27 09:28:20 2017
New Revision: 309288

URL: http://llvm.org/viewvc/llvm-project?rev=309288&view=rev
Log:
Fix double destruction of objects when OpenMP construct is canceled

When an omp for loop is canceled the constructed objects are being destructed 
twice.

It looks like the desired code is:

{

  Obj o;
  If (cancelled) branch-through-cleanups to cancel.exit.

}
[cleanups]
cancel.exit:

__kmpc_for_static_fini
br cancel.cont (*)

cancel.cont:

__kmpc_barrier
return

The problem seems to be the branch to cancel.cont is currently also going 
through the cleanups calling them again. This change just does a direct branch 
instead.

Patch By: michael.p.r...@intel.com

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

Added:
    cfe/trunk/test/OpenMP/cancel_codegen_cleanup.cpp
Modified:
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=309288&r1=309287&r2=309288&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Jul 27 09:28:20 2017
@@ -1116,7 +1116,7 @@ private:
         auto IP = CGF.Builder.saveAndClearIP();
         CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
         CodeGen(CGF);
-        CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
+        CGF.EmitBranch(Stack.back().ContBlock.getBlock());
         CGF.Builder.restoreIP(IP);
         Stack.back().HasBeenEmitted = true;
       }

Added: cfe/trunk/test/OpenMP/cancel_codegen_cleanup.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/cancel_codegen_cleanup.cpp?rev=309288&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/cancel_codegen_cleanup.cpp (added)
+++ cfe/trunk/test/OpenMP/cancel_codegen_cleanup.cpp Thu Jul 27 09:28:20 2017
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=45 -triple 
x86_64-apple-darwin13.4.0 -emit-llvm -o - %s | FileCheck %s
+
+//CHECK: call i32 @__kmpc_cancel
+//CHECK: br {{.*}}label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
+//CHECK: [[EXIT]]:
+//CHECK: store i32 [[EXIT_SLOT:[0-9]+]]
+//CHECK: br label %[[CLEANUP:.+]]
+//CHECK: [[CONTINUE]]:
+//CHECK: store i32 [[CONT_SLOT:[0-9]+]],
+//CHECK: br label %[[CLEANUP]]
+//CHECK: [[CLEANUP]]:
+//CHECK-NEXT: call void @_ZN3ObjD1Ev
+//CHECK: switch i32{{.*}}, label %[[UNREACHABLE:.+]] [
+//CHECK:   i32 [[CONT_SLOT]], label %[[CLEANUPCONT:.+]]
+//CHECK:   i32 [[EXIT_SLOT]], label %[[CANCELEXIT:.+]]
+//CHECK-NEXT: ]
+//CHECK: [[CLEANUPCONT]]:
+//CHECK: br label %[[CANCELCONT:.+]]
+//CHECK: [[CANCELCONT]]:
+//CHECK-NEXT: call void @__kmpc_barrier(
+//CHECK-NEXT: ret void
+//CHECK: [[UNREACHABLE]]:
+//CHECK-NEXT: unreachable
+//CHECK-NEXT: }
+
+struct Obj {
+  int a; Obj(); Obj(const Obj& r) = delete; Obj &operator=(const Obj& r);
+  ~Obj();
+};
+ 
+void foo() {
+  int i,count = 0;
+  Obj obj;
+
+  #pragma omp parallel private(i) num_threads(1)
+  {
+      #pragma omp for reduction(+:count) lastprivate(obj)
+      for (i=0; i<1000; i++) {
+            if(i==100) {
+                obj.a = 100;
+                #pragma omp cancel for
+            }
+            count++;
+        }
+    }
+}


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to