https://github.com/ddpagan updated https://github.com/llvm/llvm-project/pull/121814
>From c2c2c4c46c3ea615e86484b9f9a14a74fab21295 Mon Sep 17 00:00:00 2001 From: Dave Pagan <dave.pa...@amd.com> Date: Fri, 22 Nov 2024 10:35:40 -0600 Subject: [PATCH 1/6] [clang][OpenMP] Add 'align' modifier for 'allocate' clause 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 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/OpenMPClause.h | 92 +++- .../clang/Basic/DiagnosticParseKinds.td | 2 + clang/include/clang/Basic/OpenMPKinds.def | 1 + clang/include/clang/Basic/OpenMPKinds.h | 4 + clang/include/clang/Sema/SemaOpenMP.h | 20 +- clang/lib/AST/OpenMPClause.cpp | 58 ++- clang/lib/Parse/ParseOpenMP.cpp | 95 +++- clang/lib/Sema/SemaOpenMP.cpp | 102 +++-- clang/lib/Sema/TreeTransform.h | 30 +- clang/lib/Serialization/ASTReader.cpp | 6 +- clang/lib/Serialization/ASTWriter.cpp | 4 +- .../allocate_allocator_modifier_codegen.cpp | 255 ----------- .../allocate_allocator_modifier_messages.cpp | 97 ----- ...t.cpp => allocate_modifiers_ast_print.cpp} | 77 +++- .../OpenMP/allocate_modifiers_codegen.cpp | 409 ++++++++++++++++++ .../OpenMP/allocate_modifiers_messages.cpp | 159 +++++++ 17 files changed, 961 insertions(+), 451 deletions(-) delete mode 100644 clang/test/OpenMP/allocate_allocator_modifier_codegen.cpp delete mode 100644 clang/test/OpenMP/allocate_allocator_modifier_messages.cpp rename clang/test/OpenMP/{allocate_allocator_modifier_ast_print.cpp => allocate_modifiers_ast_print.cpp} (51%) create mode 100644 clang/test/OpenMP/allocate_modifiers_codegen.cpp create mode 100644 clang/test/OpenMP/allocate_modifiers_messages.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index acd9dd9298ce1e..25d390f69bcea3 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1284,6 +1284,7 @@ OpenMP Support - Changed the OpenMP DeviceRTL to use 'generic' IR. The ``LIBOMPTARGET_DEVICE_ARCHITECTURES`` CMake argument is now unused and will always build support for AMDGPU and NVPTX targets. +- Added support for align-modifier in 'allocate' clause. Improvements ^^^^^^^^^^^^ diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index d2f5267e4da5ea..b9088eff3bb52e 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -498,6 +498,9 @@ class OMPAllocateClause final /// Allocator specified in the clause, or 'nullptr' if the default one is /// used. Expr *Allocator = nullptr; + /// Alignment specified in the clause, or 'nullptr' if the default one is + /// used. + Expr *Alignment = nullptr; /// Position of the ':' delimiter in the clause; SourceLocation ColonLoc; /// Modifier of 'allocate' clause. @@ -505,6 +508,41 @@ class OMPAllocateClause final /// Location of allocator modifier if any. SourceLocation AllocatorModifierLoc; + // ---------------------------------------------------------------------------- + + /// Modifiers for 'allocate' clause. + enum { FIRST, SECOND, NUM_MODIFIERS }; + OpenMPAllocateClauseModifier Modifiers[NUM_MODIFIERS]; + + /// Locations of modifiers. + SourceLocation ModifiersLoc[NUM_MODIFIERS]; + + /// Set the first allocate modifier. + /// + /// \param M Allocate modifier. + void setFirstAllocateModifier(OpenMPAllocateClauseModifier M) { + Modifiers[FIRST] = M; + } + + /// Set the second allocate modifier. + /// + /// \param M Allocate modifier. + void setSecondAllocateModifier(OpenMPAllocateClauseModifier M) { + Modifiers[SECOND] = M; + } + + /// Set location of the first allocate modifier. + void setFirstAllocateModifierLoc(SourceLocation Loc) { + ModifiersLoc[FIRST] = Loc; + } + + /// Set location of the second allocate modifier. + void setSecondAllocateModifierLoc(SourceLocation Loc) { + ModifiersLoc[SECOND] = Loc; + } + + // ---------------------------------------------------------------------------- + /// Build clause with number of variables \a N. /// /// \param StartLoc Starting location of the clause. @@ -514,15 +552,20 @@ class OMPAllocateClause final /// \param EndLoc Ending location of the clause. /// \param N Number of the variables in the clause. OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, - Expr *Allocator, SourceLocation ColonLoc, - OpenMPAllocateClauseModifier AllocatorModifier, - SourceLocation AllocatorModifierLoc, SourceLocation EndLoc, + Expr *Allocator, Expr *Alignment, SourceLocation ColonLoc, + OpenMPAllocateClauseModifier Modifier1, + SourceLocation Modifier1Loc, + OpenMPAllocateClauseModifier Modifier2, + SourceLocation Modifier2Loc, SourceLocation EndLoc, unsigned N) : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, StartLoc, LParenLoc, EndLoc, N), - Allocator(Allocator), ColonLoc(ColonLoc), - AllocatorModifier(AllocatorModifier), - AllocatorModifierLoc(AllocatorModifierLoc) {} + Allocator(Allocator), Alignment(Alignment), ColonLoc(ColonLoc) { + Modifiers[FIRST] = Modifier1; + Modifiers[SECOND] = Modifier2; + ModifiersLoc[FIRST] = Modifier1Loc; + ModifiersLoc[SECOND] = Modifier2Loc; + } /// Build an empty clause. /// @@ -530,7 +573,10 @@ class OMPAllocateClause final explicit OMPAllocateClause(unsigned N) : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + SourceLocation(), N) { + Modifiers[FIRST] = OMPC_ALLOCATE_unknown; + Modifiers[SECOND] = OMPC_ALLOCATE_unknown; + } /// Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -539,6 +585,7 @@ class OMPAllocateClause final void setAllocatorModifier(OpenMPAllocateClauseModifier AM) { AllocatorModifier = AM; } + void setAlignment(Expr *A) { Alignment = A; } public: /// Creates clause with a list of variables \a VL. @@ -554,19 +601,42 @@ class OMPAllocateClause final /// \param VL List of references to the variables. static OMPAllocateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - Expr *Allocator, SourceLocation ColonLoc, - OpenMPAllocateClauseModifier AllocatorModifier, - SourceLocation AllocatorModifierLoc, SourceLocation EndLoc, - ArrayRef<Expr *> VL); + Expr *Allocator, Expr *Alignment, SourceLocation ColonLoc, + OpenMPAllocateClauseModifier Modifier1, SourceLocation Modifier1Loc, + OpenMPAllocateClauseModifier Modifier2, SourceLocation Modifier2Loc, + SourceLocation EndLoc, ArrayRef<Expr *> VL); /// Returns the allocator expression or nullptr, if no allocator is specified. Expr *getAllocator() const { return Allocator; } + /// Returns the alignment expression or nullptr, if no alignment specified. + Expr *getAlignment() const { return Alignment; } + /// Return 'allocate' modifier. OpenMPAllocateClauseModifier getAllocatorModifier() const { return AllocatorModifier; } + /// Get the first modifier of the clause. + OpenMPAllocateClauseModifier getFirstAllocateModifier() const { + return Modifiers[FIRST]; + } + + /// Get location of first modifier of the clause. + SourceLocation getFirstAllocateModifierLoc() const { + return ModifiersLoc[FIRST]; + } + + /// Get the second modifier of the clause. + OpenMPAllocateClauseModifier getSecondAllocateModifier() const { + return Modifiers[SECOND]; + } + + /// Get location of second modifier of the clause. + SourceLocation getSecondAllocateModifierLoc() const { + return ModifiersLoc[SECOND]; + } + /// Returns the location of the ':' delimiter. SourceLocation getColonLoc() const { return ColonLoc; } /// Return the location of the modifier. diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 86fcae209c40db..3309f59a981fc1 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1658,6 +1658,8 @@ def warn_omp_depend_in_ordered_deprecated : Warning<"'depend' clause for" def warn_omp_invalid_attribute_for_ompx_attributes : Warning<"'ompx_attribute' clause only allows " "'amdgpu_flat_work_group_size', 'amdgpu_waves_per_eu', and 'launch_bounds'; " "%0 is ignored">, InGroup<OpenMPExtensions>; +def err_omp_duplicate_modifier : Error<"duplicate modifier '%0' in '%1' clause">; +def err_omp_expected_modifier : Error<"expected modifier in '%0' clause">; // Pragma loop support. def err_pragma_loop_missing_argument : Error< diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 3f25e7aafe23b6..76a861f416fd57 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -219,6 +219,7 @@ OPENMP_NUMTASKS_MODIFIER(strict) // Modifiers for 'allocate' clause. OPENMP_ALLOCATE_MODIFIER(allocator) +OPENMP_ALLOCATE_MODIFIER(align) // Modifiers for the 'doacross' clause. OPENMP_DOACROSS_MODIFIER(source) diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 900ad6ca6d66f6..3e5da2a6abc017 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -230,6 +230,10 @@ enum OpenMPAllocateClauseModifier { OMPC_ALLOCATE_unknown }; +/// Number of allowed allocate-modifiers. +static constexpr unsigned NumberOfOMPAllocateClauseModifiers = + OMPC_ALLOCATE_unknown; + /// Contains 'interop' data for 'append_args' and 'init' clauses. class Expr; struct OMPInteropInfo final { diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 3d1cc4fab1c10f..a056a96f502333 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1148,7 +1148,12 @@ class SemaOpenMP : public SemaBase { SourceLocation OmpAllMemoryLoc; SourceLocation StepModifierLoc; /// 'step' modifier location for linear clause - OpenMPAllocateClauseModifier AllocClauseModifier = OMPC_ALLOCATE_unknown; + SmallVector<OpenMPAllocateClauseModifier, + NumberOfOMPAllocateClauseModifiers> + AllocClauseModifiers; + SmallVector<SourceLocation, NumberOfOMPAllocateClauseModifiers> + AllocClauseModifiersLoc; + Expr *AllocateAlignment = nullptr; }; OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind, @@ -1166,10 +1171,15 @@ class SemaOpenMP : public SemaBase { SourceLocation LParenLoc, SourceLocation EndLoc); /// Called on well-formed 'allocate' clause. - OMPClause *ActOnOpenMPAllocateClause( - Expr *Allocator, OpenMPAllocateClauseModifier ACModifier, - ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + OMPClause * + ActOnOpenMPAllocateClause(Expr *Allocator, Expr *Alignment, + OpenMPAllocateClauseModifier FirstModifier, + SourceLocation FirstModifierLoc, + OpenMPAllocateClauseModifier SecondModifier, + SourceLocation SecondModifierLoc, + ArrayRef<Expr *> VarList, SourceLocation StartLoc, + SourceLocation ColonLoc, SourceLocation LParenLoc, + SourceLocation EndLoc); /// Called on well-formed 'private' clause. OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 4246ba95d827f1..532933d6183ce7 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1019,19 +1019,18 @@ OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) { return new (C) OMPPartialClause(); } -OMPAllocateClause * -OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, Expr *Allocator, - SourceLocation ColonLoc, - OpenMPAllocateClauseModifier AllocatorModifier, - SourceLocation AllocatorModifierLoc, - SourceLocation EndLoc, ArrayRef<Expr *> VL) { +OMPAllocateClause *OMPAllocateClause::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + Expr *Allocator, Expr *Alignment, SourceLocation ColonLoc, + OpenMPAllocateClauseModifier Modifier1, SourceLocation Modifier1Loc, + OpenMPAllocateClauseModifier Modifier2, SourceLocation Modifier2Loc, + SourceLocation EndLoc, ArrayRef<Expr *> VL) { // Allocate space for private variables and initializer expressions. void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); auto *Clause = new (Mem) OMPAllocateClause( - StartLoc, LParenLoc, Allocator, ColonLoc, AllocatorModifier, - AllocatorModifierLoc, EndLoc, VL.size()); + StartLoc, LParenLoc, Allocator, Alignment, ColonLoc, Modifier1, + Modifier1Loc, Modifier2, Modifier2Loc, EndLoc, VL.size()); Clause->setVarRefs(VL); return Clause; @@ -2245,21 +2244,48 @@ void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) { void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) { if (Node->varlist_empty()) return; + + Expr *FirstModifier = nullptr; + Expr *SecondModifier = nullptr; + auto FirstAllocMod = Node->getFirstAllocateModifier(); + auto SecondAllocMod = Node->getSecondAllocateModifier(); + bool FirstUnknown = FirstAllocMod == OMPC_ALLOCATE_unknown; + bool SecondUnknown = SecondAllocMod == OMPC_ALLOCATE_unknown; + if (FirstAllocMod == OMPC_ALLOCATE_allocator || + (FirstAllocMod == OMPC_ALLOCATE_unknown && Node->getAllocator())) { + FirstModifier = Node->getAllocator(); + SecondModifier = Node->getAlignment(); + } else { + FirstModifier = Node->getAlignment(); + SecondModifier = Node->getAllocator(); + } + OS << "allocate"; - OpenMPAllocateClauseModifier Modifier = Node->getAllocatorModifier(); - if (Expr *Allocator = Node->getAllocator()) { + // If we have any explicit modifiers. + if (FirstModifier) { OS << "("; - if (Modifier == OMPC_ALLOCATE_allocator) { - OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier); + if (!FirstUnknown) { + OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), FirstAllocMod); OS << "("; - Allocator->printPretty(OS, nullptr, Policy, 0); + } + FirstModifier->printPretty(OS, nullptr, Policy, 0); + if (!FirstUnknown) OS << ")"; - } else { - Allocator->printPretty(OS, nullptr, Policy, 0); + if (SecondModifier) { + OS << ", "; + if (!SecondUnknown) { + OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), + SecondAllocMod); + OS << "("; + } + SecondModifier->printPretty(OS, nullptr, Policy, 0); + if (!SecondUnknown) + OS << ")"; } OS << ":"; VisitOMPClauseList(Node, ' '); } else { + // No modifiers. Just print the variable list. VisitOMPClauseList(Node, '('); } OS << ")"; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index b4e973bc84a7b0..4032cbcb614e73 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -4530,32 +4530,87 @@ static bool parseStepSize(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data, } /// Parse 'allocate' clause modifiers. -/// If allocator-modifier exists, return an expression for it and set -/// Data field noting modifier was specified. -/// +/// If allocator-modifier exists, return an expression for it. For both +/// allocator and align modifiers, set Data fields as appropriate. static ExprResult parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data) { const Token &Tok = P.getCurToken(); Preprocessor &PP = P.getPreprocessor(); ExprResult Tail; - auto Modifier = static_cast<OpenMPAllocateClauseModifier>( + ExprResult Val; + SourceLocation RLoc; + bool AllocatorSeen = false; + bool AlignSeen = false; + SourceLocation CurrentModifierLoc = Tok.getLocation(); + auto CurrentModifier = static_cast<OpenMPAllocateClauseModifier>( getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), P.getLangOpts())); - if (Modifier == OMPC_ALLOCATE_allocator) { - Data.AllocClauseModifier = Modifier; + + // Modifiers did not exist before 5.1 + if (P.getLangOpts().OpenMP < 51) + return P.ParseAssignmentExpression(); + + // An allocator-simple-modifier is exclusive and must appear alone. See + // OpenMP6.0 spec, pg. 313, L1 on Modifiers, as well as Table 5.1, pg. 50, + // description of "exclusive" property. If we don't recognized an explicit + // simple-/complex- modifier, assume we're looking at expression + // representing allocator and consider ourselves done. + if (CurrentModifier == OMPC_ALLOCATE_unknown) + return P.ParseAssignmentExpression(); + + do { P.ConsumeToken(); - BalancedDelimiterTracker AllocateT(P, tok::l_paren, - tok::annot_pragma_openmp_end); if (Tok.is(tok::l_paren)) { - AllocateT.consumeOpen(); - Tail = P.ParseAssignmentExpression(); - AllocateT.consumeClose(); + switch (CurrentModifier) { + case OMPC_ALLOCATE_allocator: { + if (AllocatorSeen) { + P.Diag(Tok, diag::err_omp_duplicate_modifier) + << getOpenMPSimpleClauseTypeName(OMPC_allocate, CurrentModifier) + << getOpenMPClauseName(Kind); + } else { + Data.AllocClauseModifiers.push_back(CurrentModifier); + Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc); + } + BalancedDelimiterTracker AllocateT(P, tok::l_paren, + tok::annot_pragma_openmp_end); + AllocateT.consumeOpen(); + Tail = P.ParseAssignmentExpression(); + AllocateT.consumeClose(); + AllocatorSeen = true; + } break; + case OMPC_ALLOCATE_align: { + if (AlignSeen) { + P.Diag(Tok, diag::err_omp_duplicate_modifier) + << getOpenMPSimpleClauseTypeName(OMPC_allocate, CurrentModifier) + << getOpenMPClauseName(Kind); + } else { + Data.AllocClauseModifiers.push_back(CurrentModifier); + Data.AllocClauseModifiersLoc.push_back(CurrentModifierLoc); + } + Val = P.ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc); + if (Val.isUsable()) + Data.AllocateAlignment = Val.get(); + AlignSeen = true; + } break; + default: + assert(false && "Unexpected allocate modifier"); + break; + } } else { P.Diag(Tok, diag::err_expected) << tok::l_paren; } - } else { - Tail = P.ParseAssignmentExpression(); - } + if (Tok.isNot(tok::comma)) + break; + P.ConsumeToken(); + CurrentModifierLoc = Tok.getLocation(); + CurrentModifier = static_cast<OpenMPAllocateClauseModifier>( + getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), P.getLangOpts())); + // A modifier followed by a comma implies another modifier. + if (CurrentModifier == OMPC_ALLOCATE_unknown) { + P.Diag(Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind); + break; + } + } while (!AllocatorSeen || !AlignSeen); return Tail; } @@ -4832,7 +4887,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, } else if (Kind == OMPC_allocate || (Kind == OMPC_affinity && Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator")) { - // Handle optional allocator expression followed by colon delimiter. + // Handle optional allocator and align modifiers followed by colon + // delimiter. ColonProtectionRAIIObject ColonRAII(*this); TentativeParsingAction TPA(*this); // OpenMP 5.0, 2.10.1, task Construct. @@ -4849,19 +4905,18 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Tail = Actions.CorrectDelayedTyposInExpr(Tail); Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(), /*DiscardedValue=*/false); - if (Tail.isUsable()) { + if (Tail.isUsable() || Data.AllocateAlignment) { if (Tok.is(tok::colon)) { - Data.DepModOrTailExpr = Tail.get(); + Data.DepModOrTailExpr = Tail.isUsable() ? Tail.get() : nullptr; Data.ColonLoc = ConsumeToken(); TPA.Commit(); } else { // Colon not found, parse only list of variables. TPA.Revert(); - if (Kind == OMPC_allocate && - Data.AllocClauseModifier == OMPC_ALLOCATE_allocator) { + if (Kind == OMPC_allocate && Data.AllocClauseModifiers.size()) { SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); - Diag(Tok, diag::err_modifier_expected_colon) << "allocator"; + Diag(Tok, diag::err_modifier_expected_colon) << "allocate clause"; } } } else { diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 66ff92f554fc42..9b77031ca16670 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5285,6 +5285,7 @@ static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, } for (OMPClause *C : AllocateRange) { auto *AC = cast<OMPAllocateClause>(C); + // TODO: Check alignment? if (S.getLangOpts().OpenMP >= 50 && !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && @@ -5320,6 +5321,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 +5333,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 +15618,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 +17156,25 @@ 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 (auto NumModifiers = Data.AllocClauseModifiers.size()) { + Modifier1 = Data.AllocClauseModifiers[0]; + Modifier1Loc = Data.AllocClauseModifiersLoc[0]; + assert(NumModifiers <= 2 && "More allocate modifiers than expected"); + if (NumModifiers == 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, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 0121be81bc6acd..f0958168d0c511 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2075,15 +2075,18 @@ class TreeTransform { /// /// By default, performs semantic analysis to build the new OpenMP clause. /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPAllocateClause(Expr *Allocate, - OpenMPAllocateClauseModifier ACModifier, - ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc) { + OMPClause * + RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment, + OpenMPAllocateClauseModifier FirstModifier, + SourceLocation FirstModifierLoc, + OpenMPAllocateClauseModifier SecondModifier, + SourceLocation SecondModifierLoc, + ArrayRef<Expr *> VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation ColonLoc, + SourceLocation EndLoc) { return getSema().OpenMP().ActOnOpenMPAllocateClause( - Allocate, ACModifier, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc); + Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier, + SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc); } /// Build a new OpenMP 'num_teams' clause. @@ -11206,6 +11209,13 @@ TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) { return nullptr; Allocator = AllocatorRes.get(); } + Expr *Alignment = C->getAlignment(); + if (Alignment) { + ExprResult AlignmentRes = getDerived().TransformExpr(Alignment); + if (AlignmentRes.isInvalid()) + return nullptr; + Alignment = AlignmentRes.get(); + } llvm::SmallVector<Expr *, 16> Vars; Vars.reserve(C->varlist_size()); for (auto *VE : C->varlist()) { @@ -11215,7 +11225,9 @@ TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) { Vars.push_back(EVar.get()); } return getDerived().RebuildOMPAllocateClause( - Allocator, C->getAllocatorModifier(), Vars, C->getBeginLoc(), + Allocator, Alignment, C->getFirstAllocateModifier(), + C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(), + C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc()); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index fccd79bf745203..8f105102563a22 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11824,10 +11824,14 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { } void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) { - C->setAllocatorModifier(Record.readEnum<OpenMPAllocateClauseModifier>()); + C->setFirstAllocateModifier( + static_cast<OpenMPAllocateClauseModifier>(Record.readInt())); + C->setSecondAllocateModifier( + static_cast<OpenMPAllocateClauseModifier>(Record.readInt())); C->setLParenLoc(Record.readSourceLocation()); C->setColonLoc(Record.readSourceLocation()); C->setAllocator(Record.readSubExpr()); + C->setAlignment(Record.readSubExpr()); unsigned NumVars = C->varlist_size(); SmallVector<Expr *, 16> Vars; Vars.reserve(NumVars); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 7fa9322e7551f7..3485052bbc4fdc 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -7924,10 +7924,12 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) { Record.push_back(C->varlist_size()); - Record.writeEnum(C->getAllocatorModifier()); + Record.push_back(C->getFirstAllocateModifier()); + Record.push_back(C->getSecondAllocateModifier()); Record.AddSourceLocation(C->getLParenLoc()); Record.AddSourceLocation(C->getColonLoc()); Record.AddStmt(C->getAllocator()); + Record.AddStmt(C->getAlignment()); for (auto *VE : C->varlist()) Record.AddStmt(VE); } diff --git a/clang/test/OpenMP/allocate_allocator_modifier_codegen.cpp b/clang/test/OpenMP/allocate_allocator_modifier_codegen.cpp deleted file mode 100644 index 1bf927ebb2eb7c..00000000000000 --- a/clang/test/OpenMP/allocate_allocator_modifier_codegen.cpp +++ /dev/null @@ -1,255 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ --version 5 -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix CHECK-TLS %s - -// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s -// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s -// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s -// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s -// expected-no-diagnostics - -#ifndef HEADER -#define HEADER - -enum omp_allocator_handle_t { - omp_null_allocator = 0, - omp_default_mem_alloc = 1, - omp_large_cap_mem_alloc = 2, - omp_const_mem_alloc = 3, - omp_high_bw_mem_alloc = 4, - omp_low_lat_mem_alloc = 5, - omp_cgroup_mem_alloc = 6, - omp_pteam_mem_alloc = 7, - omp_thread_mem_alloc = 8, - KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__ -}; - -template <class T> -struct ST { - static T m; -}; - -template <class T, omp_allocator_handle_t TY> T foo() { - T v; - #pragma omp scope private(v) allocate(allocator(TY):v) - v = ST<T>::m; - return v; -} - -namespace ns { -int a; -} - -int main() { - static int a; - static int temp; - #pragma omp scope private(ns::a) allocate(allocator(omp_pteam_mem_alloc):ns::a) - ns::a++; - - #pragma omp scope private(a) allocate(allocator(omp_thread_mem_alloc):a) - a = 2; - double b = 3; - #pragma omp scope private(temp) allocate(temp) - temp += foo<int, omp_cgroup_mem_alloc>(); - return temp+ns::a; -} - -extern template int ST<int>::m; - -int b; - -void bar(int a, float &z) { - #pragma omp scope private(a,z) allocate(allocator(omp_default_mem_alloc):a,z) - a += b; -} -#endif -// CHECK-LABEL: define dso_local noundef i32 @main( -// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 -// CHECK-NEXT: [[B:%.*]] = alloca double, align 8 -// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) -// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// CHECK-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 7 to ptr)) -// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4 -// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 -// CHECK-NEXT: store i32 [[INC]], ptr [[DOTA__VOID_ADDR]], align 4 -// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 7 to ptr)) -// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[TMP0]]) -// CHECK-NEXT: [[DOTA__VOID_ADDR1:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 8 to ptr)) -// CHECK-NEXT: store i32 2, ptr [[DOTA__VOID_ADDR1]], align 4 -// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR1]], ptr inttoptr (i64 8 to ptr)) -// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) -// CHECK-NEXT: store double 3.000000e+00, ptr [[B]], align 8 -// CHECK-NEXT: [[DOTTEMP__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr null) -// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v() -// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTTEMP__VOID_ADDR]], align 4 -// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[CALL]] -// CHECK-NEXT: store i32 [[ADD]], ptr [[DOTTEMP__VOID_ADDR]], align 4 -// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTTEMP__VOID_ADDR]], ptr null) -// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) -// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZZ4mainE4temp, align 4 -// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr @_ZN2ns1aE, align 4 -// CHECK-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP3]], [[TMP4]] -// CHECK-NEXT: ret i32 [[ADD2]] -// -// -// CHECK-LABEL: define linkonce_odr noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v( -// CHECK-SAME: ) #[[ATTR3:[0-9]+]] comdat { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[V:%.*]] = alloca i32, align 4 -// CHECK-NEXT: [[V1:%.*]] = alloca i32, align 4 -// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZN2STIiE1mE, align 4 -// CHECK-NEXT: store i32 [[TMP1]], ptr [[V1]], align 4 -// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[V]], align 4 -// CHECK-NEXT: ret i32 [[TMP2]] -// -// -// CHECK-LABEL: define dso_local void @_Z3bariRf( -// CHECK-SAME: i32 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[Z:%.*]]) #[[ATTR3]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: [[Z_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[TMP:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-NEXT: store ptr [[Z]], ptr [[Z_ADDR]], align 8 -// CHECK-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr)) -// CHECK-NEXT: [[DOTZ__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr)) -// CHECK-NEXT: store ptr [[DOTZ__VOID_ADDR]], ptr [[TMP]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @b, align 4 -// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4 -// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[TMP1]] -// CHECK-NEXT: store i32 [[ADD]], ptr [[DOTA__VOID_ADDR]], align 4 -// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTZ__VOID_ADDR]], ptr inttoptr (i64 1 to ptr)) -// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 1 to ptr)) -// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) -// CHECK-NEXT: ret void -// -// -// CHECK-TLS-LABEL: define dso_local noundef i32 @main( -// CHECK-TLS-SAME: ) #[[ATTR0:[0-9]+]] { -// CHECK-TLS-NEXT: [[ENTRY:.*:]] -// CHECK-TLS-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 -// CHECK-TLS-NEXT: [[B:%.*]] = alloca double, align 8 -// CHECK-TLS-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) -// CHECK-TLS-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// CHECK-TLS-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 7 to ptr)) -// CHECK-TLS-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4 -// CHECK-TLS-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 -// CHECK-TLS-NEXT: store i32 [[INC]], ptr [[DOTA__VOID_ADDR]], align 4 -// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 7 to ptr)) -// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[TMP0]]) -// CHECK-TLS-NEXT: [[DOTA__VOID_ADDR1:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 8 to ptr)) -// CHECK-TLS-NEXT: store i32 2, ptr [[DOTA__VOID_ADDR1]], align 4 -// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR1]], ptr inttoptr (i64 8 to ptr)) -// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) -// CHECK-TLS-NEXT: store double 3.000000e+00, ptr [[B]], align 8 -// CHECK-TLS-NEXT: [[DOTTEMP__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr null) -// CHECK-TLS-NEXT: [[CALL:%.*]] = call noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v() -// CHECK-TLS-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTTEMP__VOID_ADDR]], align 4 -// CHECK-TLS-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[CALL]] -// CHECK-TLS-NEXT: store i32 [[ADD]], ptr [[DOTTEMP__VOID_ADDR]], align 4 -// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTTEMP__VOID_ADDR]], ptr null) -// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) -// CHECK-TLS-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZZ4mainE4temp, align 4 -// CHECK-TLS-NEXT: [[TMP4:%.*]] = load i32, ptr @_ZN2ns1aE, align 4 -// CHECK-TLS-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP3]], [[TMP4]] -// CHECK-TLS-NEXT: ret i32 [[ADD2]] -// -// -// CHECK-TLS-LABEL: define linkonce_odr noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v( -// CHECK-TLS-SAME: ) #[[ATTR3:[0-9]+]] comdat { -// CHECK-TLS-NEXT: [[ENTRY:.*:]] -// CHECK-TLS-NEXT: [[V:%.*]] = alloca i32, align 4 -// CHECK-TLS-NEXT: [[V1:%.*]] = alloca i32, align 4 -// CHECK-TLS-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-TLS-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZN2STIiE1mE, align 4 -// CHECK-TLS-NEXT: store i32 [[TMP1]], ptr [[V1]], align 4 -// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) -// CHECK-TLS-NEXT: [[TMP2:%.*]] = load i32, ptr [[V]], align 4 -// CHECK-TLS-NEXT: ret i32 [[TMP2]] -// -// -// CHECK-TLS-LABEL: define dso_local void @_Z3bariRf( -// CHECK-TLS-SAME: i32 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[Z:%.*]]) #[[ATTR3]] { -// CHECK-TLS-NEXT: [[ENTRY:.*:]] -// CHECK-TLS-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 -// CHECK-TLS-NEXT: [[Z_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-TLS-NEXT: [[TMP:%.*]] = alloca ptr, align 8 -// CHECK-TLS-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-TLS-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS-NEXT: store ptr [[Z]], ptr [[Z_ADDR]], align 8 -// CHECK-TLS-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr)) -// CHECK-TLS-NEXT: [[DOTZ__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr)) -// CHECK-TLS-NEXT: store ptr [[DOTZ__VOID_ADDR]], ptr [[TMP]], align 8 -// CHECK-TLS-NEXT: [[TMP1:%.*]] = load i32, ptr @b, align 4 -// CHECK-TLS-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4 -// CHECK-TLS-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[TMP1]] -// CHECK-TLS-NEXT: store i32 [[ADD]], ptr [[DOTA__VOID_ADDR]], align 4 -// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTZ__VOID_ADDR]], ptr inttoptr (i64 1 to ptr)) -// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 1 to ptr)) -// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) -// CHECK-TLS-NEXT: ret void -// -// -// SIMD-ONLY0-LABEL: define dso_local noundef i32 @main( -// SIMD-ONLY0-SAME: ) #[[ATTR0:[0-9]+]] { -// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] -// SIMD-ONLY0-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 -// SIMD-ONLY0-NEXT: [[A:%.*]] = alloca i32, align 4 -// SIMD-ONLY0-NEXT: [[A1:%.*]] = alloca i32, align 4 -// SIMD-ONLY0-NEXT: [[B:%.*]] = alloca double, align 8 -// SIMD-ONLY0-NEXT: [[TEMP:%.*]] = alloca i32, align 4 -// SIMD-ONLY0-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 -// SIMD-ONLY0-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1 -// SIMD-ONLY0-NEXT: store i32 [[INC]], ptr [[A]], align 4 -// SIMD-ONLY0-NEXT: store i32 2, ptr [[A1]], align 4 -// SIMD-ONLY0-NEXT: store double 3.000000e+00, ptr [[B]], align 8 -// SIMD-ONLY0-NEXT: [[CALL:%.*]] = call noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v() -// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load i32, ptr [[TEMP]], align 4 -// SIMD-ONLY0-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[CALL]] -// SIMD-ONLY0-NEXT: store i32 [[ADD]], ptr [[TEMP]], align 4 -// SIMD-ONLY0-NEXT: [[TMP2:%.*]] = load i32, ptr @_ZZ4mainE4temp, align 4 -// SIMD-ONLY0-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZN2ns1aE, align 4 -// SIMD-ONLY0-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP2]], [[TMP3]] -// SIMD-ONLY0-NEXT: ret i32 [[ADD2]] -// -// -// SIMD-ONLY0-LABEL: define linkonce_odr noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v( -// SIMD-ONLY0-SAME: ) #[[ATTR1:[0-9]+]] comdat { -// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] -// SIMD-ONLY0-NEXT: [[V:%.*]] = alloca i32, align 4 -// SIMD-ONLY0-NEXT: [[V1:%.*]] = alloca i32, align 4 -// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load i32, ptr @_ZN2STIiE1mE, align 4 -// SIMD-ONLY0-NEXT: store i32 [[TMP0]], ptr [[V1]], align 4 -// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load i32, ptr [[V]], align 4 -// SIMD-ONLY0-NEXT: ret i32 [[TMP1]] -// -// -// SIMD-ONLY0-LABEL: define dso_local void @_Z3bariRf( -// SIMD-ONLY0-SAME: i32 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[Z:%.*]]) #[[ATTR1]] { -// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] -// SIMD-ONLY0-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 -// SIMD-ONLY0-NEXT: [[Z_ADDR:%.*]] = alloca ptr, align 8 -// SIMD-ONLY0-NEXT: [[A1:%.*]] = alloca i32, align 4 -// SIMD-ONLY0-NEXT: [[Z2:%.*]] = alloca float, align 4 -// SIMD-ONLY0-NEXT: [[TMP:%.*]] = alloca ptr, align 8 -// SIMD-ONLY0-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD-ONLY0-NEXT: store ptr [[Z]], ptr [[Z_ADDR]], align 8 -// SIMD-ONLY0-NEXT: store ptr [[Z2]], ptr [[TMP]], align 8 -// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load i32, ptr @b, align 4 -// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load i32, ptr [[A1]], align 4 -// SIMD-ONLY0-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[TMP0]] -// SIMD-ONLY0-NEXT: store i32 [[ADD]], ptr [[A1]], align 4 -// SIMD-ONLY0-NEXT: ret void -// diff --git a/clang/test/OpenMP/allocate_allocator_modifier_messages.cpp b/clang/test/OpenMP/allocate_allocator_modifier_messages.cpp deleted file mode 100644 index 160c4996c12195..00000000000000 --- a/clang/test/OpenMP/allocate_allocator_modifier_messages.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 %s - -typedef enum omp_allocator_handle_t { - omp_null_allocator = 0, - omp_default_mem_alloc = 1, - omp_large_cap_mem_alloc = 2, - omp_const_mem_alloc = 3, - omp_high_bw_mem_alloc = 4, - omp_low_lat_mem_alloc = 5, - omp_cgroup_mem_alloc = 6, - omp_pteam_mem_alloc = 7, - omp_thread_mem_alloc = 8, -} omp_allocator_handle_t; - -int myAlloc() { - return 100; -} - -int main() { - int a, b, c; - // expected-error@+4 {{expected '('}} - // expected-error@+3 {{expected expression}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp scope private(c) allocate(allocator - // expected-error@+6 {{expected expression}} - // expected-error@+5 {{expected ')'}} - // expected-note@+4 {{to match this '('}} - // expected-error@+3 {{expected expression}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp scope private(c) allocate(allocator( - // expected-error@+4 {{expected expression}} - // expected-error@+3 {{expected expression}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp scope private(c) allocate(allocator() - // expected-error@+2 {{expected expression}} - // expected-error@+1 {{expected expression}} - #pragma omp scope private(c) allocate(allocator()) - // expected-error@+6 {{expected ')'}} - // expected-note@+5 {{to match this '('}} - // expected-error@+4 {{missing ':' after allocator modifier}} - // expected-error@+3 {{expected expression}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp scope private(c) allocate(allocator(omp_default_mem_alloc - // expected-error@+6 {{missing ':' after allocator modifier}} - // expected-error@+5 {{expected expression}} - // expected-error@+4 {{expected ')'}} - // expected-note@+3 {{to match this '('}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp scope private(c) allocate(allocator(omp_large_cap_mem_alloc: - // expected-error@+4 {{missing ':' after allocator modifier}} - // expected-error@+3 {{expected expression}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp scope private(c) allocate(allocator(omp_const_mem_alloc) - // expected-error@+2 {{missing ':' after allocator modifier}} - // expected-error@+1 {{expected expression}} - #pragma omp scope private(c) allocate(allocator(omp_high_bw_mem_alloc)) - // expected-error@+1 {{expected expression}} - #pragma omp scope private(c) allocate(allocator(omp_low_lat_mem_alloc):) - // expected-error@+6 {{expected ')'}} - // expected-note@+5 {{to match this '('}} - // expected-error@+4 {{missing ':' after allocator modifier}} - // expected-error@+3 {{expected expression}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp scope private(c) allocate(allocator(omp_cgroup_mem_alloc:) - // expected-error@+4 {{expected ')'}} - // expected-note@+3 {{to match this '('}} - // expected-error@+2 {{missing ':' after allocator modifier}} - // expected-error@+1 {{expected expression}} - #pragma omp scope private(c) allocate(allocator(omp_pteam_mem_alloc:)) - // expected-error@+4 {{expected ')'}} - // expected-note@+3 {{to match this '('}} - // expected-error@+2 {{missing ':' after allocator modifier}} - // expected-error@+1 {{expected expression}} - #pragma omp scope private(c) allocate(allocator(omp_thread_mem_alloc:c)) - // expected-error@+1 {{expected variable name}} - #pragma omp scope private(c) allocate(allocator(omp_const_mem_alloc):1) - // expected-error@+1 {{expected variable name}} - #pragma omp scope private(c) allocate(allocator(omp_const_mem_alloc):-10) - // expected-error@+4 {{expected ',' or ')' in 'allocate' clause}} - // expected-error@+3 {{expected ')'}} - // expected-warning@+2 {{extra tokens at the end of '#pragma omp scope' are ignored}} - // expected-note@+1 {{to match this '('}} - #pragma omp scope private(a,b,c) allocate(allocator(omp_const_mem_alloc):c:b;a) - // expected-error@+1 {{initializing 'const omp_allocator_handle_t' with an expression of incompatible type 'int'}} - #pragma omp scope private(c,a,b) allocate(allocator(myAlloc()):a,b,c) - // expected-error@+2 {{missing ':' after allocator modifier}} - // expected-error@+1 {{expected expression}} - #pragma omp scope private(c) allocate(allocator(omp_default_mem_alloc);c) - ++a; -} diff --git a/clang/test/OpenMP/allocate_allocator_modifier_ast_print.cpp b/clang/test/OpenMP/allocate_modifiers_ast_print.cpp similarity index 51% rename from clang/test/OpenMP/allocate_allocator_modifier_ast_print.cpp rename to clang/test/OpenMP/allocate_modifiers_ast_print.cpp index 15f3f1dd9bbb92..436647be75da3f 100644 --- a/clang/test/OpenMP/allocate_allocator_modifier_ast_print.cpp +++ b/clang/test/OpenMP/allocate_modifiers_ast_print.cpp @@ -41,6 +41,11 @@ int main() { #pragma omp scope private(c,a,b) allocate(allocator(myAlloc()):a,b,c) c++; #pragma omp scope private(c,a,b,d) allocate(myAlloc():a,b,c,d) + a++; + #pragma omp scope private(a,b) allocate(align(2), allocator(omp_const_mem_alloc):a,b) + b++; + #pragma omp scope private(c,a,b) allocate(allocator(myAlloc()), align(8) :a,b,c) + c++; // DUMP: FunctionDecl {{.*}} // DUMP: DeclRefExpr {{.*}}'omp_allocator_handle_t' EnumConstant {{.*}}'omp_large_cap_mem_alloc' 'omp_allocator_handle_t' // DUMP: FunctionDecl {{.*}} @@ -76,11 +81,81 @@ int main() { // DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int' // DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'c' 'int' // DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'d' 'int' +// DUMP: OMPScopeDirective {{.*}} +// DUMP: OMPPrivateClause {{.*}} +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int' +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int' +// DUMP: OMPAllocateClause {{.*}} +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int' +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int' +// DUMP: OMPScopeDirective {{.*}} +// DUMP: OMPPrivateClause {{.*}} +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'c' 'int' +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int' +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int' +// DUMP: OMPAllocateClause {{.*}} +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int' +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int' +// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'c' 'int' // PRINT: #pragma omp scope private(a) allocate(omp_const_mem_alloc: a) // PRINT: #pragma omp scope private(a,b) allocate(allocator(omp_const_mem_alloc): a,b) // PRINT: #pragma omp scope private(c,a,b) allocate(allocator(myAlloc()): a,b,c) // PRINT: #pragma omp scope private(c,a,b,d) allocate(myAlloc(): a,b,c,d) - d++; +// PRINT: #pragma omp scope private(a,b) allocate(align(2), allocator(omp_const_mem_alloc): a,b) +// PRINT: #pragma omp scope private(c,a,b) allocate(allocator(myAlloc()), align(8): a,b,c) return a+b+c+d; } + +template<typename T, unsigned al> +void templated_func(T n) { + int a, b; + T mem = n; + #pragma omp scope private(mem,a,b) allocate(allocator(n),align(al):mem,a,b) + a += b; + #pragma omp scope allocate(allocator(n),align(al):mem,a,b) private(mem,a,b) + a += b; +} + +void template_inst(int n) { + templated_func<omp_allocator_handle_t, 4>(omp_const_mem_alloc); + return; +} +// DUMP: FunctionTemplateDecl{{.*}}templated_func +// DUMP: FunctionDecl{{.*}}templated_func 'void (T)' +// DUMP: OMPScopeDirective +// DUMP: OMPPrivateClause +// DUMP: OMPAllocateClause +// DUMP: DeclRefExpr{{.*}}'T' lvalue Var{{.*}}'mem' 'T' +// DUMP: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'a' 'int' +// DUMP: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'b' 'int' +// DUMP: OMPScopeDirective +// DUMP: OMPAllocateClause +// DUMP: DeclRefExpr{{.*}}'T' lvalue Var{{.*}}'mem' 'T' +// DUMP: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'a' 'int' +// DUMP: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'b' 'int' +// DUMP: OMPPrivateClause + +// DUMP: FunctionDecl{{.*}}used templated_func 'void (omp_allocator_handle_t)' implicit_instantiation +// DUMP: TemplateArgument type 'omp_allocator_handle_t' +// DUMP: EnumType{{.*}}'omp_allocator_handle_t' +// DUMP: Enum{{.*}}'omp_allocator_handle_t' +// DUMP: TemplateArgument integral '4U' + +// DUMP: OMPScopeDirective +// DUMP: OMPPrivateClause +// DUMP: OMPAllocateClause +// DUMP: DeclRefExpr{{.*}}'omp_allocator_handle_t' lvalue Var{{.*}}'mem' 'omp_allocator_handle_t' +// DUMP: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'a' 'int' +// DUMP: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'b' 'int' +// DUMP: OMPScopeDirective +// DUMP: OMPAllocateClause +// DUMP: DeclRefExpr{{.*}}'omp_allocator_handle_t' lvalue Var{{.*}}'mem' 'omp_allocator_handle_t' +// DUMP: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'a' 'int' +// DUMP: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'b' 'int' +// DUMP: OMPPrivateClause +// PRINT: #pragma omp scope private(mem,a,b) allocate(allocator(n), align(al): mem,a,b) +// PRINT: #pragma omp scope allocate(allocator(n), align(al): mem,a,b) private(mem,a,b) +// PRINT: #pragma omp scope private(mem,a,b) allocate(allocator(n), align(4U): mem,a,b) +// PRINT: #pragma omp scope allocate(allocator(n), align(4U): mem,a,b) private(mem,a,b) + #endif diff --git a/clang/test/OpenMP/allocate_modifiers_codegen.cpp b/clang/test/OpenMP/allocate_modifiers_codegen.cpp new file mode 100644 index 00000000000000..d798e9b3435f0e --- /dev/null +++ b/clang/test/OpenMP/allocate_modifiers_codegen.cpp @@ -0,0 +1,409 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ --version 5 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix CHECK-TLS %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +enum omp_allocator_handle_t { + omp_null_allocator = 0, + omp_default_mem_alloc = 1, + omp_large_cap_mem_alloc = 2, + omp_const_mem_alloc = 3, + omp_high_bw_mem_alloc = 4, + omp_low_lat_mem_alloc = 5, + omp_cgroup_mem_alloc = 6, + omp_pteam_mem_alloc = 7, + omp_thread_mem_alloc = 8, + KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__ +}; + +template <class T> +struct ST { + static T m; +}; + +template <class T, omp_allocator_handle_t TY, unsigned al> T foo() { + T v; + #pragma omp scope private(v) allocate(allocator(TY):v) + v = ST<T>::m; + #pragma omp scope private(v) allocate(align(al), allocator(TY):v) + ++v; + return v; +} + +namespace ns { +int a; +} + +omp_allocator_handle_t foo(); + +int main() { + static int a; + static int temp; + int v; + #pragma omp scope private(ns::a) allocate(allocator(omp_pteam_mem_alloc):ns::a) + ns::a++; + #pragma omp scope private(a) allocate(align(8),allocator(omp_thread_mem_alloc):a) + a = 2; + #pragma omp scope private(v) allocate(align(1) : v) + ++v; + #pragma omp scope private(v) allocate(allocator(omp_default_mem_alloc) : v) + ++v; + #pragma omp scope private(v) allocate(allocator(omp_large_cap_mem_alloc), align(8) : v) + ++v; + #pragma omp scope private(v) allocate(align(4) : v) + ++v; + #pragma omp scope private(v) allocate(align(2), allocator(omp_default_mem_alloc) : v) + ++v; + #pragma omp scope private(v) allocate(align(8), allocator(foo()) : v) + ++v; + + double b = 3; + #pragma omp scope private(temp) allocate(temp) + temp += foo<int, omp_cgroup_mem_alloc, 8>(); + return temp+ns::a; +} + +extern template int ST<int>::m; + +const int b = 8; + +void bar(int a, float &z) { + #pragma omp scope private(a,z) allocate(align(b), allocator(omp_default_mem_alloc) : a,z) + a += b + z; +} +#endif +// CHECK-LABEL: define dso_local noundef i32 @main( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[V:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[B:%.*]] = alloca double, align 8 +// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) +// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 7 to ptr)) +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4 +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 +// CHECK-NEXT: store i32 [[INC]], ptr [[DOTA__VOID_ADDR]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 7 to ptr)) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[TMP0]]) +// CHECK-NEXT: [[DOTA__VOID_ADDR1:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 8 to ptr)) +// CHECK-NEXT: store i32 2, ptr [[DOTA__VOID_ADDR1]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR1]], ptr inttoptr (i64 8 to ptr)) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: [[DOTV__VOID_ADDR:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 4, i64 4, ptr null) +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTV__VOID_ADDR]], align 4 +// CHECK-NEXT: [[INC2:%.*]] = add nsw i32 [[TMP2]], 1 +// CHECK-NEXT: store i32 [[INC2]], ptr [[DOTV__VOID_ADDR]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR]], ptr null) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: [[DOTV__VOID_ADDR3:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr)) +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTV__VOID_ADDR3]], align 4 +// CHECK-NEXT: [[INC4:%.*]] = add nsw i32 [[TMP3]], 1 +// CHECK-NEXT: store i32 [[INC4]], ptr [[DOTV__VOID_ADDR3]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR3]], ptr inttoptr (i64 1 to ptr)) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: [[DOTV__VOID_ADDR5:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 2 to ptr)) +// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTV__VOID_ADDR5]], align 4 +// CHECK-NEXT: [[INC6:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK-NEXT: store i32 [[INC6]], ptr [[DOTV__VOID_ADDR5]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR5]], ptr inttoptr (i64 2 to ptr)) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: [[DOTV__VOID_ADDR7:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 4, i64 4, ptr null) +// CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTV__VOID_ADDR7]], align 4 +// CHECK-NEXT: [[INC8:%.*]] = add nsw i32 [[TMP5]], 1 +// CHECK-NEXT: store i32 [[INC8]], ptr [[DOTV__VOID_ADDR7]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR7]], ptr null) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: [[DOTV__VOID_ADDR9:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 4, i64 4, ptr inttoptr (i64 1 to ptr)) +// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTV__VOID_ADDR9]], align 4 +// CHECK-NEXT: [[INC10:%.*]] = add nsw i32 [[TMP6]], 1 +// CHECK-NEXT: store i32 [[INC10]], ptr [[DOTV__VOID_ADDR9]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR9]], ptr inttoptr (i64 1 to ptr)) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: [[CALL:%.*]] = call noundef i64 @_Z3foov() +// CHECK-NEXT: [[CONV:%.*]] = inttoptr i64 [[CALL]] to ptr +// CHECK-NEXT: [[DOTV__VOID_ADDR11:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr [[CONV]]) +// CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTV__VOID_ADDR11]], align 4 +// CHECK-NEXT: [[INC12:%.*]] = add nsw i32 [[TMP7]], 1 +// CHECK-NEXT: store i32 [[INC12]], ptr [[DOTV__VOID_ADDR11]], align 4 +// CHECK-NEXT: [[CALL13:%.*]] = call noundef i64 @_Z3foov() +// CHECK-NEXT: [[CONV14:%.*]] = inttoptr i64 [[CALL13]] to ptr +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR11]], ptr [[CONV14]]) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: store double 3.000000e+00, ptr [[B]], align 8 +// CHECK-NEXT: [[DOTTEMP__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr null) +// CHECK-NEXT: [[CALL15:%.*]] = call noundef i32 @_Z3fooIiL22omp_allocator_handle_t6ELj8EET_v() +// CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTTEMP__VOID_ADDR]], align 4 +// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP8]], [[CALL15]] +// CHECK-NEXT: store i32 [[ADD]], ptr [[DOTTEMP__VOID_ADDR]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTTEMP__VOID_ADDR]], ptr null) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZZ4mainE4temp, align 4 +// CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr @_ZN2ns1aE, align 4 +// CHECK-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP9]], [[TMP10]] +// CHECK-NEXT: ret i32 [[ADD16]] +// +// +// CHECK-LABEL: define linkonce_odr noundef i32 @_Z3fooIiL22omp_allocator_handle_t6ELj8EET_v( +// CHECK-SAME: ) #[[ATTR4:[0-9]+]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[V:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) +// CHECK-NEXT: [[DOTV__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 6 to ptr)) +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZN2STIiE1mE, align 4 +// CHECK-NEXT: store i32 [[TMP1]], ptr [[DOTV__VOID_ADDR]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR]], ptr inttoptr (i64 6 to ptr)) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: [[DOTV__VOID_ADDR1:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 6 to ptr)) +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTV__VOID_ADDR1]], align 4 +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1 +// CHECK-NEXT: store i32 [[INC]], ptr [[DOTV__VOID_ADDR1]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR1]], ptr inttoptr (i64 6 to ptr)) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[V]], align 4 +// CHECK-NEXT: ret i32 [[TMP3]] +// +// +// CHECK-LABEL: define dso_local void @_Z3bariRf( +// CHECK-SAME: i32 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[Z:%.*]]) #[[ATTR4]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[Z_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) +// CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 +// CHECK-NEXT: store ptr [[Z]], ptr [[Z_ADDR]], align 8 +// CHECK-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 1 to ptr)) +// CHECK-NEXT: [[DOTZ__VOID_ADDR:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 1 to ptr)) +// CHECK-NEXT: store ptr [[DOTZ__VOID_ADDR]], ptr [[TMP]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[TMP1]], align 4 +// CHECK-NEXT: [[ADD:%.*]] = fadd float 8.000000e+00, [[TMP2]] +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP3]] to float +// CHECK-NEXT: [[ADD1:%.*]] = fadd float [[CONV]], [[ADD]] +// CHECK-NEXT: [[CONV2:%.*]] = fptosi float [[ADD1]] to i32 +// CHECK-NEXT: store i32 [[CONV2]], ptr [[DOTA__VOID_ADDR]], align 4 +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTZ__VOID_ADDR]], ptr inttoptr (i64 1 to ptr)) +// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 1 to ptr)) +// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-NEXT: ret void +// +// +// CHECK-TLS-LABEL: define dso_local noundef i32 @main( +// CHECK-TLS-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-TLS-NEXT: [[ENTRY:.*:]] +// CHECK-TLS-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK-TLS-NEXT: [[V:%.*]] = alloca i32, align 4 +// CHECK-TLS-NEXT: [[B:%.*]] = alloca double, align 8 +// CHECK-TLS-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) +// CHECK-TLS-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK-TLS-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 7 to ptr)) +// CHECK-TLS-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4 +// CHECK-TLS-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 +// CHECK-TLS-NEXT: store i32 [[INC]], ptr [[DOTA__VOID_ADDR]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 7 to ptr)) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[DOTA__VOID_ADDR1:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 8 to ptr)) +// CHECK-TLS-NEXT: store i32 2, ptr [[DOTA__VOID_ADDR1]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR1]], ptr inttoptr (i64 8 to ptr)) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[DOTV__VOID_ADDR:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 4, i64 4, ptr null) +// CHECK-TLS-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTV__VOID_ADDR]], align 4 +// CHECK-TLS-NEXT: [[INC2:%.*]] = add nsw i32 [[TMP2]], 1 +// CHECK-TLS-NEXT: store i32 [[INC2]], ptr [[DOTV__VOID_ADDR]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR]], ptr null) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[DOTV__VOID_ADDR3:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr)) +// CHECK-TLS-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTV__VOID_ADDR3]], align 4 +// CHECK-TLS-NEXT: [[INC4:%.*]] = add nsw i32 [[TMP3]], 1 +// CHECK-TLS-NEXT: store i32 [[INC4]], ptr [[DOTV__VOID_ADDR3]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR3]], ptr inttoptr (i64 1 to ptr)) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[DOTV__VOID_ADDR5:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 2 to ptr)) +// CHECK-TLS-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTV__VOID_ADDR5]], align 4 +// CHECK-TLS-NEXT: [[INC6:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK-TLS-NEXT: store i32 [[INC6]], ptr [[DOTV__VOID_ADDR5]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR5]], ptr inttoptr (i64 2 to ptr)) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[DOTV__VOID_ADDR7:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 4, i64 4, ptr null) +// CHECK-TLS-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTV__VOID_ADDR7]], align 4 +// CHECK-TLS-NEXT: [[INC8:%.*]] = add nsw i32 [[TMP5]], 1 +// CHECK-TLS-NEXT: store i32 [[INC8]], ptr [[DOTV__VOID_ADDR7]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR7]], ptr null) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[DOTV__VOID_ADDR9:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 4, i64 4, ptr inttoptr (i64 1 to ptr)) +// CHECK-TLS-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTV__VOID_ADDR9]], align 4 +// CHECK-TLS-NEXT: [[INC10:%.*]] = add nsw i32 [[TMP6]], 1 +// CHECK-TLS-NEXT: store i32 [[INC10]], ptr [[DOTV__VOID_ADDR9]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR9]], ptr inttoptr (i64 1 to ptr)) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[CALL:%.*]] = call noundef i64 @_Z3foov() +// CHECK-TLS-NEXT: [[CONV:%.*]] = inttoptr i64 [[CALL]] to ptr +// CHECK-TLS-NEXT: [[DOTV__VOID_ADDR11:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr [[CONV]]) +// CHECK-TLS-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTV__VOID_ADDR11]], align 4 +// CHECK-TLS-NEXT: [[INC12:%.*]] = add nsw i32 [[TMP7]], 1 +// CHECK-TLS-NEXT: store i32 [[INC12]], ptr [[DOTV__VOID_ADDR11]], align 4 +// CHECK-TLS-NEXT: [[CALL13:%.*]] = call noundef i64 @_Z3foov() +// CHECK-TLS-NEXT: [[CONV14:%.*]] = inttoptr i64 [[CALL13]] to ptr +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR11]], ptr [[CONV14]]) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: store double 3.000000e+00, ptr [[B]], align 8 +// CHECK-TLS-NEXT: [[DOTTEMP__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr null) +// CHECK-TLS-NEXT: [[CALL15:%.*]] = call noundef i32 @_Z3fooIiL22omp_allocator_handle_t6ELj8EET_v() +// CHECK-TLS-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTTEMP__VOID_ADDR]], align 4 +// CHECK-TLS-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP8]], [[CALL15]] +// CHECK-TLS-NEXT: store i32 [[ADD]], ptr [[DOTTEMP__VOID_ADDR]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTTEMP__VOID_ADDR]], ptr null) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZZ4mainE4temp, align 4 +// CHECK-TLS-NEXT: [[TMP10:%.*]] = load i32, ptr @_ZN2ns1aE, align 4 +// CHECK-TLS-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP9]], [[TMP10]] +// CHECK-TLS-NEXT: ret i32 [[ADD16]] +// +// +// CHECK-TLS-LABEL: define linkonce_odr noundef i32 @_Z3fooIiL22omp_allocator_handle_t6ELj8EET_v( +// CHECK-TLS-SAME: ) #[[ATTR4:[0-9]+]] comdat { +// CHECK-TLS-NEXT: [[ENTRY:.*:]] +// CHECK-TLS-NEXT: [[V:%.*]] = alloca i32, align 4 +// CHECK-TLS-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) +// CHECK-TLS-NEXT: [[DOTV__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 6 to ptr)) +// CHECK-TLS-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZN2STIiE1mE, align 4 +// CHECK-TLS-NEXT: store i32 [[TMP1]], ptr [[DOTV__VOID_ADDR]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR]], ptr inttoptr (i64 6 to ptr)) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[DOTV__VOID_ADDR1:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 6 to ptr)) +// CHECK-TLS-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTV__VOID_ADDR1]], align 4 +// CHECK-TLS-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1 +// CHECK-TLS-NEXT: store i32 [[INC]], ptr [[DOTV__VOID_ADDR1]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTV__VOID_ADDR1]], ptr inttoptr (i64 6 to ptr)) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: [[TMP3:%.*]] = load i32, ptr [[V]], align 4 +// CHECK-TLS-NEXT: ret i32 [[TMP3]] +// +// +// CHECK-TLS-LABEL: define dso_local void @_Z3bariRf( +// CHECK-TLS-SAME: i32 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[Z:%.*]]) #[[ATTR4]] { +// CHECK-TLS-NEXT: [[ENTRY:.*:]] +// CHECK-TLS-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-TLS-NEXT: [[Z_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-TLS-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// CHECK-TLS-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) +// CHECK-TLS-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 +// CHECK-TLS-NEXT: store ptr [[Z]], ptr [[Z_ADDR]], align 8 +// CHECK-TLS-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 1 to ptr)) +// CHECK-TLS-NEXT: [[DOTZ__VOID_ADDR:%.*]] = call ptr @__kmpc_aligned_alloc(i32 [[TMP0]], i64 8, i64 4, ptr inttoptr (i64 1 to ptr)) +// CHECK-TLS-NEXT: store ptr [[DOTZ__VOID_ADDR]], ptr [[TMP]], align 8 +// CHECK-TLS-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP]], align 8 +// CHECK-TLS-NEXT: [[TMP2:%.*]] = load float, ptr [[TMP1]], align 4 +// CHECK-TLS-NEXT: [[ADD:%.*]] = fadd float 8.000000e+00, [[TMP2]] +// CHECK-TLS-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4 +// CHECK-TLS-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP3]] to float +// CHECK-TLS-NEXT: [[ADD1:%.*]] = fadd float [[CONV]], [[ADD]] +// CHECK-TLS-NEXT: [[CONV2:%.*]] = fptosi float [[ADD1]] to i32 +// CHECK-TLS-NEXT: store i32 [[CONV2]], ptr [[DOTA__VOID_ADDR]], align 4 +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTZ__VOID_ADDR]], ptr inttoptr (i64 1 to ptr)) +// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 1 to ptr)) +// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]]) +// CHECK-TLS-NEXT: ret void +// +// +// SIMD-ONLY0-LABEL: define dso_local noundef i32 @main( +// SIMD-ONLY0-SAME: ) #[[ATTR0:[0-9]+]] { +// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[V:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[A:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[A1:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[V2:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[V4:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[V6:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[V8:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[V10:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[V12:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[B:%.*]] = alloca double, align 8 +// SIMD-ONLY0-NEXT: [[TEMP:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 +// SIMD-ONLY0-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC]], ptr [[A]], align 4 +// SIMD-ONLY0-NEXT: store i32 2, ptr [[A1]], align 4 +// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load i32, ptr [[V2]], align 4 +// SIMD-ONLY0-NEXT: [[INC3:%.*]] = add nsw i32 [[TMP1]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC3]], ptr [[V2]], align 4 +// SIMD-ONLY0-NEXT: [[TMP2:%.*]] = load i32, ptr [[V4]], align 4 +// SIMD-ONLY0-NEXT: [[INC5:%.*]] = add nsw i32 [[TMP2]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC5]], ptr [[V4]], align 4 +// SIMD-ONLY0-NEXT: [[TMP3:%.*]] = load i32, ptr [[V6]], align 4 +// SIMD-ONLY0-NEXT: [[INC7:%.*]] = add nsw i32 [[TMP3]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC7]], ptr [[V6]], align 4 +// SIMD-ONLY0-NEXT: [[TMP4:%.*]] = load i32, ptr [[V8]], align 4 +// SIMD-ONLY0-NEXT: [[INC9:%.*]] = add nsw i32 [[TMP4]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC9]], ptr [[V8]], align 4 +// SIMD-ONLY0-NEXT: [[TMP5:%.*]] = load i32, ptr [[V10]], align 4 +// SIMD-ONLY0-NEXT: [[INC11:%.*]] = add nsw i32 [[TMP5]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC11]], ptr [[V10]], align 4 +// SIMD-ONLY0-NEXT: [[TMP6:%.*]] = load i32, ptr [[V12]], align 4 +// SIMD-ONLY0-NEXT: [[INC13:%.*]] = add nsw i32 [[TMP6]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC13]], ptr [[V12]], align 4 +// SIMD-ONLY0-NEXT: store double 3.000000e+00, ptr [[B]], align 8 +// SIMD-ONLY0-NEXT: [[CALL:%.*]] = call noundef i32 @_Z3fooIiL22omp_allocator_handle_t6ELj8EET_v() +// SIMD-ONLY0-NEXT: [[TMP7:%.*]] = load i32, ptr [[TEMP]], align 4 +// SIMD-ONLY0-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP7]], [[CALL]] +// SIMD-ONLY0-NEXT: store i32 [[ADD]], ptr [[TEMP]], align 4 +// SIMD-ONLY0-NEXT: [[TMP8:%.*]] = load i32, ptr @_ZZ4mainE4temp, align 4 +// SIMD-ONLY0-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZN2ns1aE, align 4 +// SIMD-ONLY0-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP8]], [[TMP9]] +// SIMD-ONLY0-NEXT: ret i32 [[ADD14]] +// +// +// SIMD-ONLY0-LABEL: define linkonce_odr noundef i32 @_Z3fooIiL22omp_allocator_handle_t6ELj8EET_v( +// SIMD-ONLY0-SAME: ) #[[ATTR1:[0-9]+]] comdat { +// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-NEXT: [[V:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[V1:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[V2:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load i32, ptr @_ZN2STIiE1mE, align 4 +// SIMD-ONLY0-NEXT: store i32 [[TMP0]], ptr [[V1]], align 4 +// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load i32, ptr [[V2]], align 4 +// SIMD-ONLY0-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC]], ptr [[V2]], align 4 +// SIMD-ONLY0-NEXT: [[TMP2:%.*]] = load i32, ptr [[V]], align 4 +// SIMD-ONLY0-NEXT: ret i32 [[TMP2]] +// +// +// SIMD-ONLY0-LABEL: define dso_local void @_Z3bariRf( +// SIMD-ONLY0-SAME: i32 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[Z:%.*]]) #[[ATTR1]] { +// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[Z_ADDR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[A1:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[Z2:%.*]] = alloca float, align 4 +// SIMD-ONLY0-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 +// SIMD-ONLY0-NEXT: store ptr [[Z]], ptr [[Z_ADDR]], align 8 +// SIMD-ONLY0-NEXT: store ptr [[Z2]], ptr [[TMP]], align 8 +// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load ptr, ptr [[TMP]], align 8 +// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load float, ptr [[TMP0]], align 4 +// SIMD-ONLY0-NEXT: [[ADD:%.*]] = fadd float 8.000000e+00, [[TMP1]] +// SIMD-ONLY0-NEXT: [[TMP2:%.*]] = load i32, ptr [[A1]], align 4 +// SIMD-ONLY0-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP2]] to float +// SIMD-ONLY0-NEXT: [[ADD3:%.*]] = fadd float [[CONV]], [[ADD]] +// SIMD-ONLY0-NEXT: [[CONV4:%.*]] = fptosi float [[ADD3]] to i32 +// SIMD-ONLY0-NEXT: store i32 [[CONV4]], ptr [[A1]], align 4 +// SIMD-ONLY0-NEXT: ret void +// diff --git a/clang/test/OpenMP/allocate_modifiers_messages.cpp b/clang/test/OpenMP/allocate_modifiers_messages.cpp new file mode 100644 index 00000000000000..6867e78a89ee90 --- /dev/null +++ b/clang/test/OpenMP/allocate_modifiers_messages.cpp @@ -0,0 +1,159 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 %s + +typedef enum omp_allocator_handle_t { + omp_null_allocator = 0, + omp_default_mem_alloc = 1, + omp_large_cap_mem_alloc = 2, + omp_const_mem_alloc = 3, + omp_high_bw_mem_alloc = 4, + omp_low_lat_mem_alloc = 5, + omp_cgroup_mem_alloc = 6, + omp_pteam_mem_alloc = 7, + omp_thread_mem_alloc = 8, +} omp_allocator_handle_t; + +int myAlloc() { + return 100; +} + +int main() { + int a, b, c; + // expected-error@+4 {{expected '('}} + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(c) allocate(allocator + // expected-error@+6 {{expected expression}} + // expected-error@+5 {{expected ')'}} + // expected-note@+4 {{to match this '('}} + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(c) allocate(allocator( + // expected-error@+4 {{expected expression}} + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(c) allocate(allocator() + // expected-error@+2 {{expected expression}} + // expected-error@+1 {{expected expression}} + #pragma omp scope private(c) allocate(allocator()) + // expected-error@+6 {{expected ')'}} + // expected-note@+5 {{to match this '('}} + // expected-error@+4 {{missing ':' after allocate clause modifier}} + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(c) allocate(allocator(omp_default_mem_alloc + // expected-error@+6 {{missing ':' after allocate clause modifier}} + // expected-error@+5 {{expected expression}} + // expected-error@+4 {{expected ')'}} + // expected-note@+3 {{to match this '('}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(c) allocate(allocator(omp_large_cap_mem_alloc: + // expected-error@+4 {{missing ':' after allocate clause modifier}} + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(c) allocate(allocator(omp_const_mem_alloc) + // expected-error@+2 {{missing ':' after allocate clause modifier}} + // expected-error@+1 {{expected expression}} + #pragma omp scope private(c) allocate(allocator(omp_high_bw_mem_alloc)) + // expected-error@+1 {{expected expression}} + #pragma omp scope private(c) allocate(allocator(omp_low_lat_mem_alloc):) + // expected-error@+6 {{expected ')'}} + // expected-note@+5 {{to match this '('}} + // expected-error@+4 {{missing ':' after allocate clause modifier}} + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(c) allocate(allocator(omp_cgroup_mem_alloc:) + // expected-error@+4 {{expected ')'}} + // expected-note@+3 {{to match this '('}} + // expected-error@+2 {{missing ':' after allocate clause modifier}} + // expected-error@+1 {{expected expression}} + #pragma omp scope private(c) allocate(allocator(omp_pteam_mem_alloc:)) + // expected-error@+4 {{expected ')'}} + // expected-note@+3 {{to match this '('}} + // expected-error@+2 {{missing ':' after allocate clause modifier}} + // expected-error@+1 {{expected expression}} + #pragma omp scope private(c) allocate(allocator(omp_thread_mem_alloc:c)) + // expected-error@+1 {{expected variable name}} + #pragma omp scope private(c) allocate(allocator(omp_const_mem_alloc):1) + // expected-error@+1 {{expected variable name}} + #pragma omp scope private(c) allocate(allocator(omp_const_mem_alloc):-10) + // expected-error@+4 {{expected ',' or ')' in 'allocate' clause}} + // expected-error@+3 {{expected ')'}} + // expected-warning@+2 {{extra tokens at the end of '#pragma omp scope' are ignored}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(a,b,c) allocate(allocator(omp_const_mem_alloc):c:b;a) + // expected-error@+1 {{initializing 'const omp_allocator_handle_t' with an expression of incompatible type 'int'}} + #pragma omp scope private(c,a,b) allocate(allocator(myAlloc()):a,b,c) + // expected-error@+2 {{missing ':' after allocate clause modifier}} + // expected-error@+1 {{expected expression}} + #pragma omp scope private(c) allocate(allocator(omp_default_mem_alloc);c) + // expected-error@+2 {{duplicate modifier 'allocator' in 'allocate' clause}} + // expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}} + #pragma omp scope private(a) allocate(allocator(omp_default_mem_alloc), allocator(omp_default_mem_alloc), align(3) : a) + // expected-error@+4 {{expected '('}} + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(a) allocate(allocator + // expected-error@+4 {{expected '('}} + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(b) allocate(align + // expected-error@+1 {{duplicate modifier 'align' in 'allocate' clause}} + #pragma omp scope private(a) allocate(align(8), align(4) : a) + // expected-error@+5 {{use of undeclared identifier 'align'}} + // expected-error@+4 {{expected ',' or ')' in 'allocate' clause}} + // expected-error@+3 {{expected ')'}} + // expected-note@+2 {{to match this '('}} + // expected-error@+1 {{expected variable name}} + #pragma omp scope private(a) allocate(omp_default_mem_alloc, align(8) : a) + // expected-error@+3 {{expected modifier in 'allocate' clause}} + // expected-error@+2 {{missing ':' after allocate clause modifier}} + // expected-error@+1 {{expected expression}} + #pragma omp scope private(a) allocate(align(8), omp_default_mem_alloc : a) + // expected-error@+5 {{expected ',' or ')' in 'allocate' clause}} + // expected-error@+4 {{expected ')'}} + // expected-note@+3 {{to match this '('}} + // expected-error@+2 {{expected variable name}} + // expected-error@+1 {{expected variable name}} + #pragma omp scope private(a) allocate(omp_default_mem_alloc, omp_default_mem_alloc : a) + // expected-error@+2 {{use of undeclared identifier 'undefinedVar'}} + // expected-error@+1 {{expected expression}} + #pragma omp scope private(a) allocate(undefinedVar : a) + // expected-error@+1 {{expected expression}} + #pragma omp scope private(a) allocate(align(8), allocator(omp_default_mem_alloc) : ) + // expected-error@+2 {{missing ':' after allocate clause modifier}} + // expected-error@+1 {{expected expression}} + #pragma omp scope private(a) allocate(align(8), allocator(omp_default_mem_alloc) ) + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(a) allocate(align(8), allocator(omp_default_mem_alloc) : + + // expected-error@+4 {{missing ':' after allocate clause modifier}} + // expected-error@+3 {{expected expression}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(a) allocate(align(8), allocator(omp_default_mem_alloc) + // expected-error@+4 {{expected '('}} + // expected-error@+3 {{expected '('}} + // expected-error@+2 {{expected expression}} + // expected-error@+1 {{use of undeclared identifier 'allocator'}} + #pragma omp scope private(a) allocate(align, allocator : ) + // expected-error@+7 {{expected expression}} + // expected-error@+6 {{expected expression}} + // expected-error@+5 {{expected expression}} + // expected-error@+4 {{use of undeclared identifier 'allocator'}} + // expected-error@+3 {{expected ',' or ')' in 'allocate' clause}} + // expected-error@+2 {{expected ')'}} + // expected-note@+1 {{to match this '('}} + #pragma omp scope private(a) allocate(align(), allocator() : ) + ++a; +} >From 4e4ae69235a92e2e754bbaca3facaba7a0437465 Mon Sep 17 00:00:00 2001 From: Dave Pagan <dave.pa...@amd.com> Date: Mon, 6 Jan 2025 16:06:30 -0600 Subject: [PATCH 2/6] Added 'align' modifier for 'allocate' clause as a completed feature in OpenMP 5.1 Implementation Details. --- clang/docs/OpenMPSupport.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index 481362dba3f51d..5235d6248215bd 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -286,6 +286,8 @@ implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | memory management | 'allocator' modifier for allocate clause | :good:`done` | https://github.com/llvm/llvm-project/pull/114883 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| memory management | 'align' modifier for allocate clause | :good:`done` | https://github.com/llvm/llvm-project/pull/121814 | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | memory management | new memory management routines | :none:`unclaimed` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | memory management | changes to omp_alloctrait_key enum | :none:`unclaimed` | | >From fbe26c0d9f16d8f28a44ec3a78e9b60bf36e993d Mon Sep 17 00:00:00 2001 From: Dave Pagan <dave.pa...@amd.com> Date: Tue, 7 Jan 2025 13:39:35 -0600 Subject: [PATCH 3/6] Updated placement of a couple of break statements in switch statement. Removed superfluous "TODO" comment. --- clang/lib/Parse/ParseOpenMP.cpp | 6 ++++-- clang/lib/Sema/SemaOpenMP.cpp | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 4032cbcb614e73..db7b2bfec58fb2 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -4577,7 +4577,8 @@ parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, Tail = P.ParseAssignmentExpression(); AllocateT.consumeClose(); AllocatorSeen = true; - } break; + break; + } case OMPC_ALLOCATE_align: { if (AlignSeen) { P.Diag(Tok, diag::err_omp_duplicate_modifier) @@ -4591,7 +4592,8 @@ parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, if (Val.isUsable()) Data.AllocateAlignment = Val.get(); AlignSeen = true; - } break; + break; + } default: assert(false && "Unexpected allocate modifier"); break; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 9b77031ca16670..5cdef4c7324697 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5285,7 +5285,6 @@ static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, } for (OMPClause *C : AllocateRange) { auto *AC = cast<OMPAllocateClause>(C); - // TODO: Check alignment? if (S.getLangOpts().OpenMP >= 50 && !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && >From 405686efc06d0762ee2c20cf7c498d4de1a49106 Mon Sep 17 00:00:00 2001 From: Dave Pagan <dave.pa...@amd.com> Date: Wed, 8 Jan 2025 18:20:26 -0600 Subject: [PATCH 4/6] Use llvm_unreachable() instead of assert() for unexpected modifier. For serialization, use writeEnum/readEnum for enum modifier values. --- clang/lib/Parse/ParseOpenMP.cpp | 2 +- clang/lib/Serialization/ASTReader.cpp | 6 ++---- clang/lib/Serialization/ASTWriter.cpp | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index db7b2bfec58fb2..8346f133ebc066 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -4595,7 +4595,7 @@ parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, break; } default: - assert(false && "Unexpected allocate modifier"); + llvm_unreachable("Unexpected allocate modifier"); break; } } else { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 8f105102563a22..aa0f6447909409 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11824,10 +11824,8 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { } void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) { - C->setFirstAllocateModifier( - static_cast<OpenMPAllocateClauseModifier>(Record.readInt())); - C->setSecondAllocateModifier( - static_cast<OpenMPAllocateClauseModifier>(Record.readInt())); + C->setFirstAllocateModifier(Record.readEnum<OpenMPAllocateClauseModifier>()); + C->setSecondAllocateModifier(Record.readEnum<OpenMPAllocateClauseModifier>()); C->setLParenLoc(Record.readSourceLocation()); C->setColonLoc(Record.readSourceLocation()); C->setAllocator(Record.readSubExpr()); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 3485052bbc4fdc..e6386541894a09 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -7924,8 +7924,8 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) { Record.push_back(C->varlist_size()); - Record.push_back(C->getFirstAllocateModifier()); - Record.push_back(C->getSecondAllocateModifier()); + Record.writeEnum(C->getFirstAllocateModifier()); + Record.writeEnum(C->getSecondAllocateModifier()); Record.AddSourceLocation(C->getLParenLoc()); Record.AddSourceLocation(C->getColonLoc()); Record.AddStmt(C->getAllocator()); >From 2ed4eee3499957b114d7f2265e6e982f89d25c6a Mon Sep 17 00:00:00 2001 From: Dave Pagan <dave.pa...@amd.com> Date: Thu, 9 Jan 2025 10:45:44 -0600 Subject: [PATCH 5/6] Per review suggestion, updated check for presence of allocate modifiers in SemaOpenMP.cpp --- clang/lib/Sema/SemaOpenMP.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 5cdef4c7324697..b83b2b12f4a230 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -17159,11 +17159,12 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, OpenMPAllocateClauseModifier Modifier1 = OMPC_ALLOCATE_unknown; OpenMPAllocateClauseModifier Modifier2 = OMPC_ALLOCATE_unknown; SourceLocation Modifier1Loc, Modifier2Loc; - if (auto NumModifiers = Data.AllocClauseModifiers.size()) { + if (!Data.AllocClauseModifiers.empty()) { + assert(Data.AllocClauseModifiers.size() <= 2 && + "More allocate modifiers than expected"); Modifier1 = Data.AllocClauseModifiers[0]; Modifier1Loc = Data.AllocClauseModifiersLoc[0]; - assert(NumModifiers <= 2 && "More allocate modifiers than expected"); - if (NumModifiers == 2) { + if (Data.AllocClauseModifiers.size() == 2) { Modifier2 = Data.AllocClauseModifiers[1]; Modifier2Loc = Data.AllocClauseModifiersLoc[1]; } >From 908955fa0dc1b9f3db8f7e8f7c2a563fc0a8b9f7 Mon Sep 17 00:00:00 2001 From: Dave Pagan <dave.pa...@amd.com> Date: Thu, 9 Jan 2025 15:53:30 -0600 Subject: [PATCH 6/6] Removed unnecessary break after llvm_unreachable(). --- clang/lib/Parse/ParseOpenMP.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 8346f133ebc066..89b83938f352df 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -4596,7 +4596,6 @@ parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, } default: llvm_unreachable("Unexpected allocate modifier"); - break; } } else { P.Diag(Tok, diag::err_expected) << tok::l_paren; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits