summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2016-04-27 11:38:05 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2016-04-27 11:38:05 +0000
commit8fbae8cf093c10ad3848ab9858faa2464197f8ef (patch)
tree39c05d0785002bcda968acfcaf5cecceacfec742
parentde0bbe6d1cf2f9273c54b3b35c1f07ea61ca079f (diff)
downloadbcm5719-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.cpp6
-rw-r--r--clang/test/OpenMP/declare_reduction_codegen.cpp30
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
OpenPOWER on IntegriCloud