Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@redhat.com>2017-11-14 01:52:27 +0300
committerTom Stellard <tstellar@redhat.com>2017-11-14 01:52:27 +0300
commiteadbc97bc9f9aabc619e8c541e5f35f088f51d04 (patch)
tree68217a4e6407003d397bb8e017c7418f1b32d7de
parent8810e0e6dcfc7ffbff82cbf195bf0f9fe4e8a7d2 (diff)
Merging r309288:
------------------------------------------------------------------------ r309288 | erichkeane | 2017-07-27 09:28:20 -0700 (Thu, 27 Jul 2017) | 32 lines 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.rice@intel.com Differential Revision: https://reviews.llvm.org/D35854 ------------------------------------------------------------------------ llvm-svn: 318099
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h2
-rw-r--r--clang/test/OpenMP/cancel_codegen_cleanup.cpp46
2 files changed, 47 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 753dd92f3071..cca5cf8e18e0 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -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;
}
diff --git a/clang/test/OpenMP/cancel_codegen_cleanup.cpp b/clang/test/OpenMP/cancel_codegen_cleanup.cpp
new file mode 100644
index 000000000000..5a297bd377b1
--- /dev/null
+++ b/clang/test/OpenMP/cancel_codegen_cleanup.cpp
@@ -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++;
+ }
+ }
+}