@@ -17366,6 +17366,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
1736617366 SourceLocation EndLoc = Locs.EndLoc;
1736717367 OMPClause *Res = nullptr;
1736817368 int ExtraModifier = Data.ExtraModifier;
17369+ int OriginalSharingModifier = Data.OriginalSharingModifier;
1736917370 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
1737017371 SourceLocation ColonLoc = Data.ColonLoc;
1737117372 switch (Kind) {
@@ -17391,7 +17392,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
1739117392 Res = ActOnOpenMPReductionClause(
1739217393 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
1739317394 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
17394- Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17395+ Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, {},
17396+ static_cast<OpenMPOriginalSharingModifier>(OriginalSharingModifier));
1739517397 break;
1739617398 case OMPC_task_reduction:
1739717399 Res = ActOnOpenMPTaskReductionClause(
@@ -18570,14 +18572,20 @@ struct ReductionData {
1857018572 SmallVector<Expr *, 4> ExprPostUpdates;
1857118573 /// Reduction modifier.
1857218574 unsigned RedModifier = 0;
18575+ /// Original modifier.
18576+ unsigned OrigSharingModifier = 0;
18577+ /// Private Variable Reduction
18578+ SmallVector<bool, 8> IsPrivateVarReduction;
1857318579 ReductionData() = delete;
1857418580 /// Reserves required memory for the reduction data.
18575- ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
18581+ ReductionData(unsigned Size, unsigned Modifier = 0, unsigned OrgModifier = 0)
18582+ : RedModifier(Modifier), OrigSharingModifier(OrgModifier) {
1857618583 Vars.reserve(Size);
1857718584 Privates.reserve(Size);
1857818585 LHSs.reserve(Size);
1857918586 RHSs.reserve(Size);
1858018587 ReductionOps.reserve(Size);
18588+ IsPrivateVarReduction.reserve(Size);
1858118589 if (RedModifier == OMPC_REDUCTION_inscan) {
1858218590 InscanCopyOps.reserve(Size);
1858318591 InscanCopyArrayTemps.reserve(Size);
@@ -18595,6 +18603,7 @@ struct ReductionData {
1859518603 LHSs.emplace_back(nullptr);
1859618604 RHSs.emplace_back(nullptr);
1859718605 ReductionOps.emplace_back(ReductionOp);
18606+ IsPrivateVarReduction.emplace_back(false);
1859818607 TaskgroupDescriptors.emplace_back(nullptr);
1859918608 if (RedModifier == OMPC_REDUCTION_inscan) {
1860018609 InscanCopyOps.push_back(nullptr);
@@ -18605,7 +18614,7 @@ struct ReductionData {
1860518614 /// Stores reduction data.
1860618615 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
1860718616 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
18608- Expr *CopyArrayElem) {
18617+ Expr *CopyArrayElem, bool IsPrivate ) {
1860918618 Vars.emplace_back(Item);
1861018619 Privates.emplace_back(Private);
1861118620 LHSs.emplace_back(LHS);
@@ -18621,6 +18630,7 @@ struct ReductionData {
1862118630 CopyArrayElem == nullptr &&
1862218631 "Copy operation must be used for inscan reductions only.");
1862318632 }
18633+ IsPrivateVarReduction.emplace_back(IsPrivate);
1862418634 }
1862518635};
1862618636} // namespace
@@ -18834,6 +18844,7 @@ static bool actOnOMPReductionKindClause(
1883418844 FirstIter = false;
1883518845 SourceLocation ELoc;
1883618846 SourceRange ERange;
18847+ bool IsPrivate = false;
1883718848 Expr *SimpleRefExpr = RefExpr;
1883818849 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
1883918850 /*AllowArraySection=*/true);
@@ -18933,12 +18944,35 @@ static bool actOnOMPReductionKindClause(
1893318944 reportOriginalDsa(S, Stack, D, DVar);
1893418945 continue;
1893518946 }
18947+ // OpenMP 6.0 [ 7.6.10 ]
18948+ // Support Reduction over private variables with reduction clause.
18949+ // A list item in a reduction clause can now be private in the enclosing
18950+ // context. For orphaned constructs it is assumed to be shared unless the
18951+ // original(private) modifier appears in the clause.
18952+ DVar = Stack->getImplicitDSA(D, true);
18953+ bool IsOrphaned = false;
18954+ OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
18955+ OpenMPDirectiveKind ParentDir = Stack->getParentDirective();
18956+ // Check if the construct is orphaned (has no enclosing OpenMP context)
18957+ IsOrphaned = (ParentDir == OMPD_unknown);
18958+ IsPrivate =
18959+ ((isOpenMPPrivate(DVar.CKind) && DVar.CKind != OMPC_reduction &&
18960+ isOpenMPWorksharingDirective(CurrDir) &&
18961+ !isOpenMPParallelDirective(CurrDir) &&
18962+ !isOpenMPTeamsDirective(CurrDir) &&
18963+ !isOpenMPSimdDirective(ParentDir)) ||
18964+ (IsOrphaned && DVar.CKind == OMPC_unknown) ||
18965+ RD.OrigSharingModifier != OMPC_ORIGINAL_SHARING_shared);
18966+ // Disable private handling for OpenMP versions <= 5.2
18967+ if (S.getLangOpts().OpenMP <= 52)
18968+ IsPrivate = false;
1893618969
1893718970 // OpenMP [2.14.3.6, Restrictions, p.1]
1893818971 // A list item that appears in a reduction clause of a worksharing
1893918972 // construct must be shared in the parallel regions to which any of the
1894018973 // worksharing regions arising from the worksharing construct bind.
18941- if (isOpenMPWorksharingDirective(CurrDir) &&
18974+
18975+ if (!IsPrivate && isOpenMPWorksharingDirective(CurrDir) &&
1894218976 !isOpenMPParallelDirective(CurrDir) &&
1894318977 !isOpenMPTeamsDirective(CurrDir)) {
1894418978 DVar = Stack->getImplicitDSA(D, true);
@@ -19434,7 +19468,7 @@ static bool actOnOMPReductionKindClause(
1943419468 }
1943519469 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
1943619470 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
19437- TempArrayElem.get());
19471+ TempArrayElem.get(), IsPrivate );
1943819472 }
1943919473 return RD.Vars.empty();
1944019474}
@@ -19444,7 +19478,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPReductionClause(
1944419478 SourceLocation StartLoc, SourceLocation LParenLoc,
1944519479 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1944619480 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19447- ArrayRef<Expr *> UnresolvedReductions) {
19481+ ArrayRef<Expr *> UnresolvedReductions,
19482+ OpenMPOriginalSharingModifier OriginalSharingMod) {
1944819483 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
1944919484 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
1945019485 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
@@ -19466,8 +19501,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPReductionClause(
1946619501 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
1946719502 return nullptr;
1946819503 }
19469-
19470- ReductionData RD(VarList.size(), Modifier);
19504+ ReductionData RD(VarList.size(), Modifier, OriginalSharingMod);
1947119505 if (actOnOMPReductionKindClause(SemaRef, DSAStack, OMPC_reduction, VarList,
1947219506 StartLoc, LParenLoc, ColonLoc, EndLoc,
1947319507 ReductionIdScopeSpec, ReductionId,
@@ -19481,7 +19515,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPReductionClause(
1948119515 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
1948219516 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
1948319517 buildPreInits(getASTContext(), RD.ExprCaptures),
19484- buildPostUpdate(SemaRef, RD.ExprPostUpdates));
19518+ buildPostUpdate(SemaRef, RD.ExprPostUpdates), RD.IsPrivateVarReduction );
1948519519}
1948619520
1948719521OMPClause *SemaOpenMP::ActOnOpenMPTaskReductionClause(
0 commit comments