diff options
author | David Pagan <dave.pagan@amd.com> | 2025-01-13 05:44:48 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-13 05:44:48 -0800 |
commit | ad38e24eb74e97148faec97c4f843b87768b6e9b (patch) | |
tree | 69872de287fc2c5156410cb0c1376238220c312b /clang/lib/Sema/SemaOpenMP.cpp | |
parent | 7ed451a3f3f777966b05c51af920aa23fa1cd73e (diff) | |
download | llvm-ad38e24eb74e97148faec97c4f843b87768b6e9b.zip llvm-ad38e24eb74e97148faec97c4f843b87768b6e9b.tar.gz llvm-ad38e24eb74e97148faec97c4f843b87768b6e9b.tar.bz2 |
[clang][OpenMP] Add 'align' modifier for 'allocate' clause (#121814)
The 'align' modifier is now accepted in the 'allocate' clause. Added LIT
tests covering codegen, PCH, template handling, and serialization for
'align' modifier.
Added support for align-modifier to release notes.
Testing
- New allocate modifier LIT tests.
- OpenMP LIT tests.
- check-all
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 102 |
1 files changed, 67 insertions, 35 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 66ff92f..b83b2b1 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5320,6 +5320,8 @@ static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, Expr *SimpleRefExpr = E; auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); ValueDecl *VD = Res.first; + if (!VD) + continue; DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); if (!isOpenMPPrivate(Data.CKind)) { S.Diag(E->getExprLoc(), @@ -5330,10 +5332,8 @@ static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, AllocatorKind, AC->getAllocator())) continue; - // Placeholder until allocate clause supports align modifier. - Expr *Alignment = nullptr; applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), - Alignment, E->getSourceRange()); + AC->getAlignment(), E->getSourceRange()); } } } @@ -15617,7 +15617,9 @@ ExprResult SemaOpenMP::VerifyPositiveIntegerConstantInClause( << E->getSourceRange(); return ExprError(); } - if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) { + if ((CKind == OMPC_aligned || CKind == OMPC_align || + CKind == OMPC_allocate) && + !Result.isPowerOf2()) { Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) << E->getSourceRange(); return ExprError(); @@ -17153,11 +17155,26 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, case OMPC_has_device_addr: Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs); break; - case OMPC_allocate: - Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, - Data.AllocClauseModifier, VarList, StartLoc, - LParenLoc, ColonLoc, EndLoc); + case OMPC_allocate: { + OpenMPAllocateClauseModifier Modifier1 = OMPC_ALLOCATE_unknown; + OpenMPAllocateClauseModifier Modifier2 = OMPC_ALLOCATE_unknown; + SourceLocation Modifier1Loc, Modifier2Loc; + if (!Data.AllocClauseModifiers.empty()) { + assert(Data.AllocClauseModifiers.size() <= 2 && + "More allocate modifiers than expected"); + Modifier1 = Data.AllocClauseModifiers[0]; + Modifier1Loc = Data.AllocClauseModifiersLoc[0]; + if (Data.AllocClauseModifiers.size() == 2) { + Modifier2 = Data.AllocClauseModifiers[1]; + Modifier2Loc = Data.AllocClauseModifiersLoc[1]; + } + } + Res = ActOnOpenMPAllocateClause( + Data.DepModOrTailExpr, Data.AllocateAlignment, Modifier1, Modifier1Loc, + Modifier2, Modifier2Loc, VarList, StartLoc, LParenLoc, ColonLoc, + EndLoc); break; + } case OMPC_nontemporal: Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); break; @@ -23163,32 +23180,37 @@ SemaOpenMP::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList, } OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause( - Expr *Allocator, OpenMPAllocateClauseModifier AllocClauseModifier, - ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ColonLoc, SourceLocation EndLoc) { - + Expr *Allocator, Expr *Alignment, + OpenMPAllocateClauseModifier FirstAllocateModifier, + SourceLocation FirstAllocateModifierLoc, + OpenMPAllocateClauseModifier SecondAllocateModifier, + SourceLocation SecondAllocateModifierLoc, ArrayRef<Expr *> VarList, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, + SourceLocation EndLoc) { if (Allocator) { // Allocator expression is dependent - skip it for now and build the // allocator when instantiated. - if (Allocator->isTypeDependent() || Allocator->isValueDependent() || - Allocator->isInstantiationDependent() || - Allocator->containsUnexpandedParameterPack()) - return nullptr; - // OpenMP [2.11.4 allocate Clause, Description] - // allocator is an expression of omp_allocator_handle_t type. - if (!findOMPAllocatorHandleT(SemaRef, Allocator->getExprLoc(), DSAStack)) - return nullptr; + bool AllocDependent = + (Allocator->isTypeDependent() || Allocator->isValueDependent() || + Allocator->isInstantiationDependent() || + Allocator->containsUnexpandedParameterPack()); + if (!AllocDependent) { + // OpenMP [2.11.4 allocate Clause, Description] + // allocator is an expression of omp_allocator_handle_t type. + if (!findOMPAllocatorHandleT(SemaRef, Allocator->getExprLoc(), DSAStack)) + return nullptr; - ExprResult AllocatorRes = SemaRef.DefaultLvalueConversion(Allocator); - if (AllocatorRes.isInvalid()) - return nullptr; - AllocatorRes = SemaRef.PerformImplicitConversion( - AllocatorRes.get(), DSAStack->getOMPAllocatorHandleT(), - AssignmentAction::Initializing, - /*AllowExplicit=*/true); - if (AllocatorRes.isInvalid()) - return nullptr; - Allocator = AllocatorRes.get(); + ExprResult AllocatorRes = SemaRef.DefaultLvalueConversion(Allocator); + if (AllocatorRes.isInvalid()) + return nullptr; + AllocatorRes = SemaRef.PerformImplicitConversion( + AllocatorRes.get(), DSAStack->getOMPAllocatorHandleT(), + AssignmentAction::Initializing, + /*AllowExplicit=*/true); + if (AllocatorRes.isInvalid()) + return nullptr; + Allocator = AllocatorRes.isUsable() ? AllocatorRes.get() : nullptr; + } } else { // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. // allocate clauses that appear on a target construct or on constructs in a @@ -23199,6 +23221,17 @@ OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause( !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) SemaRef.targetDiag(StartLoc, diag::err_expected_allocator_expression); } + if (Alignment) { + bool AlignmentDependent = Alignment->isTypeDependent() || + Alignment->isValueDependent() || + Alignment->isInstantiationDependent() || + Alignment->containsUnexpandedParameterPack(); + if (!AlignmentDependent) { + ExprResult AlignResult = + VerifyPositiveIntegerConstantInClause(Alignment, OMPC_allocate); + Alignment = AlignResult.isUsable() ? AlignResult.get() : nullptr; + } + } // Analyze and build list of variables. SmallVector<Expr *, 8> Vars; for (Expr *RefExpr : VarList) { @@ -23230,11 +23263,10 @@ OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause( if (Allocator) DSAStack->addInnerAllocatorExpr(Allocator); - OpenMPAllocateClauseModifier AllocatorModifier = AllocClauseModifier; - SourceLocation AllocatorModifierLoc; - return OMPAllocateClause::Create(getASTContext(), StartLoc, LParenLoc, - Allocator, ColonLoc, AllocatorModifier, - AllocatorModifierLoc, EndLoc, Vars); + return OMPAllocateClause::Create( + getASTContext(), StartLoc, LParenLoc, Allocator, Alignment, ColonLoc, + FirstAllocateModifier, FirstAllocateModifierLoc, SecondAllocateModifier, + SecondAllocateModifierLoc, EndLoc, Vars); } OMPClause *SemaOpenMP::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, |