diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2016-04-27 11:38:05 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-04-27 11:38:05 +0000 |
commit | 8fbae8cf093c10ad3848ab9858faa2464197f8ef (patch) | |
tree | 39c05d0785002bcda968acfcaf5cecceacfec742 | |
parent | de0bbe6d1cf2f9273c54b3b35c1f07ea61ca079f (diff) | |
download | bcm5719-llvm-8fbae8cf093c10ad3848ab9858faa2464197f8ef.tar.gz bcm5719-llvm-8fbae8cf093c10ad3848ab9858faa2464197f8ef.zip |
[OPENMP] Fix crash on initialization of classes with no init clause in
declare reductions.
If reduction clause is applied to instance of class with user-defined
reduction operation without initialization clause, it may cause a crash.
Patch fixes this issue.
llvm-svn: 267695
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 6 | ||||
-rw-r--r-- | clang/test/OpenMP/declare_reduction_codegen.cpp | 30 |
2 files changed, 24 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 5bcf0fa4187..78e8c691e00 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -481,7 +481,7 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, // Emit copy. { CodeGenFunction::RunCleanupsScope InitScope(CGF); - if (DRD) { + if (DRD && (DRD->getInitializer() || !Init)) { emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent, SrcElementCurrent, ElementTy); } else @@ -993,7 +993,7 @@ void CodeGenFunction::EmitOMPReductionClauseInit( // Emit private VarDecl with reduction init. AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD); auto Addr = Emission.getAllocatedAddress(); - if (DRD) { + if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) { emitInitWithReductionInitializer(*this, DRD, *IRed, Addr, ASELValue.getAddress(), ASELValue.getType()); @@ -1075,7 +1075,7 @@ void CodeGenFunction::EmitOMPReductionClauseInit( // Emit private VarDecl with reduction init. AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD); auto Addr = Emission.getAllocatedAddress(); - if (DRD) { + if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) { emitInitWithReductionInitializer(*this, DRD, *IRed, Addr, OriginalAddr, PrivateVD->getType()); diff --git a/clang/test/OpenMP/declare_reduction_codegen.cpp b/clang/test/OpenMP/declare_reduction_codegen.cpp index c5783a21cef..a18e73f8a10 100644 --- a/clang/test/OpenMP/declare_reduction_codegen.cpp +++ b/clang/test/OpenMP/declare_reduction_codegen.cpp @@ -42,6 +42,7 @@ template <class T> struct SSS { T a; + SSS() : a() {} #pragma omp declare reduction(fun : T : omp_out ^= omp_in) initializer(omp_priv = 24 + omp_orig) }; @@ -59,8 +60,8 @@ SSS<int> d; // CHECK-NEXT: ret void // CHECK-NEXT: } -// CHECK: define void [[INIT:@[^(]+]]([[SSS_INT]]* -// CHECK-LOAD: define void [[INIT:@[^(]+]]([[SSS_INT]]* +// CHECK: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]* +// CHECK-LOAD: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]* void init(SSS<int> &lhs, SSS<int> &rhs) {} #pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig)) @@ -69,7 +70,7 @@ void init(SSS<int> &lhs, SSS<int> &rhs) {} // CHECK-NEXT: ret void // CHECK-NEXT: } // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) -// CHECK: call void [[INIT]]( +// CHECK: call {{.*}}void [[INIT]]( // CHECK-NEXT: ret void // CHECK-NEXT: } @@ -78,7 +79,7 @@ void init(SSS<int> &lhs, SSS<int> &rhs) {} // CHECK-LOAD-NEXT: ret void // CHECK-LOAD-NEXT: } // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) -// CHECK-LOAD: call void [[INIT]]( +// CHECK-LOAD: call {{.*}}void [[INIT]]( // CHECK-LOAD-NEXT: ret void // CHECK-LOAD-NEXT: } @@ -95,19 +96,30 @@ T foo(T a) { int main() { int i = 0; SSS<int> sss; - // TODO: Add support for scoped reduction identifiers - // #pragma omp parallel reduction(SSS<int>::fun : i) - // TODO-CHECK: #pragma omp parallel reduction(SSS<int>::fun: i) +#pragma omp parallel reduction(SSS < int > ::fun : i) { i += 1; } - // #pragma omp parallel reduction(::fun:sss) - // TODO-CHECK: #pragma omp parallel reduction(::fun: sss) +#pragma omp parallel reduction(::fun : sss) { } +#pragma omp declare reduction(fun : SSS < int > : init(omp_out, omp_in)) +#pragma omp parallel reduction(fun : sss) + { + } + // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( + // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( + // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call({{[^@]*}} @{{[^@]*}}[[REGION:@[^ ]+]] + // CHECK-LABEL: foo return foo(15); } +// CHECK: define internal {{.*}}void [[REGION]]( +// CHECK: [[SSS_PRIV:%.+]] = alloca %struct.SSS, +// CHECK: invoke {{.*}} @_ZN3SSSIiEC1Ev(%struct.SSS* [[SSS_PRIV]]) +// CHECK-NOT: {{call |invoke }} +// CHECK: call {{.*}}i32 @__kmpc_reduce_nowait( + // CHECK-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32 // CHECK-LOAD-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32 |