diff options
author | Tom Stellard <tstellar@redhat.com> | 2017-11-14 01:52:27 +0300 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2017-11-14 01:52:27 +0300 |
commit | eadbc97bc9f9aabc619e8c541e5f35f088f51d04 (patch) | |
tree | 68217a4e6407003d397bb8e017c7418f1b32d7de | |
parent | 8810e0e6dcfc7ffbff82cbf195bf0f9fe4e8a7d2 (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.h | 2 | ||||
-rw-r--r-- | clang/test/OpenMP/cancel_codegen_cleanup.cpp | 46 |
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++; + } + } +} |