forked from OSchip/llvm-project
[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
This commit is contained in:
parent
de0bbe6d1c
commit
8fbae8cf09
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue