diff options
-rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 11 | ||||
-rw-r--r-- | clang/test/OpenMP/declare_reduction_codegen.cpp | 20 |
2 files changed, 28 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index d488bd4b30bf..c8993a466cca 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -771,7 +771,8 @@ static void emitInitWithReductionInitializer(CodeGenFunction &CGF, /// \param Init Initial expression of array. /// \param SrcAddr Address of the original array. static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, - QualType Type, const Expr *Init, + QualType Type, bool EmitDeclareReductionInit, + const Expr *Init, const OMPDeclareReductionDecl *DRD, Address SrcAddr = Address::invalid()) { // Perform element-by-element initialization. @@ -825,7 +826,7 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, // Emit copy. { CodeGenFunction::RunCleanupsScope InitScope(CGF); - if (DRD && (DRD->getInitializer() || !Init)) { + if (EmitDeclareReductionInit) { emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent, SrcElementCurrent, ElementTy); } else @@ -883,8 +884,12 @@ void ReductionCodeGen::emitAggregateInitialization( // captured region. auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl()); + bool EmitDeclareReductionInit = + DRD && (DRD->getInitializer() || !PrivateVD->hasInit()); EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(), - DRD ? ClausesData[N].ReductionOp : PrivateVD->getInit(), + EmitDeclareReductionInit, + EmitDeclareReductionInit ? ClausesData[N].ReductionOp + : PrivateVD->getInit(), DRD, SharedLVal.getAddress()); } diff --git a/clang/test/OpenMP/declare_reduction_codegen.cpp b/clang/test/OpenMP/declare_reduction_codegen.cpp index daa1fe8aaf5c..ae6e047d9483 100644 --- a/clang/test/OpenMP/declare_reduction_codegen.cpp +++ b/clang/test/OpenMP/declare_reduction_codegen.cpp @@ -9,6 +9,26 @@ // CHECK: [[SSS_INT:.+]] = type { i32 } // CHECK-LOAD: [[SSS_INT:.+]] = type { i32 } +// CHECK: add +void add(short &out, short &in) {} + +#pragma omp declare reduction(my_add : short : add(omp_out, omp_in)) + +// CHECK: define internal void @. +// CHECK: call void @{{.+}}add{{.+}}( +// CHECK: ret void + +// CHECK: foo_reduction_array +void foo_reduction_array() { + short y[1]; + // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( +#pragma omp parallel for reduction(my_add : y) + for (int i = 0; i < 1; i++) { + } +} + +// CHECK: define internal void @ + #pragma omp declare reduction(+ : int, char : omp_out *= omp_in) // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) // CHECK: [[MUL:%.+]] = mul nsw i32 |