Author: Alexey Bataev Date: 2020-07-15T15:14:22-04:00 New Revision: 41d0af00740ac5140f11c7f37157fc6e6dd1b016
URL: https://github.com/llvm/llvm-project/commit/41d0af00740ac5140f11c7f37157fc6e6dd1b016 DIFF: https://github.com/llvm/llvm-project/commit/41d0af00740ac5140f11c7f37157fc6e6dd1b016.diff LOG: [OPENMP]Fix PR46593: Reduction initializer missing construnctor call. Summary: If user-defined reductions with the initializer are used with classes, the compiler misses the constructor call when trying to create a private copy of the reduction variable. Reviewers: jdoerfert Subscribers: cfe-commits, yaxunl, guansong, caomhin Tags: #clang Differential Revision: https://reviews.llvm.org/D83334 Added: Modified: clang/lib/CodeGen/CGOpenMPRuntime.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/OpenMP/for_reduction_codegen_UDR.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 43cbe9c720ea..a7e1fe8560b6 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -886,8 +886,11 @@ void ReductionCodeGen::emitInitialization( SharedType, SharedAddresses[N].first.getBaseInfo(), CGF.CGM.getTBAAInfoForSubobject(SharedAddresses[N].first, SharedType)); if (CGF.getContext().getAsArrayType(PrivateVD->getType())) { + if (DRD && DRD->getInitializer()) + (void)DefaultInit(CGF); emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD); } else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) { + (void)DefaultInit(CGF); emitInitWithReductionInitializer(CGF, DRD, ClausesData[N].ReductionOp, PrivateAddr, SharedLVal.getAddress(CGF), SharedLVal.getType()); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 920463da4027..8bf605e5e76b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -15153,6 +15153,7 @@ static bool actOnOMPReductionKindClause( auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); if (DRD->getInitializer()) { + S.ActOnUninitializedDecl(PrivateVD); Init = DRDRef; RHSVD->setInit(DRDRef); RHSVD->setInitStyle(VarDecl::CallInit); @@ -15259,10 +15260,19 @@ static bool actOnOMPReductionKindClause( llvm_unreachable("Unexpected reduction operation"); } } - if (Init && DeclareReductionRef.isUnset()) + if (Init && DeclareReductionRef.isUnset()) { S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); - else if (!Init) + // Store initializer for single element in private copy. Will be used + // during codegen. + PrivateVD->setInit(RHSVD->getInit()); + PrivateVD->setInitStyle(RHSVD->getInitStyle()); + } else if (!Init) { S.ActOnUninitializedDecl(RHSVD); + // Store initializer for single element in private copy. Will be used + // during codegen. + PrivateVD->setInit(RHSVD->getInit()); + PrivateVD->setInitStyle(RHSVD->getInitStyle()); + } if (RHSVD->isInvalidDecl()) continue; if (!RHSVD->hasInit() && @@ -15276,10 +15286,6 @@ static bool actOnOMPReductionKindClause( << D; continue; } - // Store initializer for single element in private copy. Will be used during - // codegen. - PrivateVD->setInit(RHSVD->getInit()); - PrivateVD->setInitStyle(RHSVD->getInitStyle()); DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); ExprResult ReductionOp; if (DeclareReductionRef.isUsable()) { diff --git a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp index 45962b3ed2b1..31168bc325e3 100644 --- a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp +++ b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp @@ -203,9 +203,11 @@ int main() { // For + reduction operation initial value of private variable is -1. // CHECK: call void [[RED_INIT1:@.+]](float* %{{.+}}, float* %{{.+}}) +// CHECK: call void @_ZN1SIfEC1Ev([[S_FLOAT_TY]]* [[VAR_PRIV]] // For & reduction operation initial value of private variable is defined by call of 'init()' function. // CHECK: call void [[RED_INIT2:@.+]]( +// CHECK: call void @_ZN1SIfEC1Ev([[S_FLOAT_TY]]* [[VAR1_PRIV]] // For && reduction operation initial value of private variable is 1.0. // CHECK: call void [[RED_INIT3:@.+]]( @@ -598,6 +600,17 @@ int main() { // CHECK: br i1 [[DONE]], // Check initialization of private copy. +// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0 +// CHECK: [[END:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40 +// CHECK: br label %[[CTOR:[^,]+]] +// CHECK: [[CTOR]]: +// CHECK: [[CUR:%.+]] = phi [[S_FLOAT_TY]]* [ [[BEGIN]], %{{.+}} ], [ [[NEXT:%.+]], %[[CTOR]] ] +// CHECK: call void @_ZN1SIfEC1Ev([[S_FLOAT_TY]]* [[CUR]]) +// CHECK: [[NEXT:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[CUR]], i64 1 +// CHECK: [[IS_DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* [[NEXT]], [[END]] +// CHECK: br i1 [[IS_DONE]], label %[[DONE:[^,]+]], label %[[CTOR]] +// CHECK: [[DONE]]: + // CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0 // CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]* // CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40 @@ -901,9 +914,11 @@ int main() { // For + reduction operation initial value of private variable is 0. // CHECK: call void [[RED_INIT6:@.+]]( +// CHECK: call void @_ZN1SIiEC1Ev([[S_INT_TY]]* [[VAR_PRIV]] // For & reduction operation initial value of private variable is ones in all bits. // CHECK: call void [[RED_INIT2:@.+]]( +// CHECK: call void @_ZN1SIiEC1Ev([[S_INT_TY]]* [[VAR1_PRIV]] // For && reduction operation initial value of private variable is 1.0. // CHECK: call void [[RED_INIT7:@.+]]( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits