From llvm-branch-commits at lists.llvm.org Fri Apr 3 23:58:35 2020 From: llvm-branch-commits at lists.llvm.org (Johannes Doerfert via llvm-branch-commits) Date: Fri, 03 Apr 2020 23:58:35 -0700 (PDT) Subject: [llvm-branch-commits] [clang] 7f46c38 - [OpenMP][NFC] Remove unnecessary argument Message-ID: <5e88301b.1c69fb81.ac76c.18dd@mx.google.com> Author: Johannes Doerfert Date: 2020-04-03T21:26:26-05:00 New Revision: 7f46c38128e7d80df1a0d43d3bbcb390ab70068a URL: https://github.com/llvm/llvm-project/commit/7f46c38128e7d80df1a0d43d3bbcb390ab70068a DIFF: https://github.com/llvm/llvm-project/commit/7f46c38128e7d80df1a0d43d3bbcb390ab70068a.diff LOG: [OpenMP][NFC] Remove unnecessary argument Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaOpenMP.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 7c689c2a13e8..10e2d69f3d9e 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9892,7 +9892,7 @@ class Sema final { /// specialization via the OpenMP declare variant mechanism available. If /// there is, return the specialized call expression, otherwise return the /// original \p Call. - ExprResult ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, + ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8d0e97c85771..b311aad84816 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5997,7 +5997,7 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, } if (LangOpts.OpenMP) - Call = ActOnOpenMPCall(*this, Call, Scope, LParenLoc, ArgExprs, RParenLoc, + Call = ActOnOpenMPCall(Call, Scope, LParenLoc, ArgExprs, RParenLoc, ExecConfig); return Call; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index f663b1d43659..cfaf981983c1 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5584,7 +5584,7 @@ void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( BaseFD->setImplicit(true); } -ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, +ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig) { @@ -5601,8 +5601,8 @@ ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, if (!CalleeFnDecl->hasAttr()) return Call; - ASTContext &Context = S.getASTContext(); - OMPContext OMPCtx(S.getLangOpts().OpenMPIsDevice, + ASTContext &Context = getASTContext(); + OMPContext OMPCtx(getLangOpts().OpenMPIsDevice, Context.getTargetInfo().getTriple()); SmallVector Exprs; @@ -5650,12 +5650,12 @@ ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, if (auto *SpecializedMethod = dyn_cast(BestDecl)) { auto *MemberCall = dyn_cast(CE); BestExpr = MemberExpr::CreateImplicit( - S.Context, MemberCall->getImplicitObjectArgument(), - /* IsArrow */ false, SpecializedMethod, S.Context.BoundMemberTy, + Context, MemberCall->getImplicitObjectArgument(), + /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, MemberCall->getValueKind(), MemberCall->getObjectKind()); } - NewCall = S.BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, - ExecConfig); + NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, + ExecConfig); if (NewCall.isUsable()) break; } @@ -5666,7 +5666,6 @@ ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, if (!NewCall.isUsable()) return Call; - return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); } From llvm-branch-commits at lists.llvm.org Fri Apr 3 23:58:37 2020 From: llvm-branch-commits at lists.llvm.org (Johannes Doerfert via llvm-branch-commits) Date: Fri, 03 Apr 2020 23:58:37 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] ba52c84 - [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` Message-ID: <5e88301d.1c69fb81.25ccd.23b9@mx.google.com> Author: Johannes Doerfert Date: 2020-04-04T00:27:07-05:00 New Revision: ba52c8466bf950d34581c696737e5b5d83c1ac5c URL: https://github.com/llvm/llvm-project/commit/ba52c8466bf950d34581c696737e5b5d83c1ac5c DIFF: https://github.com/llvm/llvm-project/commit/ba52c8466bf950d34581c696737e5b5d83c1ac5c.diff LOG: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` Summary: This is a cleanup and normalization patch that also enables reuse with Flang later on. A follow up will clean up and move the directive -> clauses mapping. Reviewers: lebedev.ri, JonChesterfield, ABataev, fghanim Reviewed By: fghanim Subscribers: yaxunl, jholewinski, mgorny, hiraditya, bollu, guansong, arphaman, jfb, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77112 Added: Modified: clang/include/clang/AST/ASTFwd.h clang/include/clang/AST/ASTTypeTraits.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/AST/ASTTypeTraits.cpp clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/Analysis/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/CMakeLists.txt clang/tools/libclang/CIndex.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTFwd.h b/clang/include/clang/AST/ASTFwd.h index 5a891817b336..65319a19728b 100644 --- a/clang/include/clang/AST/ASTFwd.h +++ b/clang/include/clang/AST/ASTFwd.h @@ -27,8 +27,8 @@ class Type; #include "clang/AST/TypeNodes.inc" class CXXCtorInitializer; class OMPClause; -#define OPENMP_CLAUSE(KIND, CLASSNAME) class CLASSNAME; -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) class Class; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } // end namespace clang diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h index a9c2e334a29e..cd80e9bc3808 100644 --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -148,8 +148,8 @@ class ASTNodeKind { #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, #include "clang/AST/TypeNodes.inc" NKI_OMPClause, -#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class, -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) NKI_##Class, +#include "llvm/Frontend/OpenMP/OMPKinds.def" NKI_NumberOfKinds }; @@ -204,8 +204,8 @@ KIND_TO_KIND_ID(OMPClause) #include "clang/AST/StmtNodes.inc" #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) #include "clang/AST/TypeNodes.inc" -#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class) -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class) +#include "llvm/Frontend/OpenMP/OMPKinds.def" #undef KIND_TO_KIND_ID inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) { diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index efa6d0554a7c..9f5ff5a85182 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -285,12 +285,13 @@ class OMPAllocatorClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc), - Allocator(A) {} + : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc), + LParenLoc(LParenLoc), Allocator(A) {} /// Build an empty clause. OMPAllocatorClause() - : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -315,7 +316,7 @@ class OMPAllocatorClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocator; + return T->getClauseKind() == llvm::omp::OMPC_allocator; } }; @@ -350,17 +351,17 @@ class OMPAllocateClause final OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_allocate, StartLoc, LParenLoc, - EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_allocate, StartLoc, + LParenLoc, EndLoc, N), Allocator(Allocator), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPAllocateClause(unsigned N) - : OMPVarListClause(OMPC_allocate, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_allocate, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -412,7 +413,7 @@ class OMPAllocateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocate; + return T->getClauseKind() == llvm::omp::OMPC_allocate; } }; @@ -470,15 +471,16 @@ class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc) - : OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc), - NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) { + : OMPClause(llvm::omp::OMPC_if, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond), + ColonLoc(ColonLoc), NameModifier(NameModifier), + NameModifierLoc(NameModifierLoc) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPIfClause() - : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_if, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -512,7 +514,7 @@ class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_if; + return T->getClauseKind() == llvm::omp::OMPC_if; } }; @@ -548,14 +550,14 @@ class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit { OMPFinalClause(Expr *Cond, Stmt *HelperCond, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_final, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond) { + : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPFinalClause() - : OMPClause(OMPC_final, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -580,7 +582,7 @@ class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_final; + return T->getClauseKind() == llvm::omp::OMPC_final; } }; @@ -618,7 +620,7 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_threads, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumThreads(NumThreads) { setPreInitStmt(HelperNumThreads, CaptureRegion); @@ -626,7 +628,8 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. OMPNumThreadsClause() - : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -652,7 +655,7 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_threads; + return T->getClauseKind() == llvm::omp::OMPC_num_threads; } }; @@ -688,12 +691,13 @@ class OMPSafelenClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc), - Safelen(Len) {} + : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Safelen(Len) {} /// Build an empty clause. explicit OMPSafelenClause() - : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -718,7 +722,7 @@ class OMPSafelenClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_safelen; + return T->getClauseKind() == llvm::omp::OMPC_safelen; } }; @@ -753,12 +757,13 @@ class OMPSimdlenClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc), - Simdlen(Len) {} + : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Simdlen(Len) {} /// Build an empty clause. explicit OMPSimdlenClause() - : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -783,7 +788,7 @@ class OMPSimdlenClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simdlen; + return T->getClauseKind() == llvm::omp::OMPC_simdlen; } }; @@ -819,12 +824,13 @@ class OMPCollapseClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPCollapseClause(Expr *Num, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num) {} + : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num) {} /// Build an empty clause. explicit OMPCollapseClause() - : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -849,7 +855,7 @@ class OMPCollapseClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_collapse; + return T->getClauseKind() == llvm::omp::OMPC_collapse; } }; @@ -893,12 +899,13 @@ class OMPDefaultClause : public OMPClause { OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPDefaultClause() - : OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_default, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -928,7 +935,7 @@ class OMPDefaultClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_default; + return T->getClauseKind() == llvm::omp::OMPC_default; } }; @@ -974,12 +981,13 @@ class OMPProcBindClause : public OMPClause { OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_proc_bind, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPProcBindClause() - : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_proc_bind, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -1009,7 +1017,7 @@ class OMPProcBindClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_proc_bind; + return T->getClauseKind() == llvm::omp::OMPC_proc_bind; } }; @@ -1029,11 +1037,12 @@ class OMPUnifiedAddressClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_address, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedAddressClause() - : OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1051,7 +1060,7 @@ class OMPUnifiedAddressClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_address; + return T->getClauseKind() == llvm::omp::OMPC_unified_address; } }; @@ -1071,11 +1080,12 @@ class OMPUnifiedSharedMemoryClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_shared_memory, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedSharedMemoryClause() - : OMPClause(OMPC_unified_shared_memory, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1093,7 +1103,7 @@ class OMPUnifiedSharedMemoryClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_shared_memory; + return T->getClauseKind() == llvm::omp::OMPC_unified_shared_memory; } }; @@ -1113,11 +1123,12 @@ class OMPReverseOffloadClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_reverse_offload, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, StartLoc, EndLoc) {} /// Build an empty clause. OMPReverseOffloadClause() - : OMPClause(OMPC_reverse_offload, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1135,7 +1146,7 @@ class OMPReverseOffloadClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reverse_offload; + return T->getClauseKind() == llvm::omp::OMPC_reverse_offload; } }; @@ -1155,12 +1166,12 @@ class OMPDynamicAllocatorsClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_dynamic_allocators, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_dynamic_allocators, StartLoc, EndLoc) {} /// Build an empty clause. OMPDynamicAllocatorsClause() - : OMPClause(OMPC_dynamic_allocators, SourceLocation(), SourceLocation()) { - } + : OMPClause(llvm::omp::OMPC_dynamic_allocators, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1178,7 +1189,7 @@ class OMPDynamicAllocatorsClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dynamic_allocators; + return T->getClauseKind() == llvm::omp::OMPC_dynamic_allocators; } }; @@ -1230,12 +1241,12 @@ class OMPAtomicDefaultMemOrderClause final : public OMPClause { SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPAtomicDefaultMemOrderClause() - : OMPClause(OMPC_atomic_default_mem_order, SourceLocation(), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. @@ -1268,7 +1279,7 @@ class OMPAtomicDefaultMemOrderClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_atomic_default_mem_order; + return T->getClauseKind() == llvm::omp::OMPC_atomic_default_mem_order; } }; @@ -1387,9 +1398,9 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { Expr *ChunkSize, Stmt *HelperChunkSize, OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) - : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), - ChunkSize(ChunkSize) { + : OMPClause(llvm::omp::OMPC_schedule, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), + KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); Modifiers[FIRST] = M1; Modifiers[SECOND] = M2; @@ -1399,7 +1410,7 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. explicit OMPScheduleClause() - : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_schedule, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; @@ -1461,7 +1472,7 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_schedule; + return T->getClauseKind() == llvm::omp::OMPC_schedule; } }; @@ -1496,12 +1507,12 @@ class OMPOrderedClause final /// \param EndLoc Ending location of the clause. OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num), NumberOfLoops(NumLoops) {} + : OMPClause(llvm::omp::OMPC_ordered, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num), NumberOfLoops(NumLoops) {} /// Build an empty clause. explicit OMPOrderedClause(unsigned NumLoops) - : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_ordered, SourceLocation(), SourceLocation()), NumberOfLoops(NumLoops) {} /// Set the number of associated for-loops. @@ -1557,7 +1568,7 @@ class OMPOrderedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_ordered; + return T->getClauseKind() == llvm::omp::OMPC_ordered; } }; @@ -1574,11 +1585,11 @@ class OMPNowaitClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nowait, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {} /// Build an empty clause. OMPNowaitClause() - : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1596,7 +1607,7 @@ class OMPNowaitClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nowait; + return T->getClauseKind() == llvm::omp::OMPC_nowait; } }; @@ -1613,11 +1624,11 @@ class OMPUntiedClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_untied, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_untied, StartLoc, EndLoc) {} /// Build an empty clause. OMPUntiedClause() - : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_untied, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1635,7 +1646,7 @@ class OMPUntiedClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_untied; + return T->getClauseKind() == llvm::omp::OMPC_untied; } }; @@ -1653,11 +1664,12 @@ class OMPMergeableClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_mergeable, StartLoc, EndLoc) {} /// Build an empty clause. OMPMergeableClause() - : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_mergeable, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1675,7 +1687,7 @@ class OMPMergeableClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_mergeable; + return T->getClauseKind() == llvm::omp::OMPC_mergeable; } }; @@ -1692,10 +1704,11 @@ class OMPReadClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_read, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_read, StartLoc, EndLoc) {} /// Build an empty clause. - OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {} + OMPReadClause() + : OMPClause(llvm::omp::OMPC_read, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1713,7 +1726,7 @@ class OMPReadClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_read; + return T->getClauseKind() == llvm::omp::OMPC_read; } }; @@ -1730,11 +1743,11 @@ class OMPWriteClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_write, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_write, StartLoc, EndLoc) {} /// Build an empty clause. OMPWriteClause() - : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_write, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1752,7 +1765,7 @@ class OMPWriteClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_write; + return T->getClauseKind() == llvm::omp::OMPC_write; } }; @@ -1812,11 +1825,12 @@ class OMPUpdateClause final /// \param EndLoc Ending location of the clause. OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc, bool IsExtended) - : OMPClause(OMPC_update, StartLoc, EndLoc), IsExtended(IsExtended) {} + : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc), + IsExtended(IsExtended) {} /// Build an empty clause. OMPUpdateClause(bool IsExtended) - : OMPClause(OMPC_update, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()), IsExtended(IsExtended) {} public: @@ -1886,7 +1900,7 @@ class OMPUpdateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_update; + return T->getClauseKind() == llvm::omp::OMPC_update; } }; @@ -1904,11 +1918,12 @@ class OMPCaptureClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_capture, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_capture, StartLoc, EndLoc) {} /// Build an empty clause. OMPCaptureClause() - : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_capture, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1926,7 +1941,7 @@ class OMPCaptureClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_capture; + return T->getClauseKind() == llvm::omp::OMPC_capture; } }; @@ -1944,11 +1959,12 @@ class OMPSeqCstClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_seq_cst, StartLoc, EndLoc) {} /// Build an empty clause. OMPSeqCstClause() - : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_seq_cst, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1966,7 +1982,7 @@ class OMPSeqCstClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_seq_cst; + return T->getClauseKind() == llvm::omp::OMPC_seq_cst; } }; @@ -1984,11 +2000,12 @@ class OMPAcqRelClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_acq_rel, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_acq_rel, StartLoc, EndLoc) {} /// Build an empty clause. OMPAcqRelClause() - : OMPClause(OMPC_acq_rel, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_acq_rel, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2006,7 +2023,7 @@ class OMPAcqRelClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_acq_rel; + return T->getClauseKind() == llvm::omp::OMPC_acq_rel; } }; @@ -2024,11 +2041,12 @@ class OMPAcquireClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_acquire, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_acquire, StartLoc, EndLoc) {} /// Build an empty clause. OMPAcquireClause() - : OMPClause(OMPC_acquire, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_acquire, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2046,7 +2064,7 @@ class OMPAcquireClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_acquire; + return T->getClauseKind() == llvm::omp::OMPC_acquire; } }; @@ -2064,11 +2082,12 @@ class OMPReleaseClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_release, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_release, StartLoc, EndLoc) {} /// Build an empty clause. OMPReleaseClause() - : OMPClause(OMPC_release, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_release, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2086,7 +2105,7 @@ class OMPReleaseClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_release; + return T->getClauseKind() == llvm::omp::OMPC_release; } }; @@ -2104,11 +2123,12 @@ class OMPRelaxedClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_relaxed, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_relaxed, StartLoc, EndLoc) {} /// Build an empty clause. OMPRelaxedClause() - : OMPClause(OMPC_relaxed, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_relaxed, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2126,7 +2146,7 @@ class OMPRelaxedClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_relaxed; + return T->getClauseKind() == llvm::omp::OMPC_relaxed; } }; @@ -2152,16 +2172,16 @@ class OMPPrivateClause final /// \param N Number of the variables in the clause. OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_private, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_private, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPPrivateClause(unsigned N) - : OMPVarListClause(OMPC_private, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_private, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets the list of references to private copies with initializers for /// new private variables. @@ -2231,7 +2251,7 @@ class OMPPrivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_private; + return T->getClauseKind() == llvm::omp::OMPC_private; } }; @@ -2259,8 +2279,8 @@ class OMPFirstprivateClause final /// \param N Number of the variables in the clause. OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_firstprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_firstprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPreInit(this) {} /// Build an empty clause. @@ -2268,7 +2288,7 @@ class OMPFirstprivateClause final /// \param N Number of variables. explicit OMPFirstprivateClause(unsigned N) : OMPVarListClause( - OMPC_firstprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_firstprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPreInit(this) {} @@ -2372,7 +2392,7 @@ class OMPFirstprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_firstprivate; + return T->getClauseKind() == llvm::omp::OMPC_firstprivate; } }; @@ -2425,8 +2445,8 @@ class OMPLastprivateClause final SourceLocation EndLoc, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, unsigned N) - : OMPVarListClause(OMPC_lastprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_lastprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc), ColonLoc(ColonLoc) {} @@ -2435,7 +2455,7 @@ class OMPLastprivateClause final /// \param N Number of variables. explicit OMPLastprivateClause(unsigned N) : OMPVarListClause( - OMPC_lastprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_lastprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -2611,7 +2631,7 @@ class OMPLastprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_lastprivate; + return T->getClauseKind() == llvm::omp::OMPC_lastprivate; } }; @@ -2636,16 +2656,16 @@ class OMPSharedClause final /// \param N Number of the variables in the clause. OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_shared, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_shared, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPSharedClause(unsigned N) - : OMPVarListClause(OMPC_shared, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_shared, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -2683,7 +2703,7 @@ class OMPSharedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_shared; + return T->getClauseKind() == llvm::omp::OMPC_shared; } }; @@ -2734,8 +2754,8 @@ class OMPReductionClause final OpenMPReductionClauseModifier Modifier, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_reduction, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2744,9 +2764,9 @@ class OMPReductionClause final /// /// \param N Number of variables. explicit OMPReductionClause(unsigned N) - : OMPVarListClause(OMPC_reduction, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_reduction, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), OMPClauseWithPostUpdate(this) {} /// Sets reduction modifier. @@ -2943,7 +2963,7 @@ class OMPReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reduction; + return T->getClauseKind() == llvm::omp::OMPC_reduction; } }; @@ -2985,8 +3005,8 @@ class OMPTaskReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_task_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause( + llvm::omp::OMPC_task_reduction, StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2995,7 +3015,7 @@ class OMPTaskReductionClause final /// \param N Number of variables. explicit OMPTaskReductionClause(unsigned N) : OMPVarListClause( - OMPC_task_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_task_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3175,7 +3195,7 @@ class OMPTaskReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_task_reduction; + return T->getClauseKind() == llvm::omp::OMPC_task_reduction; } }; @@ -3216,8 +3236,8 @@ class OMPInReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_in_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_in_reduction, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -3226,7 +3246,7 @@ class OMPInReductionClause final /// \param N Number of variables. explicit OMPInReductionClause(unsigned N) : OMPVarListClause( - OMPC_in_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_in_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3430,7 +3450,7 @@ class OMPInReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_in_reduction; + return T->getClauseKind() == llvm::omp::OMPC_in_reduction; } }; @@ -3476,8 +3496,8 @@ class OMPLinearClause final OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(OMPC_linear, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause(llvm::omp::OMPC_linear, StartLoc, + LParenLoc, EndLoc, NumVars), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} @@ -3485,9 +3505,9 @@ class OMPLinearClause final /// /// \param NumVars Number of variables. explicit OMPLinearClause(unsigned NumVars) - : OMPVarListClause(OMPC_linear, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_linear, SourceLocation(), SourceLocation(), - NumVars), + SourceLocation(), NumVars), OMPClauseWithPostUpdate(this) {} /// Gets the list of initial values for linear variables. @@ -3707,7 +3727,7 @@ class OMPLinearClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_linear; + return T->getClauseKind() == llvm::omp::OMPC_linear; } }; @@ -3742,17 +3762,17 @@ class OMPAlignedClause final OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(OMPC_aligned, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause(llvm::omp::OMPC_aligned, StartLoc, + LParenLoc, EndLoc, NumVars), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param NumVars Number of variables. explicit OMPAlignedClause(unsigned NumVars) - : OMPVarListClause(OMPC_aligned, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_aligned, SourceLocation(), SourceLocation(), - NumVars) {} + SourceLocation(), NumVars) {} public: /// Creates clause with a list of variables \a VL and alignment \a A. @@ -3806,7 +3826,7 @@ class OMPAlignedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_aligned; + return T->getClauseKind() == llvm::omp::OMPC_aligned; } }; @@ -3845,16 +3865,16 @@ class OMPCopyinClause final /// \param N Number of the variables in the clause. OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_copyin, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_copyin, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyinClause(unsigned N) - : OMPVarListClause(OMPC_copyin, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_copyin, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the /// clause. These expressions represent source expression in the final @@ -3982,7 +4002,7 @@ class OMPCopyinClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyin; + return T->getClauseKind() == llvm::omp::OMPC_copyin; } }; @@ -4009,15 +4029,16 @@ class OMPCopyprivateClause final /// \param N Number of the variables in the clause. OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_copyprivate, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_copyprivate, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyprivateClause(unsigned N) : OMPVarListClause( - OMPC_copyprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_copyprivate, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the @@ -4145,7 +4166,7 @@ class OMPCopyprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyprivate; + return T->getClauseKind() == llvm::omp::OMPC_copyprivate; } }; @@ -4175,16 +4196,16 @@ class OMPFlushClause final /// \param N Number of the variables in the clause. OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_flush, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_flush, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPFlushClause(unsigned N) - : OMPVarListClause(OMPC_flush, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_flush, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -4222,7 +4243,7 @@ class OMPFlushClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_flush; + return T->getClauseKind() == llvm::omp::OMPC_flush; } }; @@ -4254,12 +4275,13 @@ class OMPDepobjClause final : public OMPClause { /// \param EndLoc Ending location of the clause. OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_depobj, StartLoc, EndLoc), LParenLoc(LParenLoc) {} + : OMPClause(llvm::omp::OMPC_depobj, StartLoc, EndLoc), + LParenLoc(LParenLoc) {} /// Build an empty clause. /// explicit OMPDepobjClause() - : OMPClause(OMPC_depobj, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_depobj, SourceLocation(), SourceLocation()) {} void setDepobj(Expr *E) { Depobj = E; } @@ -4308,7 +4330,7 @@ class OMPDepobjClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_depobj; + return T->getClauseKind() == llvm::omp::OMPC_depobj; } }; @@ -4349,8 +4371,9 @@ class OMPDependClause final /// clause. OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N, unsigned NumLoops) - : OMPVarListClause(OMPC_depend, StartLoc, LParenLoc, - EndLoc, N), NumLoops(NumLoops) {} + : OMPVarListClause(llvm::omp::OMPC_depend, StartLoc, + LParenLoc, EndLoc, N), + NumLoops(NumLoops) {} /// Build an empty clause. /// @@ -4358,9 +4381,9 @@ class OMPDependClause final /// \param NumLoops Number of loops that is associated with this depend /// clause. explicit OMPDependClause(unsigned N, unsigned NumLoops) - : OMPVarListClause(OMPC_depend, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_depend, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), NumLoops(NumLoops) {} /// Set dependency kind. @@ -4448,7 +4471,7 @@ class OMPDependClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_depend; + return T->getClauseKind() == llvm::omp::OMPC_depend; } }; @@ -4501,15 +4524,15 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc) - : OMPClause(OMPC_device, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Modifier(Modifier), ModifierLoc(ModifierLoc), - Device(E) { + : OMPClause(llvm::omp::OMPC_device, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), + ModifierLoc(ModifierLoc), Device(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPDeviceClause() - : OMPClause(OMPC_device, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_device, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -4544,7 +4567,7 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_device; + return T->getClauseKind() == llvm::omp::OMPC_device; } }; @@ -4561,11 +4584,12 @@ class OMPThreadsClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_threads, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {} /// Build an empty clause. OMPThreadsClause() - : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4583,7 +4607,7 @@ class OMPThreadsClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_threads; + return T->getClauseKind() == llvm::omp::OMPC_threads; } }; @@ -4600,10 +4624,11 @@ class OMPSIMDClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_simd, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_simd, StartLoc, EndLoc) {} /// Build an empty clause. - OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {} + OMPSIMDClause() + : OMPClause(llvm::omp::OMPC_simd, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4621,7 +4646,7 @@ class OMPSIMDClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simd; + return T->getClauseKind() == llvm::omp::OMPC_simd; } }; @@ -5297,8 +5322,8 @@ class OMPMapClause final : public OMPMappableExprListClause, OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, SourceLocation MapLoc, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo), + : OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo), MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() && "Unexpected number of map type modifiers."); @@ -5318,7 +5343,8 @@ class OMPMapClause final : public OMPMappableExprListClause, /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_map, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(), + Sizes) {} /// Set map-type-modifier for the clause. /// @@ -5465,7 +5491,7 @@ class OMPMapClause final : public OMPMappableExprListClause, static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_map; + return T->getClauseKind() == llvm::omp::OMPC_map; } }; @@ -5504,14 +5530,15 @@ class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTeams(E) { + : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPNumTeamsClause() - : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5540,7 +5567,7 @@ class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_teams; + return T->getClauseKind() == llvm::omp::OMPC_num_teams; } }; @@ -5580,14 +5607,15 @@ class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_thread_limit, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPThreadLimitClause() - : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_thread_limit, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5616,7 +5644,7 @@ class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_thread_limit; + return T->getClauseKind() == llvm::omp::OMPC_thread_limit; } }; @@ -5655,14 +5683,14 @@ class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit { OMPPriorityClause(Expr *Priority, Stmt *HelperPriority, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_priority, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Priority(Priority) { + : OMPClause(llvm::omp::OMPC_priority, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Priority(Priority) { setPreInitStmt(HelperPriority, CaptureRegion); } /// Build an empty clause. OMPPriorityClause() - : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_priority, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5690,7 +5718,7 @@ class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_priority; + return T->getClauseKind() == llvm::omp::OMPC_priority; } }; @@ -5726,14 +5754,15 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { OMPGrainsizeClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_grainsize, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Grainsize(Size) { + : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPGrainsizeClause() - : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_grainsize, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5758,7 +5787,7 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_grainsize; + return T->getClauseKind() == llvm::omp::OMPC_grainsize; } }; @@ -5775,11 +5804,12 @@ class OMPNogroupClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nogroup, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nogroup, StartLoc, EndLoc) {} /// Build an empty clause. OMPNogroupClause() - : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nogroup, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -5797,7 +5827,7 @@ class OMPNogroupClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nogroup; + return T->getClauseKind() == llvm::omp::OMPC_nogroup; } }; @@ -5833,14 +5863,15 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { OMPNumTasksClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTasks(Size) { + : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPNumTasksClause() - : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_tasks, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5865,7 +5896,7 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_tasks; + return T->getClauseKind() == llvm::omp::OMPC_num_tasks; } }; @@ -5897,11 +5928,12 @@ class OMPHintClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), + : OMPClause(llvm::omp::OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), Hint(Hint) {} /// Build an empty clause. - OMPHintClause() : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()) {} + OMPHintClause() + : OMPClause(llvm::omp::OMPC_hint, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -5926,7 +5958,7 @@ class OMPHintClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_hint; + return T->getClauseKind() == llvm::omp::OMPC_hint; } }; @@ -5998,7 +6030,7 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { SourceLocation EndLoc, OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, Stmt *HelperChunkSize) - : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_dist_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); @@ -6006,7 +6038,8 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. explicit OMPDistScheduleClause() - : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_dist_schedule, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Get kind of the clause. @@ -6045,7 +6078,7 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dist_schedule; + return T->getClauseKind() == llvm::omp::OMPC_dist_schedule; } }; @@ -6115,12 +6148,14 @@ class OMPDefaultmapClause : public OMPClause { SourceLocation MLoc, SourceLocation KLoc, SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind, OpenMPDefaultmapClauseModifier M) - : OMPClause(OMPC_defaultmap, StartLoc, EndLoc), LParenLoc(LParenLoc), - Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {} + : OMPClause(llvm::omp::OMPC_defaultmap, StartLoc, EndLoc), + LParenLoc(LParenLoc), Modifier(M), ModifierLoc(MLoc), Kind(Kind), + KindLoc(KLoc) {} /// Build an empty clause. explicit OMPDefaultmapClause() - : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_defaultmap, SourceLocation(), + SourceLocation()) {} /// Get kind of the clause. OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; } @@ -6157,7 +6192,7 @@ class OMPDefaultmapClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_defaultmap; + return T->getClauseKind() == llvm::omp::OMPC_defaultmap; } }; @@ -6195,8 +6230,8 @@ class OMPToClause final : public OMPMappableExprListClause, DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -6206,7 +6241,8 @@ class OMPToClause final : public OMPMappableExprListClause, /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_to, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6274,7 +6310,7 @@ class OMPToClause final : public OMPMappableExprListClause, } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_to; + return T->getClauseKind() == llvm::omp::OMPC_to; } }; @@ -6313,8 +6349,8 @@ class OMPFromClause final DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -6324,7 +6360,8 @@ class OMPFromClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6392,7 +6429,7 @@ class OMPFromClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_from; + return T->getClauseKind() == llvm::omp::OMPC_from; } }; @@ -6426,7 +6463,8 @@ class OMPUseDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) { + } /// Build an empty clause. /// @@ -6436,8 +6474,8 @@ class OMPUseDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6555,7 +6593,7 @@ class OMPUseDevicePtrClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_use_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_use_device_ptr; } }; @@ -6589,7 +6627,7 @@ class OMPIsDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, Locs, Sizes) {} /// Build an empty clause. /// @@ -6599,8 +6637,8 @@ class OMPIsDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6658,7 +6696,7 @@ class OMPIsDevicePtrClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_is_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_is_device_ptr; } }; @@ -6684,15 +6722,16 @@ class OMPNontemporalClause final /// \param N Number of the variables in the clause. OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_nontemporal, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_nontemporal, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPNontemporalClause(unsigned N) : OMPVarListClause( - OMPC_nontemporal, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_nontemporal, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Get the list of privatied copies if the member expression was captured by @@ -6754,7 +6793,7 @@ class OMPNontemporalClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nontemporal; + return T->getClauseKind() == llvm::omp::OMPC_nontemporal; } }; @@ -6798,12 +6837,12 @@ class OMPOrderClause final : public OMPClause { OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), - KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPOrderClause() - : OMPClause(OMPC_order, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -6833,7 +6872,7 @@ class OMPOrderClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_order; + return T->getClauseKind() == llvm::omp::OMPC_order; } }; @@ -6851,11 +6890,12 @@ class OMPDestroyClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDestroyClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_destroy, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc) {} /// Build an empty clause. OMPDestroyClause() - : OMPClause(OMPC_destroy, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -6873,7 +6913,7 @@ class OMPDestroyClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_destroy; + return T->getClauseKind() == llvm::omp::OMPC_destroy; } }; @@ -6908,12 +6948,12 @@ class OMPDetachClause final : public OMPClause { /// \param EndLoc Ending location of the clause. OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_detach, StartLoc, EndLoc), LParenLoc(LParenLoc), - Evt(Evt) {} + : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc), + LParenLoc(LParenLoc), Evt(Evt) {} /// Build an empty clause. OMPDetachClause() - : OMPClause(OMPC_detach, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {} /// Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } @@ -6935,7 +6975,7 @@ class OMPDetachClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_detach; + return T->getClauseKind() == llvm::omp::OMPC_detach; } }; @@ -6961,16 +7001,16 @@ class OMPInclusiveClause final /// \param N Number of the variables in the clause. OMPInclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_inclusive, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_inclusive, + StartLoc, LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPInclusiveClause(unsigned N) - : OMPVarListClause(OMPC_inclusive, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_inclusive, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -7009,7 +7049,7 @@ class OMPInclusiveClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_inclusive; + return T->getClauseKind() == llvm::omp::OMPC_inclusive; } }; @@ -7035,16 +7075,16 @@ class OMPExclusiveClause final /// \param N Number of the variables in the clause. OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_exclusive, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_exclusive, + StartLoc, LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPExclusiveClause(unsigned N) - : OMPVarListClause(OMPC_exclusive, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_exclusive, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -7083,7 +7123,7 @@ class OMPExclusiveClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_exclusive; + return T->getClauseKind() == llvm::omp::OMPC_exclusive; } }; @@ -7096,17 +7136,20 @@ class OMPClauseVisitorBase { #define DISPATCH(CLASS) \ return static_cast(this)->Visit##CLASS(static_cast(S)) -#define OPENMP_CLAUSE(Name, Class) \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" RetTy Visit(PTR(OMPClause) S) { // Top switch clause: visit each OMPClause. switch (S->getClauseKind()) { - default: llvm_unreachable("Unknown clause kind!"); -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_ ## Name : return Visit ## Class(static_cast(S)); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ + return Visit##Class(static_cast(S)); +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } } // Base case, ignore it. :) @@ -7135,8 +7178,9 @@ class OMPClausePrinter final : public OMPClauseVisitor { OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) : OS(OS), Policy(Policy) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + void Visit##Class(Class *S); +#include "llvm/Frontend/OpenMP/OMPKinds.def" }; struct OMPTraitProperty { diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 345333849659..b19b566294b7 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -534,8 +534,8 @@ template class RecursiveASTVisitor { bool TraverseOMPExecutableDirective(OMPExecutableDirective *S); bool TraverseOMPLoopDirective(OMPLoopDirective *S); bool TraverseOMPClause(OMPClause *C); -#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" /// Process clauses with list of variables. template bool VisitOMPClauseList(T *Node); /// Process clauses with pre-initis. @@ -2957,17 +2957,14 @@ bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { if (!C) return true; switch (C->getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ TRY_TO(Visit##Class(static_cast(C))); \ break; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_threadprivate: - case OMPC_uniform: - case OMPC_device_type: - case OMPC_match: - case OMPC_unknown: +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } return true; } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 96bfdd313f47..f55ce2cc84dd 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3242,8 +3242,13 @@ def OMPCaptureKind : Attr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Args = [UnsignedArgument<"CaptureKind">]; + let Args = [UnsignedArgument<"CaptureKindVal">]; let Documentation = [Undocumented]; + let AdditionalMembers = [{ + llvm::omp::Clause getCaptureKind() const { + return static_cast(getCaptureKindVal()); + } + }]; } def OMPReferencedVar : Attr { diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 3cf92ead9560..4a4e6c6cb4c3 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -222,74 +222,6 @@ #define OPENMP_REDUCTION_MODIFIER(Name) #endif -// OpenMP clauses. -OPENMP_CLAUSE(allocator, OMPAllocatorClause) -OPENMP_CLAUSE(if, OMPIfClause) -OPENMP_CLAUSE(final, OMPFinalClause) -OPENMP_CLAUSE(num_threads, OMPNumThreadsClause) -OPENMP_CLAUSE(safelen, OMPSafelenClause) -OPENMP_CLAUSE(simdlen, OMPSimdlenClause) -OPENMP_CLAUSE(collapse, OMPCollapseClause) -OPENMP_CLAUSE(default, OMPDefaultClause) -OPENMP_CLAUSE(private, OMPPrivateClause) -OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause) -OPENMP_CLAUSE(lastprivate, OMPLastprivateClause) -OPENMP_CLAUSE(shared, OMPSharedClause) -OPENMP_CLAUSE(reduction, OMPReductionClause) -OPENMP_CLAUSE(linear, OMPLinearClause) -OPENMP_CLAUSE(aligned, OMPAlignedClause) -OPENMP_CLAUSE(copyin, OMPCopyinClause) -OPENMP_CLAUSE(copyprivate, OMPCopyprivateClause) -OPENMP_CLAUSE(proc_bind, OMPProcBindClause) -OPENMP_CLAUSE(schedule, OMPScheduleClause) -OPENMP_CLAUSE(ordered, OMPOrderedClause) -OPENMP_CLAUSE(nowait, OMPNowaitClause) -OPENMP_CLAUSE(untied, OMPUntiedClause) -OPENMP_CLAUSE(mergeable, OMPMergeableClause) -OPENMP_CLAUSE(flush, OMPFlushClause) -OPENMP_CLAUSE(read, OMPReadClause) -OPENMP_CLAUSE(write, OMPWriteClause) -OPENMP_CLAUSE(update, OMPUpdateClause) -OPENMP_CLAUSE(capture, OMPCaptureClause) -OPENMP_CLAUSE(seq_cst, OMPSeqCstClause) -OPENMP_CLAUSE(acq_rel, OMPAcqRelClause) -OPENMP_CLAUSE(acquire, OMPAcquireClause) -OPENMP_CLAUSE(release, OMPReleaseClause) -OPENMP_CLAUSE(relaxed, OMPRelaxedClause) -OPENMP_CLAUSE(depend, OMPDependClause) -OPENMP_CLAUSE(device, OMPDeviceClause) -OPENMP_CLAUSE(threads, OMPThreadsClause) -OPENMP_CLAUSE(simd, OMPSIMDClause) -OPENMP_CLAUSE(map, OMPMapClause) -OPENMP_CLAUSE(num_teams, OMPNumTeamsClause) -OPENMP_CLAUSE(thread_limit, OMPThreadLimitClause) -OPENMP_CLAUSE(priority, OMPPriorityClause) -OPENMP_CLAUSE(grainsize, OMPGrainsizeClause) -OPENMP_CLAUSE(nogroup, OMPNogroupClause) -OPENMP_CLAUSE(num_tasks, OMPNumTasksClause) -OPENMP_CLAUSE(hint, OMPHintClause) -OPENMP_CLAUSE(dist_schedule, OMPDistScheduleClause) -OPENMP_CLAUSE(defaultmap, OMPDefaultmapClause) -OPENMP_CLAUSE(to, OMPToClause) -OPENMP_CLAUSE(from, OMPFromClause) -OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) -OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) -OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause) -OPENMP_CLAUSE(in_reduction, OMPInReductionClause) -OPENMP_CLAUSE(unified_address, OMPUnifiedAddressClause) -OPENMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) -OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) -OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) -OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) -OPENMP_CLAUSE(allocate, OMPAllocateClause) -OPENMP_CLAUSE(nontemporal, OMPNontemporalClause) -OPENMP_CLAUSE(order, OMPOrderClause) -OPENMP_CLAUSE(depobj, OMPDepobjClause) -OPENMP_CLAUSE(destroy, OMPDestroyClause) -OPENMP_CLAUSE(detach, OMPDetachClause) -OPENMP_CLAUSE(inclusive, OMPInclusiveClause) -OPENMP_CLAUSE(exclusive, OMPExclusiveClause) - // Clauses allowed for OpenMP directive 'scan'. OPENMP_SCAN_CLAUSE(inclusive) OPENMP_SCAN_CLAUSE(exclusive) diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index f12b5545d0c1..9a6a2050a165 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -23,16 +23,7 @@ namespace clang { using OpenMPDirectiveKind = llvm::omp::Directive; /// OpenMP clauses. -enum OpenMPClauseKind { -#define OPENMP_CLAUSE(Name, Class) \ - OMPC_##Name, -#include "clang/Basic/OpenMPKinds.def" - OMPC_threadprivate, - OMPC_uniform, - OMPC_device_type, - OMPC_match, - OMPC_unknown -}; +using OpenMPClauseKind = llvm::omp::Clause; /// OpenMP attributes for 'schedule' clause. enum OpenMPScheduleClauseKind { @@ -179,9 +170,6 @@ enum OpenMPReductionClauseModifier { OMPC_REDUCTION_unknown, }; -OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str); -const char *getOpenMPClauseName(OpenMPClauseKind Kind); - unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str); const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type); diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp index e4ea3f41af36..6404edd79679 100644 --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -39,8 +39,8 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { #define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" }, #include "clang/AST/TypeNodes.inc" { NKI_None, "OMPClause" }, -#define OPENMP_CLAUSE(TextualSpelling, Class) {NKI_OMPClause, #Class}, -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) {NKI_OMPClause, #Class}, +#include "llvm/Frontend/OpenMP/OMPKinds.def" }; bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const { @@ -111,15 +111,13 @@ ASTNodeKind ASTNodeKind::getFromNode(const Type &T) { ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) { switch (C.getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: return ASTNodeKind(NKI_##Class); -#include "clang/Basic/OpenMPKinds.def" - case OMPC_threadprivate: - case OMPC_uniform: - case OMPC_device_type: - case OMPC_match: - case OMPC_unknown: +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ + return ASTNodeKind(NKI_##Class); +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ llvm_unreachable("unexpected OpenMP clause kind"); +#include "llvm/Frontend/OpenMP/OMPKinds.def" } llvm_unreachable("invalid stmt kind"); } diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index bc0db1ba10a2..7818fbb1918b 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -108,7 +108,8 @@ void OMPDeclareSimdDeclAttr::printPrettyPragma( for (auto *E : linears()) { OS << " linear("; if (*MI != OMPC_LINEAR_unknown) - OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "("; + OS << getOpenMPSimpleClauseTypeName(llvm::omp::Clause::OMPC_linear, *MI) + << "("; E->printPretty(OS, nullptr, Policy); if (*MI != OMPC_LINEAR_unknown) OS << ")"; diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index a205a1bca1b9..0fdbec634103 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -31,20 +31,20 @@ OMPClause::child_range OMPClause::children() { switch (getClauseKind()) { default: break; -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case Enum: \ return static_cast(this)->children(); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" } llvm_unreachable("unknown OMPClause"); } OMPClause::child_range OMPClause::used_children() { switch (getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case Enum: \ return static_cast(this)->used_children(); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" case OMPC_threadprivate: case OMPC_uniform: case OMPC_device_type: diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index fec12ac98b4e..be0bc13ccb4d 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -414,9 +414,8 @@ class OMPClauseProfiler : public ConstOMPClauseVisitor { public: OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { } -#define OPENMP_CLAUSE(Name, Class) \ - void Visit##Class(const Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C); void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); }; diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index dc0dd92f09df..2933457b5711 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -314,7 +314,7 @@ void TextNodeDumper::Visit(const OMPClause *C) { } { ColorScope Color(OS, ShowColors, AttrColor); - StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); + StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind())); OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } @@ -1534,7 +1534,8 @@ void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) { } { ColorScope Color(OS, ShowColors, AttrColor); - StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); + StringRef ClauseName( + llvm::omp::getOpenMPClauseName(C->getClauseKind())); OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } diff --git a/clang/lib/ASTMatchers/CMakeLists.txt b/clang/lib/ASTMatchers/CMakeLists.txt index 8f700ca3226b..cde871cd31ca 100644 --- a/clang/lib/ASTMatchers/CMakeLists.txt +++ b/clang/lib/ASTMatchers/CMakeLists.txt @@ -1,6 +1,9 @@ add_subdirectory(Dynamic) -set(LLVM_LINK_COMPONENTS support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) add_clang_library(clangASTMatchers ASTMatchFinder.cpp diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 48a454e3397e..db9122acede7 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -170,9 +170,8 @@ template <> struct ArgTypeTraits { private: static Optional getClauseKind(llvm::StringRef ClauseKind) { return llvm::StringSwitch>(ClauseKind) -#define OPENMP_CLAUSE(TextualSpelling, Class) \ - .Case("OMPC_" #TextualSpelling, OMPC_##TextualSpelling) -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum) +#include "llvm/Frontend/OpenMP/OMPKinds.def" .Default(llvm::None); } diff --git a/clang/lib/Analysis/CMakeLists.txt b/clang/lib/Analysis/CMakeLists.txt index c1d0d6ed62c5..3333eab3b96d 100644 --- a/clang/lib/Analysis/CMakeLists.txt +++ b/clang/lib/Analysis/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 7a7c66c8e587..981bd7adbe9b 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -20,50 +20,6 @@ using namespace clang; using namespace llvm::omp; -OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) { - // 'flush' clause cannot be specified explicitly, because this is an implicit - // clause for 'flush' directive. If the 'flush' clause is explicitly specified - // the Parser should generate a warning about extra tokens at the end of the - // directive. - // 'depobj' clause cannot be specified explicitly, because this is an implicit - // clause for 'depobj' directive. If the 'depobj' clause is explicitly - // specified the Parser should generate a warning about extra tokens at the - // end of the directive. - if (llvm::StringSwitch(Str) - .Case("flush", true) - .Case("depobj", true) - .Default(false)) - return OMPC_unknown; - return llvm::StringSwitch(Str) -#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name) -#include "clang/Basic/OpenMPKinds.def" - .Case("uniform", OMPC_uniform) - .Case("device_type", OMPC_device_type) - .Case("match", OMPC_match) - .Default(OMPC_unknown); -} - -const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) { - assert(Kind <= OMPC_unknown); - switch (Kind) { - case OMPC_unknown: - return "unknown"; -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ - return #Name; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_uniform: - return "uniform"; - case OMPC_threadprivate: - return "threadprivate or thread local"; - case OMPC_device_type: - return "device_type"; - case OMPC_match: - return "match"; - } - llvm_unreachable("Invalid OpenMP clause kind"); -} - unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str) { switch (Kind) { diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index aa6b6bc64c32..b6db63545c2c 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -341,8 +341,7 @@ class CheckVarsEscapingDeclContext final if (!Attr) return; if (((Attr->getCaptureKind() != OMPC_map) && - !isOpenMPPrivate( - static_cast(Attr->getCaptureKind()))) || + !isOpenMPPrivate(Attr->getCaptureKind())) || ((Attr->getCaptureKind() == OMPC_map) && !FD->getType()->isAnyPointerType())) return; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 4bec5f557ab8..4da1b4146af3 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1389,7 +1389,7 @@ bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(OMPC_match))) { + getOpenMPClauseName(OMPC_match).data())) { while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch)) ; // Skip the last annot_pragma_openmp_end. @@ -1436,7 +1436,7 @@ parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) { // Parse '('. BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind))) + getOpenMPClauseName(Kind).data())) return llvm::None; unsigned Type = getOpenMPSimpleClauseType( @@ -1675,18 +1675,18 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, - !FirstClauses[CKind].getInt()); + OMPClause *Clause = ParseOpenMPClause( + OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[CKind].setInt(true); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -1710,8 +1710,9 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_requires: { SourceLocation StartLoc = ConsumeToken(); SmallVector Clauses; - SmallVector, OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + SmallVector, + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); if (Tok.is(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::err_omp_expected_clause) << getOpenMPDirectiveName(OMPD_requires); @@ -1722,11 +1723,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind, - !FirstClauses[CKind].getInt()); + OMPClause *Clause = ParseOpenMPClause( + OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[CKind].setInt(true); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2025,8 +2026,9 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { ParsingOpenMPDirectiveRAII DirScope(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); SmallVector Clauses; - SmallVector, OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + SmallVector, + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; SourceLocation Loc = ConsumeAnnotationToken(), EndLoc; @@ -2071,18 +2073,18 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, - !FirstClauses[CKind].getInt()); + OMPClause *Clause = ParseOpenMPClause( + OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[CKind].setInt(true); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2250,11 +2252,11 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { ImplicitClauseAllowed = false; Actions.StartOpenMPClause(CKind); HasImplicitClause = false; - OMPClause *Clause = - ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt()); - FirstClauses[CKind].setInt(true); + OMPClause *Clause = ParseOpenMPClause( + DKind, CKind, !FirstClauses[unsigned(CKind)].getInt()); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause) { - FirstClauses[CKind].setPointer(Clause); + FirstClauses[unsigned(CKind)].setPointer(Clause); Clauses.push_back(Clause); } @@ -2271,7 +2273,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { // OpenMP [2.13.8, ordered Construct, Syntax] // If the depend clause is specified, the ordered construct is a stand-alone // directive. - if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) { + if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) { if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Loc, diag::err_omp_immediate_directive) @@ -2756,7 +2758,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind))) + getOpenMPClauseName(Kind).data())) return nullptr; ExprResult Val; @@ -3176,7 +3178,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind))) + getOpenMPClauseName(Kind).data())) return true; bool DependWithIterator = false; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index cfaf981983c1..dfb809e0aaa1 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2233,7 +2233,7 @@ void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, } } if (OMPC != OMPC_unknown) - FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); + FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); } bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index de05d436d3b9..1f88f9c57465 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -730,10 +730,10 @@ class TreeTransform { #define ABSTRACT_STMT(Stmt) #include "clang/AST/StmtNodes.inc" -#define OPENMP_CLAUSE(Name, Class) \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ LLVM_ATTRIBUTE_NOINLINE \ OMPClause *Transform ## Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" /// Build a new qualified type given its unqualified type and type location. /// @@ -3597,10 +3597,10 @@ OMPClause *TreeTransform::TransformOMPClause(OMPClause *S) { switch (S->getClauseKind()) { default: break; // Transform individual clause nodes -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_ ## Name : \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case Enum: \ return getDerived().Transform ## Class(cast(S)); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" } return S; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 7d84f1108c85..22a3771e4b85 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11616,8 +11616,8 @@ class OMPClauseReader : public OMPClauseVisitor { OMPClauseReader(ASTRecordReader &Record) : Record(Record), Context(Record.getContext()) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" OMPClause *readClause(); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -11631,149 +11631,149 @@ OMPClause *ASTRecordReader::readOMPClause() { OMPClause *OMPClauseReader::readClause() { OMPClause *C = nullptr; - switch (Record.readInt()) { - case OMPC_if: + switch (llvm::omp::Clause(Record.readInt())) { + case llvm::omp::OMPC_if: C = new (Context) OMPIfClause(); break; - case OMPC_final: + case llvm::omp::OMPC_final: C = new (Context) OMPFinalClause(); break; - case OMPC_num_threads: + case llvm::omp::OMPC_num_threads: C = new (Context) OMPNumThreadsClause(); break; - case OMPC_safelen: + case llvm::omp::OMPC_safelen: C = new (Context) OMPSafelenClause(); break; - case OMPC_simdlen: + case llvm::omp::OMPC_simdlen: C = new (Context) OMPSimdlenClause(); break; - case OMPC_allocator: + case llvm::omp::OMPC_allocator: C = new (Context) OMPAllocatorClause(); break; - case OMPC_collapse: + case llvm::omp::OMPC_collapse: C = new (Context) OMPCollapseClause(); break; - case OMPC_default: + case llvm::omp::OMPC_default: C = new (Context) OMPDefaultClause(); break; - case OMPC_proc_bind: + case llvm::omp::OMPC_proc_bind: C = new (Context) OMPProcBindClause(); break; - case OMPC_schedule: + case llvm::omp::OMPC_schedule: C = new (Context) OMPScheduleClause(); break; - case OMPC_ordered: + case llvm::omp::OMPC_ordered: C = OMPOrderedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_nowait: + case llvm::omp::OMPC_nowait: C = new (Context) OMPNowaitClause(); break; - case OMPC_untied: + case llvm::omp::OMPC_untied: C = new (Context) OMPUntiedClause(); break; - case OMPC_mergeable: + case llvm::omp::OMPC_mergeable: C = new (Context) OMPMergeableClause(); break; - case OMPC_read: + case llvm::omp::OMPC_read: C = new (Context) OMPReadClause(); break; - case OMPC_write: + case llvm::omp::OMPC_write: C = new (Context) OMPWriteClause(); break; - case OMPC_update: + case llvm::omp::OMPC_update: C = OMPUpdateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_capture: + case llvm::omp::OMPC_capture: C = new (Context) OMPCaptureClause(); break; - case OMPC_seq_cst: + case llvm::omp::OMPC_seq_cst: C = new (Context) OMPSeqCstClause(); break; - case OMPC_acq_rel: + case llvm::omp::OMPC_acq_rel: C = new (Context) OMPAcqRelClause(); break; - case OMPC_acquire: + case llvm::omp::OMPC_acquire: C = new (Context) OMPAcquireClause(); break; - case OMPC_release: + case llvm::omp::OMPC_release: C = new (Context) OMPReleaseClause(); break; - case OMPC_relaxed: + case llvm::omp::OMPC_relaxed: C = new (Context) OMPRelaxedClause(); break; - case OMPC_threads: + case llvm::omp::OMPC_threads: C = new (Context) OMPThreadsClause(); break; - case OMPC_simd: + case llvm::omp::OMPC_simd: C = new (Context) OMPSIMDClause(); break; - case OMPC_nogroup: + case llvm::omp::OMPC_nogroup: C = new (Context) OMPNogroupClause(); break; - case OMPC_unified_address: + case llvm::omp::OMPC_unified_address: C = new (Context) OMPUnifiedAddressClause(); break; - case OMPC_unified_shared_memory: + case llvm::omp::OMPC_unified_shared_memory: C = new (Context) OMPUnifiedSharedMemoryClause(); break; - case OMPC_reverse_offload: + case llvm::omp::OMPC_reverse_offload: C = new (Context) OMPReverseOffloadClause(); break; - case OMPC_dynamic_allocators: + case llvm::omp::OMPC_dynamic_allocators: C = new (Context) OMPDynamicAllocatorsClause(); break; - case OMPC_atomic_default_mem_order: + case llvm::omp::OMPC_atomic_default_mem_order: C = new (Context) OMPAtomicDefaultMemOrderClause(); break; - case OMPC_private: + case llvm::omp::OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_firstprivate: + case llvm::omp::OMPC_firstprivate: C = OMPFirstprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_lastprivate: + case llvm::omp::OMPC_lastprivate: C = OMPLastprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_shared: + case llvm::omp::OMPC_shared: C = OMPSharedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_reduction: + case llvm::omp::OMPC_reduction: C = OMPReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_task_reduction: + case llvm::omp::OMPC_task_reduction: C = OMPTaskReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_in_reduction: + case llvm::omp::OMPC_in_reduction: C = OMPInReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_linear: + case llvm::omp::OMPC_linear: C = OMPLinearClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_aligned: + case llvm::omp::OMPC_aligned: C = OMPAlignedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_copyin: + case llvm::omp::OMPC_copyin: C = OMPCopyinClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_copyprivate: + case llvm::omp::OMPC_copyprivate: C = OMPCopyprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_flush: + case llvm::omp::OMPC_flush: C = OMPFlushClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_depobj: + case llvm::omp::OMPC_depobj: C = OMPDepobjClause::CreateEmpty(Context); break; - case OMPC_depend: { + case llvm::omp::OMPC_depend: { unsigned NumVars = Record.readInt(); unsigned NumLoops = Record.readInt(); C = OMPDependClause::CreateEmpty(Context, NumVars, NumLoops); break; } - case OMPC_device: + case llvm::omp::OMPC_device: C = new (Context) OMPDeviceClause(); break; - case OMPC_map: { + case llvm::omp::OMPC_map: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11782,31 +11782,31 @@ OMPClause *OMPClauseReader::readClause() { C = OMPMapClause::CreateEmpty(Context, Sizes); break; } - case OMPC_num_teams: + case llvm::omp::OMPC_num_teams: C = new (Context) OMPNumTeamsClause(); break; - case OMPC_thread_limit: + case llvm::omp::OMPC_thread_limit: C = new (Context) OMPThreadLimitClause(); break; - case OMPC_priority: + case llvm::omp::OMPC_priority: C = new (Context) OMPPriorityClause(); break; - case OMPC_grainsize: + case llvm::omp::OMPC_grainsize: C = new (Context) OMPGrainsizeClause(); break; - case OMPC_num_tasks: + case llvm::omp::OMPC_num_tasks: C = new (Context) OMPNumTasksClause(); break; - case OMPC_hint: + case llvm::omp::OMPC_hint: C = new (Context) OMPHintClause(); break; - case OMPC_dist_schedule: + case llvm::omp::OMPC_dist_schedule: C = new (Context) OMPDistScheduleClause(); break; - case OMPC_defaultmap: + case llvm::omp::OMPC_defaultmap: C = new (Context) OMPDefaultmapClause(); break; - case OMPC_to: { + case llvm::omp::OMPC_to: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11815,7 +11815,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPToClause::CreateEmpty(Context, Sizes); break; } - case OMPC_from: { + case llvm::omp::OMPC_from: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11824,7 +11824,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPFromClause::CreateEmpty(Context, Sizes); break; } - case OMPC_use_device_ptr: { + case llvm::omp::OMPC_use_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11833,7 +11833,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPUseDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case OMPC_is_device_ptr: { + case llvm::omp::OMPC_is_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11842,27 +11842,31 @@ OMPClause *OMPClauseReader::readClause() { C = OMPIsDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case OMPC_allocate: + case llvm::omp::OMPC_allocate: C = OMPAllocateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_nontemporal: + case llvm::omp::OMPC_nontemporal: C = OMPNontemporalClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_inclusive: + case llvm::omp::OMPC_inclusive: C = OMPInclusiveClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_exclusive: + case llvm::omp::OMPC_exclusive: C = OMPExclusiveClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_order: + case llvm::omp::OMPC_order: C = new (Context) OMPOrderClause(); break; - case OMPC_destroy: + case llvm::omp::OMPC_destroy: C = new (Context) OMPDestroyClause(); break; - case OMPC_detach: + case llvm::omp::OMPC_detach: C = new (Context) OMPDetachClause(); break; +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } assert(C && "Unknown OMPClause type"); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 89ba7e623965..3b72f0f1cef2 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6037,8 +6037,8 @@ class OMPClauseWriter : public OMPClauseVisitor { public: OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void writeClause(OMPClause *C); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -6051,7 +6051,7 @@ void ASTRecordWriter::writeOMPClause(OMPClause *C) { } void OMPClauseWriter::writeClause(OMPClause *C) { - Record.push_back(C->getClauseKind()); + Record.push_back(unsigned(C->getClauseKind())); Visit(C); Record.AddSourceLocation(C->getBeginLoc()); Record.AddSourceLocation(C->getEndLoc()); diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index b7fb0d90c980..bcf2dfdb8326 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt index dc2a6279b737..057cdd4bb18a 100644 --- a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt @@ -1,4 +1,7 @@ -set(LLVM_LINK_COMPONENTS support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) add_clang_library(clangStaticAnalyzerCore APSIntType.cpp diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 14814f89d97d..50c088606538 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2153,8 +2153,8 @@ class OMPClauseEnqueue : public ConstOMPClauseVisitor { public: OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(const Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); }; diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index fbf2ff130785..428879d0695c 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2612,7 +2612,7 @@ TEST(HasExternalFormalLinkage, Basic) { } TEST(HasDefaultArgument, Basic) { - EXPECT_TRUE(matches("void x(int val = 0) {}", + EXPECT_TRUE(matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument()))); EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument()))); @@ -2665,7 +2665,7 @@ TEST(HasTrailingReturn, MatchesTrailingReturn) { EXPECT_TRUE(matches("auto Y() -> int { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn()))); - EXPECT_TRUE(notMatches("int X() { return 0; }", + EXPECT_TRUE(notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatchesC("void X();", functionDecl(hasTrailingReturn()))); @@ -2891,8 +2891,8 @@ void x(int x) { } TEST(OMPExecutableDirective, isAllowedToContainClauseKind) { - auto Matcher = - ompExecutableDirective(isAllowedToContainClauseKind(OMPC_default)); + auto Matcher = ompExecutableDirective( + isAllowedToContainClauseKind(llvm::omp::OMPC_default)); const std::string Source0 = R"( void x() { diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h index 7cda3197473f..d32fa8dc98ef 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -34,11 +34,18 @@ enum class Directive { #include "llvm/Frontend/OpenMP/OMPKinds.def" }; +/// IDs for all OpenMP clauses. +enum class Clause { +#define OMP_CLAUSE(Enum, ...) Enum, +#include "llvm/Frontend/OpenMP/OMPKinds.def" +}; + /// Make the enum values available in the llvm::omp namespace. This allows us to /// write something like OMPD_parallel if we have a `using namespace omp`. At /// the same time we do not loose the strong type guarantees of the enum class, /// that is we cannot pass an unsigned as Directive without an explicit cast. #define OMP_DIRECTIVE(Enum, ...) constexpr auto Enum = omp::Directive::Enum; +#define OMP_CLAUSE(Enum, ...) constexpr auto Enum = omp::Clause::Enum; #include "llvm/Frontend/OpenMP/OMPKinds.def" /// IDs for all omp runtime library (RTL) functions. @@ -87,6 +94,12 @@ Directive getOpenMPDirectiveKind(StringRef Str); /// Return a textual representation of the directive \p D. StringRef getOpenMPDirectiveName(Directive D); +/// Parse \p Str and return the clause it matches or OMPC_unknown if none. +Clause getOpenMPClauseKind(StringRef Str); + +/// Return a textual representation of the clause \p C. +StringRef getOpenMPClauseName(Clause C); + /// Forward declarations for LLVM-IR types (simple, function and structure) are /// generated below. Their names are defined and used in OpenMP/OMPKinds.def. /// Here we provide the forward declarations, the initializeTypes function will diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index c80ecc7cbf77..09468358415f 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -105,6 +105,117 @@ __OMP_DIRECTIVE(unknown) ///} +/// OpenMP Clauses +/// +///{ + +#ifndef OMP_CLAUSE +#define OMP_CLAUSE(Enum, Str, Implicit) +#endif +#ifndef OMP_CLAUSE_CLASS +#define OMP_CLAUSE_CLASS(Enum, Str, Class) +#endif +#ifndef OMP_CLAUSE_NO_CLASS +#define OMP_CLAUSE_NO_CLASS(Enum, Str) +#endif + +#define __OMP_CLAUSE(Name, Class) \ + OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \ + OMP_CLAUSE_CLASS(OMPC_##Name, #Name, Class) +#define __OMP_CLAUSE_NO_CLASS(Name) \ + OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \ + OMP_CLAUSE_NO_CLASS(OMPC_##Name, #Name) +#define __OMP_IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \ + OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \ + OMP_CLAUSE_CLASS(OMPC_##Name, Str, Class) +#define __OMP_IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \ + OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \ + OMP_CLAUSE_NO_CLASS(OMPC_##Name, Str) + +__OMP_CLAUSE(allocator, OMPAllocatorClause) +__OMP_CLAUSE(if, OMPIfClause) +__OMP_CLAUSE(final, OMPFinalClause) +__OMP_CLAUSE(num_threads, OMPNumThreadsClause) +__OMP_CLAUSE(safelen, OMPSafelenClause) +__OMP_CLAUSE(simdlen, OMPSimdlenClause) +__OMP_CLAUSE(collapse, OMPCollapseClause) +__OMP_CLAUSE(default, OMPDefaultClause) +__OMP_CLAUSE(private, OMPPrivateClause) +__OMP_CLAUSE(firstprivate, OMPFirstprivateClause) +__OMP_CLAUSE(lastprivate, OMPLastprivateClause) +__OMP_CLAUSE(shared, OMPSharedClause) +__OMP_CLAUSE(reduction, OMPReductionClause) +__OMP_CLAUSE(linear, OMPLinearClause) +__OMP_CLAUSE(aligned, OMPAlignedClause) +__OMP_CLAUSE(copyin, OMPCopyinClause) +__OMP_CLAUSE(copyprivate, OMPCopyprivateClause) +__OMP_CLAUSE(proc_bind, OMPProcBindClause) +__OMP_CLAUSE(schedule, OMPScheduleClause) +__OMP_CLAUSE(ordered, OMPOrderedClause) +__OMP_CLAUSE(nowait, OMPNowaitClause) +__OMP_CLAUSE(untied, OMPUntiedClause) +__OMP_CLAUSE(mergeable, OMPMergeableClause) +__OMP_CLAUSE(read, OMPReadClause) +__OMP_CLAUSE(write, OMPWriteClause) +__OMP_CLAUSE(update, OMPUpdateClause) +__OMP_CLAUSE(capture, OMPCaptureClause) +__OMP_CLAUSE(seq_cst, OMPSeqCstClause) +__OMP_CLAUSE(acq_rel, OMPAcqRelClause) +__OMP_CLAUSE(acquire, OMPAcquireClause) +__OMP_CLAUSE(release, OMPReleaseClause) +__OMP_CLAUSE(relaxed, OMPRelaxedClause) +__OMP_CLAUSE(depend, OMPDependClause) +__OMP_CLAUSE(device, OMPDeviceClause) +__OMP_CLAUSE(threads, OMPThreadsClause) +__OMP_CLAUSE(simd, OMPSIMDClause) +__OMP_CLAUSE(map, OMPMapClause) +__OMP_CLAUSE(num_teams, OMPNumTeamsClause) +__OMP_CLAUSE(thread_limit, OMPThreadLimitClause) +__OMP_CLAUSE(priority, OMPPriorityClause) +__OMP_CLAUSE(grainsize, OMPGrainsizeClause) +__OMP_CLAUSE(nogroup, OMPNogroupClause) +__OMP_CLAUSE(num_tasks, OMPNumTasksClause) +__OMP_CLAUSE(hint, OMPHintClause) +__OMP_CLAUSE(dist_schedule, OMPDistScheduleClause) +__OMP_CLAUSE(defaultmap, OMPDefaultmapClause) +__OMP_CLAUSE(to, OMPToClause) +__OMP_CLAUSE(from, OMPFromClause) +__OMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) +__OMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) +__OMP_CLAUSE(task_reduction, OMPTaskReductionClause) +__OMP_CLAUSE(in_reduction, OMPInReductionClause) +__OMP_CLAUSE(unified_address, OMPUnifiedAddressClause) +__OMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) +__OMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) +__OMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) +__OMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) +__OMP_CLAUSE(allocate, OMPAllocateClause) +__OMP_CLAUSE(nontemporal, OMPNontemporalClause) +__OMP_CLAUSE(order, OMPOrderClause) +__OMP_CLAUSE(destroy, OMPDestroyClause) +__OMP_CLAUSE(detach, OMPDetachClause) +__OMP_CLAUSE(inclusive, OMPInclusiveClause) +__OMP_CLAUSE(exclusive, OMPExclusiveClause) + +__OMP_CLAUSE_NO_CLASS(uniform) +__OMP_CLAUSE_NO_CLASS(device_type) +__OMP_CLAUSE_NO_CLASS(match) + +__OMP_IMPLICIT_CLAUSE_CLASS(depobj, "depobj", OMPDepobjClause) +__OMP_IMPLICIT_CLAUSE_CLASS(flush, "flush", OMPFlushClause) + +__OMP_IMPLICIT_CLAUSE_NO_CLASS(threadprivate, "threadprivate or thread local") +__OMP_IMPLICIT_CLAUSE_NO_CLASS(unknown, "unknown") + +#undef __OMP_IMPLICIT_CLAUSE_NO_CLASS +#undef __OMP_IMPLICIT_CLAUSE_CLASS +#undef __OMP_CLAUSE +#undef OMP_CLAUSE_NO_CLASS +#undef OMP_CLAUSE_CLASS +#undef OMP_CLAUSE + +///} + /// Types used in runtime structs or runtime functions /// ///{ @@ -232,8 +343,10 @@ __OMP_RTL(omp_set_max_active_levels, false, Void, Int32) __OMP_RTL(__kmpc_master, false, Int32, IdentPtr, Int32) __OMP_RTL(__kmpc_end_master, false, Void, IdentPtr, Int32) __OMP_RTL(__kmpc_critical, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy) -__OMP_RTL(__kmpc_critical_with_hint, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy, Int32) -__OMP_RTL(__kmpc_end_critical, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy) +__OMP_RTL(__kmpc_critical_with_hint, false, Void, IdentPtr, Int32, + KmpCriticalNamePtrTy, Int32) +__OMP_RTL(__kmpc_end_critical, false, Void, IdentPtr, Int32, + KmpCriticalNamePtrTy) __OMP_RTL(__last, false, Void, ) diff --git a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp index 6ee44958d1c7..edd857d7b250 100644 --- a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp @@ -36,6 +36,24 @@ StringRef llvm::omp::getOpenMPDirectiveName(Directive Kind) { llvm_unreachable("Invalid OpenMP directive kind"); } +Clause llvm::omp::getOpenMPClauseKind(StringRef Str) { + return llvm::StringSwitch(Str) +#define OMP_CLAUSE(Enum, Str, Implicit) \ + .Case(Str, Implicit ? OMPC_unknown : Enum) +#include "llvm/Frontend/OpenMP/OMPKinds.def" + .Default(OMPC_unknown); +} + +StringRef llvm::omp::getOpenMPClauseName(Clause C) { + switch (C) { +#define OMP_CLAUSE(Enum, Str, ...) \ + case Enum: \ + return Str; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + } + llvm_unreachable("Invalid OpenMP clause kind"); +} + /// Declarations for LLVM-IR types (simple, array, function and structure) are /// generated below. Their names are defined and used in OpenMPKinds.def. Here /// we provide the declarations, the initializeTypes function will provide the From llvm-branch-commits at lists.llvm.org Fri Apr 3 23:58:40 2020 From: llvm-branch-commits at lists.llvm.org (Johannes Doerfert via llvm-branch-commits) Date: Fri, 03 Apr 2020 23:58:40 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 2a636ff - [OpenMP][NFC] Move and simplify directive -> allowed clause mapping Message-ID: <5e883020.1c69fb81.9d92a.8a64@mx.google.com> Author: Johannes Doerfert Date: 2020-04-04T00:27:07-05:00 New Revision: 2a636ffac1a7d92754cd323b5ba43e7b3a14a5d5 URL: https://github.com/llvm/llvm-project/commit/2a636ffac1a7d92754cd323b5ba43e7b3a14a5d5 DIFF: https://github.com/llvm/llvm-project/commit/2a636ffac1a7d92754cd323b5ba43e7b3a14a5d5.diff LOG: [OpenMP][NFC] Move and simplify directive -> allowed clause mapping Summary: Move the listing of allowed clauses per OpenMP directive to the new macro file in `llvm/Frontend/OpenMP`. Also, use a single generic macro that specifies the directive and one allowed clause explicitly instead of a dedicated macro per directive. We save 800 loc and boilerplate for all new directives/clauses with no functional change. We also need to include the macro file only once and not once per directive. Depends on D77112. Reviewers: lebedev.ri, JonChesterfield, ABataev Subscribers: hiraditya, bollu, guansong, jfb, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77113 Added: Modified: clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/ASTMatchers/Dynamic/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/Tooling/CMakeLists.txt clang/lib/Tooling/Transformer/CMakeLists.txt clang/unittests/AST/CMakeLists.txt clang/unittests/ASTMatchers/CMakeLists.txt clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt clang/unittests/Analysis/CMakeLists.txt clang/unittests/Rename/CMakeLists.txt clang/unittests/Sema/CMakeLists.txt clang/unittests/StaticAnalyzer/CMakeLists.txt clang/unittests/Tooling/CMakeLists.txt llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp Removed: ################################################################################ diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 8d97c32a0d36..9d7b4dcaacfd 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -7119,7 +7119,7 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) { /// ``isAllowedToContainClauseKind("OMPC_default").`` AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind, OpenMPClauseKind, CKind) { - return isAllowedClauseForDirective( + return llvm::omp::isAllowedClauseForDirective( Node.getDirectiveKind(), CKind, Finder->getASTContext().getLangOpts().OpenMP); } diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 4a4e6c6cb4c3..0ae0bc844e36 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -11,102 +11,6 @@ /// //===----------------------------------------------------------------------===// -#ifndef OPENMP_CLAUSE -# define OPENMP_CLAUSE(Name, Class) -#endif -#ifndef OPENMP_PARALLEL_CLAUSE -# define OPENMP_PARALLEL_CLAUSE(Name) -#endif -#ifndef OPENMP_SIMD_CLAUSE -# define OPENMP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_FOR_CLAUSE -# define OPENMP_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_FOR_SIMD_CLAUSE -# define OPENMP_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_SECTIONS_CLAUSE -# define OPENMP_SECTIONS_CLAUSE(Name) -#endif -#ifndef OPENMP_SINGLE_CLAUSE -# define OPENMP_SINGLE_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_FOR_CLAUSE -# define OPENMP_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_FOR_SIMD_CLAUSE -# define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_MASTER_CLAUSE -# define OPENMP_PARALLEL_MASTER_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_SECTIONS_CLAUSE -# define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) -#endif -#ifndef OPENMP_TASK_CLAUSE -# define OPENMP_TASK_CLAUSE(Name) -#endif -#ifndef OPENMP_ATOMIC_CLAUSE -# define OPENMP_ATOMIC_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_CLAUSE -# define OPENMP_TARGET_CLAUSE(Name) -#endif -#ifndef OPENMP_REQUIRES_CLAUSE -# define OPENMP_REQUIRES_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_DATA_CLAUSE -# define OPENMP_TARGET_DATA_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_ENTER_DATA_CLAUSE -#define OPENMP_TARGET_ENTER_DATA_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_EXIT_DATA_CLAUSE -#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_PARALLEL_CLAUSE -# define OPENMP_TARGET_PARALLEL_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_PARALLEL_FOR_CLAUSE -# define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_UPDATE_CLAUSE -# define OPENMP_TARGET_UPDATE_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_CLAUSE -# define OPENMP_TEAMS_CLAUSE(Name) -#endif -#ifndef OPENMP_CANCEL_CLAUSE -# define OPENMP_CANCEL_CLAUSE(Name) -#endif -#ifndef OPENMP_ORDERED_CLAUSE -# define OPENMP_ORDERED_CLAUSE(Name) -#endif -#ifndef OPENMP_TASKLOOP_CLAUSE -# define OPENMP_TASKLOOP_CLAUSE(Name) -#endif -#ifndef OPENMP_TASKLOOP_SIMD_CLAUSE -# define OPENMP_TASKLOOP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_MASTER_TASKLOOP_CLAUSE -# define OPENMP_MASTER_TASKLOOP_CLAUSE(Name) -#endif -#ifndef OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE -# define OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE -# define OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE -# define OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_CRITICAL_CLAUSE -# define OPENMP_CRITICAL_CLAUSE(Name) -#endif -#ifndef OPENMP_DISTRIBUTE_CLAUSE -#define OPENMP_DISTRIBUTE_CLAUSE(Name) -#endif #ifndef OPENMP_SCHEDULE_KIND #define OPENMP_SCHEDULE_KIND(Name) #endif @@ -143,164 +47,22 @@ #ifndef OPENMP_DEFAULTMAP_MODIFIER #define OPENMP_DEFAULTMAP_MODIFIER(Name) #endif -#ifndef OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_DISTRIBUTE_SIMD_CLAUSE -#define OPENMP_DISTRIBUTE_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_SIMD_CLAUSE -#define OPENMP_TARGET_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_CLAUSE -#define OPENMP_TARGET_TEAMS_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TASKGROUP_CLAUSE -#define OPENMP_TASKGROUP_CLAUSE(Name) -#endif -#ifndef OPENMP_DECLARE_MAPPER_CLAUSE -#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) -#endif -#ifndef OPENMP_ALLOCATE_CLAUSE -# define OPENMP_ALLOCATE_CLAUSE(Name) -#endif #ifndef OPENMP_DEVICE_TYPE_KIND #define OPENMP_DEVICE_TYPE_KIND(Name) #endif -#ifndef OPENMP_DECLARE_VARIANT_CLAUSE -#define OPENMP_DECLARE_VARIANT_CLAUSE(Name) -#endif #ifndef OPENMP_LASTPRIVATE_KIND #define OPENMP_LASTPRIVATE_KIND(Name) #endif #ifndef OPENMP_ORDER_KIND #define OPENMP_ORDER_KIND(Name) #endif -#ifndef OPENMP_FLUSH_CLAUSE -#define OPENMP_FLUSH_CLAUSE(Name) -#endif -#ifndef OPENMP_DEPOBJ_CLAUSE -#define OPENMP_DEPOBJ_CLAUSE(Name) -#endif #ifndef OPENMP_DEVICE_MODIFIER #define OPENMP_DEVICE_MODIFIER(Name) #endif -#ifndef OPENMP_SCAN_CLAUSE -#define OPENMP_SCAN_CLAUSE(Name) -#endif #ifndef OPENMP_REDUCTION_MODIFIER #define OPENMP_REDUCTION_MODIFIER(Name) #endif -// Clauses allowed for OpenMP directive 'scan'. -OPENMP_SCAN_CLAUSE(inclusive) -OPENMP_SCAN_CLAUSE(exclusive) - -// Clauses allowed for OpenMP directive 'parallel'. -OPENMP_PARALLEL_CLAUSE(if) -OPENMP_PARALLEL_CLAUSE(num_threads) -OPENMP_PARALLEL_CLAUSE(default) -OPENMP_PARALLEL_CLAUSE(proc_bind) -OPENMP_PARALLEL_CLAUSE(private) -OPENMP_PARALLEL_CLAUSE(firstprivate) -OPENMP_PARALLEL_CLAUSE(shared) -OPENMP_PARALLEL_CLAUSE(reduction) -OPENMP_PARALLEL_CLAUSE(copyin) -OPENMP_PARALLEL_CLAUSE(allocate) - -// Clauses allowed for directive 'omp simd'. -OPENMP_SIMD_CLAUSE(private) -OPENMP_SIMD_CLAUSE(lastprivate) -OPENMP_SIMD_CLAUSE(linear) -OPENMP_SIMD_CLAUSE(aligned) -OPENMP_SIMD_CLAUSE(safelen) -OPENMP_SIMD_CLAUSE(simdlen) -OPENMP_SIMD_CLAUSE(collapse) -OPENMP_SIMD_CLAUSE(reduction) -OPENMP_SIMD_CLAUSE(allocate) -OPENMP_SIMD_CLAUSE(if) -OPENMP_SIMD_CLAUSE(nontemporal) -OPENMP_SIMD_CLAUSE(order) - -// Clauses allowed for directive 'omp for'. -OPENMP_FOR_CLAUSE(private) -OPENMP_FOR_CLAUSE(lastprivate) -OPENMP_FOR_CLAUSE(firstprivate) -OPENMP_FOR_CLAUSE(reduction) -OPENMP_FOR_CLAUSE(collapse) -OPENMP_FOR_CLAUSE(schedule) -OPENMP_FOR_CLAUSE(ordered) -OPENMP_FOR_CLAUSE(nowait) -OPENMP_FOR_CLAUSE(linear) -OPENMP_FOR_CLAUSE(allocate) -OPENMP_FOR_CLAUSE(order) - -// Clauses allowed for directive 'omp for simd'. -OPENMP_FOR_SIMD_CLAUSE(private) -OPENMP_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_FOR_SIMD_CLAUSE(reduction) -OPENMP_FOR_SIMD_CLAUSE(schedule) -OPENMP_FOR_SIMD_CLAUSE(collapse) -OPENMP_FOR_SIMD_CLAUSE(nowait) -OPENMP_FOR_SIMD_CLAUSE(safelen) -OPENMP_FOR_SIMD_CLAUSE(simdlen) -OPENMP_FOR_SIMD_CLAUSE(linear) -OPENMP_FOR_SIMD_CLAUSE(aligned) -OPENMP_FOR_SIMD_CLAUSE(ordered) -OPENMP_FOR_SIMD_CLAUSE(allocate) -OPENMP_FOR_SIMD_CLAUSE(if) -OPENMP_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'omp sections'. -OPENMP_SECTIONS_CLAUSE(private) -OPENMP_SECTIONS_CLAUSE(lastprivate) -OPENMP_SECTIONS_CLAUSE(firstprivate) -OPENMP_SECTIONS_CLAUSE(reduction) -OPENMP_SECTIONS_CLAUSE(nowait) -OPENMP_SECTIONS_CLAUSE(allocate) - -// Clauses allowed for directive 'omp single'. -OPENMP_SINGLE_CLAUSE(private) -OPENMP_SINGLE_CLAUSE(firstprivate) -OPENMP_SINGLE_CLAUSE(copyprivate) -OPENMP_SINGLE_CLAUSE(nowait) -OPENMP_SINGLE_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'cancel'. -OPENMP_CANCEL_CLAUSE(if) - // Static attributes for 'schedule' clause. OPENMP_SCHEDULE_KIND(static) OPENMP_SCHEDULE_KIND(dynamic) @@ -345,209 +107,11 @@ OPENMP_LINEAR_KIND(val) OPENMP_LINEAR_KIND(ref) OPENMP_LINEAR_KIND(uval) -// Clauses allowed for OpenMP directive 'parallel for'. -OPENMP_PARALLEL_FOR_CLAUSE(if) -OPENMP_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_PARALLEL_FOR_CLAUSE(default) -OPENMP_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_PARALLEL_FOR_CLAUSE(private) -OPENMP_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_PARALLEL_FOR_CLAUSE(shared) -OPENMP_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_PARALLEL_FOR_CLAUSE(copyin) -OPENMP_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_PARALLEL_FOR_CLAUSE(ordered) -OPENMP_PARALLEL_FOR_CLAUSE(linear) -OPENMP_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'parallel for simd'. -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(copyin) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(ordered) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'parallel master'. -OPENMP_PARALLEL_MASTER_CLAUSE(if) -OPENMP_PARALLEL_MASTER_CLAUSE(num_threads) -OPENMP_PARALLEL_MASTER_CLAUSE(default) -OPENMP_PARALLEL_MASTER_CLAUSE(private) -OPENMP_PARALLEL_MASTER_CLAUSE(firstprivate) -OPENMP_PARALLEL_MASTER_CLAUSE(shared) -OPENMP_PARALLEL_MASTER_CLAUSE(copyin) -OPENMP_PARALLEL_MASTER_CLAUSE(reduction) -OPENMP_PARALLEL_MASTER_CLAUSE(proc_bind) -OPENMP_PARALLEL_MASTER_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'parallel sections'. -OPENMP_PARALLEL_SECTIONS_CLAUSE(if) -OPENMP_PARALLEL_SECTIONS_CLAUSE(num_threads) -OPENMP_PARALLEL_SECTIONS_CLAUSE(default) -OPENMP_PARALLEL_SECTIONS_CLAUSE(proc_bind) -OPENMP_PARALLEL_SECTIONS_CLAUSE(private) -OPENMP_PARALLEL_SECTIONS_CLAUSE(firstprivate) -OPENMP_PARALLEL_SECTIONS_CLAUSE(shared) -OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction) -OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin) -OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate) -OPENMP_PARALLEL_SECTIONS_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'task'. -OPENMP_TASK_CLAUSE(if) -OPENMP_TASK_CLAUSE(final) -OPENMP_TASK_CLAUSE(default) -OPENMP_TASK_CLAUSE(private) -OPENMP_TASK_CLAUSE(firstprivate) -OPENMP_TASK_CLAUSE(shared) -OPENMP_TASK_CLAUSE(untied) -OPENMP_TASK_CLAUSE(mergeable) -OPENMP_TASK_CLAUSE(depend) -OPENMP_TASK_CLAUSE(priority) -OPENMP_TASK_CLAUSE(in_reduction) -OPENMP_TASK_CLAUSE(allocate) -OPENMP_TASK_CLAUSE(detach) - -// Clauses allowed for OpenMP directive 'atomic'. -OPENMP_ATOMIC_CLAUSE(read) -OPENMP_ATOMIC_CLAUSE(write) -OPENMP_ATOMIC_CLAUSE(update) -OPENMP_ATOMIC_CLAUSE(capture) -OPENMP_ATOMIC_CLAUSE(seq_cst) -OPENMP_ATOMIC_CLAUSE(acq_rel) -OPENMP_ATOMIC_CLAUSE(acquire) -OPENMP_ATOMIC_CLAUSE(release) -OPENMP_ATOMIC_CLAUSE(relaxed) -OPENMP_ATOMIC_CLAUSE(hint) - -// Clauses allowed for OpenMP directive 'target'. -OPENMP_TARGET_CLAUSE(if) -OPENMP_TARGET_CLAUSE(device) -OPENMP_TARGET_CLAUSE(map) -OPENMP_TARGET_CLAUSE(private) -OPENMP_TARGET_CLAUSE(nowait) -OPENMP_TARGET_CLAUSE(depend) -OPENMP_TARGET_CLAUSE(defaultmap) -OPENMP_TARGET_CLAUSE(firstprivate) -OPENMP_TARGET_CLAUSE(is_device_ptr) -OPENMP_TARGET_CLAUSE(reduction) -OPENMP_TARGET_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'requires'. -OPENMP_REQUIRES_CLAUSE(unified_address) -OPENMP_REQUIRES_CLAUSE(unified_shared_memory) -OPENMP_REQUIRES_CLAUSE(reverse_offload) -OPENMP_REQUIRES_CLAUSE(dynamic_allocators) -OPENMP_REQUIRES_CLAUSE(atomic_default_mem_order) - -// Clauses allowed for OpenMP directive 'allocate'. -OPENMP_ALLOCATE_CLAUSE(allocator) - // Modifiers for 'atomic_default_mem_order' clause. OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst) OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel) OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(relaxed) -// Clauses allowed for OpenMP directive 'target data'. -OPENMP_TARGET_DATA_CLAUSE(if) -OPENMP_TARGET_DATA_CLAUSE(device) -OPENMP_TARGET_DATA_CLAUSE(map) -OPENMP_TARGET_DATA_CLAUSE(use_device_ptr) - -// Clauses allowed for OpenMP directive 'target enter data'. -OPENMP_TARGET_ENTER_DATA_CLAUSE(if) -OPENMP_TARGET_ENTER_DATA_CLAUSE(device) -OPENMP_TARGET_ENTER_DATA_CLAUSE(map) -OPENMP_TARGET_ENTER_DATA_CLAUSE(nowait) -OPENMP_TARGET_ENTER_DATA_CLAUSE(depend) - -// Clauses allowed for OpenMP directive 'target exit data'. -OPENMP_TARGET_EXIT_DATA_CLAUSE(if) -OPENMP_TARGET_EXIT_DATA_CLAUSE(device) -OPENMP_TARGET_EXIT_DATA_CLAUSE(map) -OPENMP_TARGET_EXIT_DATA_CLAUSE(nowait) -OPENMP_TARGET_EXIT_DATA_CLAUSE(depend) - -// Clauses allowed for OpenMP directive 'target parallel'. -OPENMP_TARGET_PARALLEL_CLAUSE(if) -OPENMP_TARGET_PARALLEL_CLAUSE(device) -OPENMP_TARGET_PARALLEL_CLAUSE(map) -OPENMP_TARGET_PARALLEL_CLAUSE(private) -OPENMP_TARGET_PARALLEL_CLAUSE(firstprivate) -OPENMP_TARGET_PARALLEL_CLAUSE(nowait) -OPENMP_TARGET_PARALLEL_CLAUSE(depend) -OPENMP_TARGET_PARALLEL_CLAUSE(defaultmap) -OPENMP_TARGET_PARALLEL_CLAUSE(num_threads) -OPENMP_TARGET_PARALLEL_CLAUSE(default) -OPENMP_TARGET_PARALLEL_CLAUSE(proc_bind) -OPENMP_TARGET_PARALLEL_CLAUSE(shared) -OPENMP_TARGET_PARALLEL_CLAUSE(reduction) -OPENMP_TARGET_PARALLEL_CLAUSE(is_device_ptr) -OPENMP_TARGET_PARALLEL_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target parallel for'. -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(if) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(device) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(map) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(private) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(nowait) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(depend) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(defaultmap) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(default) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(shared) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(is_device_ptr) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target update'. -OPENMP_TARGET_UPDATE_CLAUSE(if) -OPENMP_TARGET_UPDATE_CLAUSE(device) -OPENMP_TARGET_UPDATE_CLAUSE(to) -OPENMP_TARGET_UPDATE_CLAUSE(from) -OPENMP_TARGET_UPDATE_CLAUSE(nowait) -OPENMP_TARGET_UPDATE_CLAUSE(depend) - -// Clauses allowed for OpenMP directive 'teams'. -OPENMP_TEAMS_CLAUSE(default) -OPENMP_TEAMS_CLAUSE(private) -OPENMP_TEAMS_CLAUSE(firstprivate) -OPENMP_TEAMS_CLAUSE(shared) -OPENMP_TEAMS_CLAUSE(reduction) -OPENMP_TEAMS_CLAUSE(num_teams) -OPENMP_TEAMS_CLAUSE(thread_limit) -OPENMP_TEAMS_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'ordered'. -OPENMP_ORDERED_CLAUSE(threads) -OPENMP_ORDERED_CLAUSE(simd) -OPENMP_ORDERED_CLAUSE(depend) - // Map types for 'map' clause. OPENMP_MAP_KIND(alloc) OPENMP_MAP_KIND(to) @@ -567,552 +131,39 @@ OPENMP_TO_MODIFIER_KIND(mapper) // Modifiers for 'from' clause. OPENMP_FROM_MODIFIER_KIND(mapper) -// Clauses allowed for OpenMP directive 'taskloop'. -OPENMP_TASKLOOP_CLAUSE(if) -OPENMP_TASKLOOP_CLAUSE(shared) -OPENMP_TASKLOOP_CLAUSE(private) -OPENMP_TASKLOOP_CLAUSE(firstprivate) -OPENMP_TASKLOOP_CLAUSE(lastprivate) -OPENMP_TASKLOOP_CLAUSE(default) -OPENMP_TASKLOOP_CLAUSE(collapse) -OPENMP_TASKLOOP_CLAUSE(final) -OPENMP_TASKLOOP_CLAUSE(untied) -OPENMP_TASKLOOP_CLAUSE(mergeable) -OPENMP_TASKLOOP_CLAUSE(priority) -OPENMP_TASKLOOP_CLAUSE(grainsize) -OPENMP_TASKLOOP_CLAUSE(nogroup) -OPENMP_TASKLOOP_CLAUSE(num_tasks) -OPENMP_TASKLOOP_CLAUSE(reduction) -OPENMP_TASKLOOP_CLAUSE(in_reduction) -OPENMP_TASKLOOP_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'taskloop simd'. -OPENMP_TASKLOOP_SIMD_CLAUSE(if) -OPENMP_TASKLOOP_SIMD_CLAUSE(shared) -OPENMP_TASKLOOP_SIMD_CLAUSE(private) -OPENMP_TASKLOOP_SIMD_CLAUSE(firstprivate) -OPENMP_TASKLOOP_SIMD_CLAUSE(lastprivate) -OPENMP_TASKLOOP_SIMD_CLAUSE(default) -OPENMP_TASKLOOP_SIMD_CLAUSE(collapse) -OPENMP_TASKLOOP_SIMD_CLAUSE(final) -OPENMP_TASKLOOP_SIMD_CLAUSE(untied) -OPENMP_TASKLOOP_SIMD_CLAUSE(mergeable) -OPENMP_TASKLOOP_SIMD_CLAUSE(priority) -OPENMP_TASKLOOP_SIMD_CLAUSE(linear) -OPENMP_TASKLOOP_SIMD_CLAUSE(aligned) -OPENMP_TASKLOOP_SIMD_CLAUSE(safelen) -OPENMP_TASKLOOP_SIMD_CLAUSE(simdlen) -OPENMP_TASKLOOP_SIMD_CLAUSE(grainsize) -OPENMP_TASKLOOP_SIMD_CLAUSE(nogroup) -OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks) -OPENMP_TASKLOOP_SIMD_CLAUSE(reduction) -OPENMP_TASKLOOP_SIMD_CLAUSE(in_reduction) -OPENMP_TASKLOOP_SIMD_CLAUSE(allocate) -OPENMP_TASKLOOP_SIMD_CLAUSE(nontemporal) -OPENMP_TASKLOOP_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'master taskloop'. -OPENMP_MASTER_TASKLOOP_CLAUSE(if) -OPENMP_MASTER_TASKLOOP_CLAUSE(shared) -OPENMP_MASTER_TASKLOOP_CLAUSE(private) -OPENMP_MASTER_TASKLOOP_CLAUSE(firstprivate) -OPENMP_MASTER_TASKLOOP_CLAUSE(lastprivate) -OPENMP_MASTER_TASKLOOP_CLAUSE(default) -OPENMP_MASTER_TASKLOOP_CLAUSE(collapse) -OPENMP_MASTER_TASKLOOP_CLAUSE(final) -OPENMP_MASTER_TASKLOOP_CLAUSE(untied) -OPENMP_MASTER_TASKLOOP_CLAUSE(mergeable) -OPENMP_MASTER_TASKLOOP_CLAUSE(priority) -OPENMP_MASTER_TASKLOOP_CLAUSE(grainsize) -OPENMP_MASTER_TASKLOOP_CLAUSE(nogroup) -OPENMP_MASTER_TASKLOOP_CLAUSE(num_tasks) -OPENMP_MASTER_TASKLOOP_CLAUSE(reduction) -OPENMP_MASTER_TASKLOOP_CLAUSE(in_reduction) -OPENMP_MASTER_TASKLOOP_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'master taskloop simd'. -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(if) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(shared) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(private) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(firstprivate) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(lastprivate) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(default) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(collapse) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(final) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(untied) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(mergeable) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(priority) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(linear) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(aligned) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(safelen) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(simdlen) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(grainsize) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(nogroup) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(num_tasks) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(reduction) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(in_reduction) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(allocate) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(nontemporal) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'parallel master taskloop'. -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(if) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(shared) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(private) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(firstprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(lastprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(default) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(collapse) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(final) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(untied) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(mergeable) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(priority) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(grainsize) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(nogroup) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(num_tasks) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(reduction) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(allocate) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(num_threads) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(proc_bind) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(copyin) - -// Clauses allowed for OpenMP directive 'parallel master taskloop simd'. -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(if) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(shared) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(private) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(firstprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(lastprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(default) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(collapse) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(final) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(untied) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(mergeable) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(priority) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(grainsize) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(nogroup) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(num_tasks) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(reduction) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(allocate) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(num_threads) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(proc_bind) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(copyin) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(linear) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(aligned) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(safelen) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(simdlen) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(nontemporal) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'critical'. -OPENMP_CRITICAL_CLAUSE(hint) - -// Clauses allowed for OpenMP directive 'distribute' -OPENMP_DISTRIBUTE_CLAUSE(private) -OPENMP_DISTRIBUTE_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_CLAUSE(collapse) -OPENMP_DISTRIBUTE_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_CLAUSE(allocate) - // Static attributes for 'dist_schedule' clause. OPENMP_DIST_SCHEDULE_KIND(static) -// Clauses allowed for OpenMP directive 'distribute parallel for' -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'distribute parallel for simd' -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(copyin) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'distribute simd' -OPENMP_DISTRIBUTE_SIMD_CLAUSE(private) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(collapse) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(linear) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(aligned) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(safelen) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(simdlen) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(allocate) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(if) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(nontemporal) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target parallel for simd'. -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(device) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(map) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(nowait) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(depend) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(ordered) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target simd'. -OPENMP_TARGET_SIMD_CLAUSE(if) -OPENMP_TARGET_SIMD_CLAUSE(device) -OPENMP_TARGET_SIMD_CLAUSE(map) -OPENMP_TARGET_SIMD_CLAUSE(private) -OPENMP_TARGET_SIMD_CLAUSE(nowait) -OPENMP_TARGET_SIMD_CLAUSE(depend) -OPENMP_TARGET_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_SIMD_CLAUSE(linear) -OPENMP_TARGET_SIMD_CLAUSE(aligned) -OPENMP_TARGET_SIMD_CLAUSE(safelen) -OPENMP_TARGET_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_SIMD_CLAUSE(collapse) -OPENMP_TARGET_SIMD_CLAUSE(reduction) -OPENMP_TARGET_SIMD_CLAUSE(allocate) -OPENMP_TARGET_SIMD_CLAUSE(nontemporal) -OPENMP_TARGET_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'teams distribute'. -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'teams distribute simd' -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nontemporal) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'teams distribute parallel for simd' -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'teams distribute parallel for' -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target teams'. -OPENMP_TARGET_TEAMS_CLAUSE(if) -OPENMP_TARGET_TEAMS_CLAUSE(device) -OPENMP_TARGET_TEAMS_CLAUSE(map) -OPENMP_TARGET_TEAMS_CLAUSE(private) -OPENMP_TARGET_TEAMS_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_CLAUSE(depend) -OPENMP_TARGET_TEAMS_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_CLAUSE(default) -OPENMP_TARGET_TEAMS_CLAUSE(shared) -OPENMP_TARGET_TEAMS_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target teams distribute'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(default) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target teams distribute parallel for'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive -// 'target teams distribute parallel for simd'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target teams distribute simd'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nontemporal) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'taskgroup'. -OPENMP_TASKGROUP_CLAUSE(task_reduction) -OPENMP_TASKGROUP_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'declare mapper'. -OPENMP_DECLARE_MAPPER_CLAUSE(map) - // Device types for 'device_type' clause. OPENMP_DEVICE_TYPE_KIND(host) OPENMP_DEVICE_TYPE_KIND(nohost) OPENMP_DEVICE_TYPE_KIND(any) -// Clauses allowed for OpenMP directive 'declare variant'. -OPENMP_DECLARE_VARIANT_CLAUSE(match) - // Type of the 'lastprivate' clause. OPENMP_LASTPRIVATE_KIND(conditional) // Type of the 'order' clause. OPENMP_ORDER_KIND(concurrent) -// Clauses allowed for OpenMP directive 'flush'. -OPENMP_FLUSH_CLAUSE(acq_rel) -OPENMP_FLUSH_CLAUSE(acquire) -OPENMP_FLUSH_CLAUSE(release) - -// Clauses allowed for OpenMP directive 'depobj'. -OPENMP_DEPOBJ_CLAUSE(depend) -OPENMP_DEPOBJ_CLAUSE(destroy) -OPENMP_DEPOBJ_CLAUSE(update) - // Modifiers for 'reduction' clause. OPENMP_REDUCTION_MODIFIER(default) OPENMP_REDUCTION_MODIFIER(inscan) #undef OPENMP_REDUCTION_MODIFIER -#undef OPENMP_SCAN_CLAUSE #undef OPENMP_DEVICE_MODIFIER -#undef OPENMP_DEPOBJ_CLAUSE -#undef OPENMP_FLUSH_CLAUSE #undef OPENMP_ORDER_KIND #undef OPENMP_LASTPRIVATE_KIND -#undef OPENMP_DECLARE_VARIANT_CLAUSE #undef OPENMP_DEVICE_TYPE_KIND -#undef OPENMP_ALLOCATE_CLAUSE -#undef OPENMP_DECLARE_MAPPER_CLAUSE -#undef OPENMP_TASKGROUP_CLAUSE -#undef OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE -#undef OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE -#undef OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE -#undef OPENMP_MASTER_TASKLOOP_CLAUSE -#undef OPENMP_TASKLOOP_SIMD_CLAUSE -#undef OPENMP_TASKLOOP_CLAUSE #undef OPENMP_LINEAR_KIND #undef OPENMP_DEPEND_KIND #undef OPENMP_SCHEDULE_MODIFIER #undef OPENMP_SCHEDULE_KIND -#undef OPENMP_CLAUSE -#undef OPENMP_CRITICAL_CLAUSE -#undef OPENMP_ORDERED_CLAUSE -#undef OPENMP_CANCEL_CLAUSE -#undef OPENMP_SINGLE_CLAUSE -#undef OPENMP_SECTIONS_CLAUSE -#undef OPENMP_PARALLEL_CLAUSE -#undef OPENMP_PARALLEL_FOR_CLAUSE -#undef OPENMP_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_PARALLEL_MASTER_CLAUSE -#undef OPENMP_PARALLEL_SECTIONS_CLAUSE -#undef OPENMP_TASK_CLAUSE -#undef OPENMP_ATOMIC_CLAUSE -#undef OPENMP_TARGET_CLAUSE -#undef OPENMP_REQUIRES_CLAUSE #undef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND -#undef OPENMP_TARGET_DATA_CLAUSE -#undef OPENMP_TARGET_ENTER_DATA_CLAUSE -#undef OPENMP_TARGET_EXIT_DATA_CLAUSE -#undef OPENMP_TARGET_PARALLEL_CLAUSE -#undef OPENMP_TARGET_PARALLEL_FOR_CLAUSE -#undef OPENMP_TEAMS_CLAUSE -#undef OPENMP_SIMD_CLAUSE -#undef OPENMP_FOR_CLAUSE -#undef OPENMP_FOR_SIMD_CLAUSE #undef OPENMP_MAP_KIND #undef OPENMP_MAP_MODIFIER_KIND #undef OPENMP_TO_MODIFIER_KIND #undef OPENMP_FROM_MODIFIER_KIND -#undef OPENMP_DISTRIBUTE_CLAUSE #undef OPENMP_DIST_SCHEDULE_KIND #undef OPENMP_DEFAULTMAP_KIND #undef OPENMP_DEFAULTMAP_MODIFIER -#undef OPENMP_TARGET_UPDATE_CLAUSE -#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_DISTRIBUTE_SIMD_CLAUSE -#undef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_TARGET_SIMD_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#undef OPENMP_TARGET_TEAMS_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE + diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 9a6a2050a165..08aaf2d43bfd 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -173,10 +173,6 @@ enum OpenMPReductionClauseModifier { unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str); const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type); -bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind, - OpenMPClauseKind CKind, - unsigned OpenMPVersion); - /// Checks if the specified directive is a directive with an associated /// loop construct. /// \param DKind Specified directive. diff --git a/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt b/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt index 82c12a47fa93..10bd9c455eb4 100644 --- a/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt +++ b/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt @@ -1,4 +1,7 @@ -set(LLVM_LINK_COMPONENTS support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) # The registry source file ends up generating a lot of sections for each # matcher. Each matcher appears to get a vtable and several methods. Each diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 981bd7adbe9b..888666b30d2e 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -425,581 +425,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, llvm_unreachable("Invalid OpenMP simple clause kind"); } -bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, - OpenMPClauseKind CKind, - unsigned OpenMPVersion) { - assert(unsigned(DKind) <= unsigned(OMPD_unknown)); - assert(CKind <= OMPC_unknown); - // Nontemporal clause is not supported in OpenMP < 5.0. - if (OpenMPVersion < 50 && CKind == OMPC_nontemporal) - return false; - // Order clause is not supported in OpenMP < 5.0. - if (OpenMPVersion < 50 && CKind == OMPC_order) - return false; - switch (DKind) { - case OMPD_parallel: - switch (CKind) { -#define OPENMP_PARALLEL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_for: - switch (CKind) { -#define OPENMP_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_for_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_sections: - switch (CKind) { -#define OPENMP_SECTIONS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_single: - switch (CKind) { -#define OPENMP_SINGLE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_for: - switch (CKind) { -#define OPENMP_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_for_simd: - switch (CKind) { -#define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_master: - switch (CKind) { -#define OPENMP_PARALLEL_MASTER_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_sections: - switch (CKind) { -#define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_task: - if (OpenMPVersion < 50 && CKind == OMPC_detach) - return false; - switch (CKind) { -#define OPENMP_TASK_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_flush: - if (CKind == OMPC_flush) - return true; - if (OpenMPVersion < 50) - return false; - switch (CKind) { -#define OPENMP_FLUSH_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_depobj: - if (OpenMPVersion < 50) - return false; - switch (CKind) { -#define OPENMP_DEPOBJ_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_depobj: - return true; - default: - break; - } - break; - case OMPD_scan: - if (OpenMPVersion < 50) - return false; - switch (CKind) { -#define OPENMP_SCAN_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_atomic: - if (OpenMPVersion < 50 && - (CKind == OMPC_acq_rel || CKind == OMPC_acquire || - CKind == OMPC_release || CKind == OMPC_relaxed || CKind == OMPC_hint)) - return false; - switch (CKind) { -#define OPENMP_ATOMIC_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target: - switch (CKind) { -#define OPENMP_TARGET_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_requires: - switch (CKind) { -#define OPENMP_REQUIRES_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_data: - switch (CKind) { -#define OPENMP_TARGET_DATA_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_enter_data: - switch (CKind) { -#define OPENMP_TARGET_ENTER_DATA_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_exit_data: - switch (CKind) { -#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_parallel: - switch (CKind) { -#define OPENMP_TARGET_PARALLEL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_parallel_for: - switch (CKind) { -#define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_update: - switch (CKind) { -#define OPENMP_TARGET_UPDATE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams: - switch (CKind) { -#define OPENMP_TEAMS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_cancel: - switch (CKind) { -#define OPENMP_CANCEL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_ordered: - switch (CKind) { -#define OPENMP_ORDERED_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_taskloop: - switch (CKind) { -#define OPENMP_TASKLOOP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_taskloop_simd: - switch (CKind) { -#define OPENMP_TASKLOOP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_master_taskloop: - switch (CKind) { -#define OPENMP_MASTER_TASKLOOP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_master_taskloop_simd: - switch (CKind) { -#define OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_master_taskloop: - switch (CKind) { -#define OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_master_taskloop_simd: - switch (CKind) { -#define OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_critical: - switch (CKind) { -#define OPENMP_CRITICAL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute: - switch (CKind) { -#define OPENMP_DISTRIBUTE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute_parallel_for: - switch (CKind) { -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute_parallel_for_simd: - switch (CKind) { -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_DISTRIBUTE_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_parallel_for_simd: - switch (CKind) { -#define OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_simd: - switch (CKind) { -#define OPENMP_TARGET_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute: - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute_parallel_for_simd: - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute_parallel_for: - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute_parallel_for: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute_parallel_for_simd: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute_simd: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_taskgroup: - switch (CKind) { -#define OPENMP_TASKGROUP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_declare_mapper: - switch (CKind) { -#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_allocate: - switch (CKind) { -#define OPENMP_ALLOCATE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_declare_variant: - switch (CKind) { -#define OPENMP_DECLARE_VARIANT_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_unknown: - case OMPD_threadprivate: - case OMPD_section: - case OMPD_master: - case OMPD_taskyield: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_declare_reduction: - case OMPD_declare_simd: - break; - } - return false; -} - bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd || DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd || diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt index 59c990daaa29..71b6cc55e504 100644 --- a/clang/lib/Tooling/CMakeLists.txt +++ b/clang/lib/Tooling/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS Option + FrontendOpenMP Support ) diff --git a/clang/lib/Tooling/Transformer/CMakeLists.txt b/clang/lib/Tooling/Transformer/CMakeLists.txt index 68f0cfeee8f6..281af1007a65 100644 --- a/clang/lib/Tooling/Transformer/CMakeLists.txt +++ b/clang/lib/Tooling/Transformer/CMakeLists.txt @@ -1,4 +1,7 @@ -set(LLVM_LINK_COMPONENTS Support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) add_clang_library(clangTransformer RangeSelector.cpp diff --git a/clang/unittests/AST/CMakeLists.txt b/clang/unittests/AST/CMakeLists.txt index b738ce08d06d..868635b6eea5 100644 --- a/clang/unittests/AST/CMakeLists.txt +++ b/clang/unittests/AST/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/ASTMatchers/CMakeLists.txt b/clang/unittests/ASTMatchers/CMakeLists.txt index aa5438c947f4..e128cfe695a6 100644 --- a/clang/unittests/ASTMatchers/CMakeLists.txt +++ b/clang/unittests/ASTMatchers/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt b/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt index c40964dfaf0b..85556b01cae1 100644 --- a/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt +++ b/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/Analysis/CMakeLists.txt b/clang/unittests/Analysis/CMakeLists.txt index 03716e2e5e97..66069c854a6a 100644 --- a/clang/unittests/Analysis/CMakeLists.txt +++ b/clang/unittests/Analysis/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/Rename/CMakeLists.txt b/clang/unittests/Rename/CMakeLists.txt index a33d7d8ef720..6ec0c521551c 100644 --- a/clang/unittests/Rename/CMakeLists.txt +++ b/clang/unittests/Rename/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP support ) diff --git a/clang/unittests/Sema/CMakeLists.txt b/clang/unittests/Sema/CMakeLists.txt index 6832908e7fb1..24105d7756f4 100644 --- a/clang/unittests/Sema/CMakeLists.txt +++ b/clang/unittests/Sema/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt b/clang/unittests/StaticAnalyzer/CMakeLists.txt index ff92bdcb299a..5ce660f00040 100644 --- a/clang/unittests/StaticAnalyzer/CMakeLists.txt +++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/Tooling/CMakeLists.txt b/clang/unittests/Tooling/CMakeLists.txt index 1f66ffd598d4..67ab6bea2016 100644 --- a/clang/unittests/Tooling/CMakeLists.txt +++ b/clang/unittests/Tooling/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} + FrontendOpenMP Support ) diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h index d32fa8dc98ef..40da41be9297 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -100,6 +100,9 @@ Clause getOpenMPClauseKind(StringRef Str); /// Return a textual representation of the clause \p C. StringRef getOpenMPClauseName(Clause C); +/// Return true if \p C is a valid clause for \p D in version \p Version. +bool isAllowedClauseForDirective(Directive D, Clause C, unsigned Version); + /// Forward declarations for LLVM-IR types (simple, function and structure) are /// generated below. Their names are defined and used in OpenMP/OMPKinds.def. /// Here we provide the forward declarations, the initializeTypes function will diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index 09468358415f..7ac614e99201 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -710,3 +710,732 @@ OMP_LAST_TRAIT_PROPERTY( #undef __OMP_REQUIRES_TRAIT #undef OMP_REQUIRES_TRAIT ///} + + +/// Clauses allowed per directive +/// +///{ + +#ifndef OMP_DIRECTIVE_CLAUSE +#define OMP_DIRECTIVE_CLAUSE(Directive, MinVersion, MaxVersion, Clause) +#endif + +#define __OMP_DIRECTIVE_CLAUSE(Directive, MinVersion, MaxVersion, Clause) \ + OMP_DIRECTIVE_CLAUSE(OMPD_##Directive, unsigned(MinVersion), \ + unsigned(MaxVersion), OMPC_##Clause) + +__OMP_DIRECTIVE_CLAUSE(scan, 50, ~0, inclusive) +__OMP_DIRECTIVE_CLAUSE(scan, 50, ~0, exclusive) + +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(simd, 50, ~0, if) +__OMP_DIRECTIVE_CLAUSE(simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, ordered) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(for_simd, 50, ~0, if) +__OMP_DIRECTIVE_CLAUSE(for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, copyprivate) +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(cancel, 1, ~0, if) + +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(task, 50, ~0, detach) + +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, read) +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, write) +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, update) +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, capture) +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, seq_cst) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, acq_rel) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, acquire) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, release) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, relaxed) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, hint) + +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, unified_address) +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, unified_shared_memory) +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, reverse_offload) +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, dynamic_allocators) +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, atomic_default_mem_order) + +__OMP_DIRECTIVE_CLAUSE(allocate, 1, ~0, allocator) + +__OMP_DIRECTIVE_CLAUSE(target_data, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_data, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_data, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_data, 1, ~0, use_device_ptr) + +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, depend) + +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, depend) + +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, to) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, from) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, depend) + +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(ordered, 1, ~0, threads) +__OMP_DIRECTIVE_CLAUSE(ordered, 1, ~0, simd) +__OMP_DIRECTIVE_CLAUSE(ordered, 1, ~0, depend) + +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, copyin) + +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(critical, 1, ~0, hint) + +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 50, ~0, if) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(target_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 50, ~0, if) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, + firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, + is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, + thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, + dist_schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + private) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + default) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + collapse) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + dist_schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + num_threads) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + aligned) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + safelen) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + simdlen) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + allocate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 50, ~0, + nontemporal) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(taskgroup, 1, ~0, task_reduction) +__OMP_DIRECTIVE_CLAUSE(taskgroup, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(declare_mapper, 1, ~0, map) + +__OMP_DIRECTIVE_CLAUSE(declare_variant, 1, ~0, match) + +__OMP_DIRECTIVE_CLAUSE(flush, 50, ~0, acq_rel) +__OMP_DIRECTIVE_CLAUSE(flush, 50, ~0, acquire) +__OMP_DIRECTIVE_CLAUSE(flush, 50, ~0, release) +// TODO This should ne `none` instead +__OMP_DIRECTIVE_CLAUSE(flush, 1, ~0, flush) + +__OMP_DIRECTIVE_CLAUSE(depobj, 50, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(depobj, 50, ~0, destroy) +__OMP_DIRECTIVE_CLAUSE(depobj, 50, ~0, update) +// TODO This should ne `none` instead +__OMP_DIRECTIVE_CLAUSE(depobj, 50, ~0, depobj) + +#undef __OMP_DIRECTIVE_CLAUSE +#undef OMP_DIRECTIVE_CLAUSE +///} diff --git a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp index edd857d7b250..ed19ae38c698 100644 --- a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp @@ -54,6 +54,17 @@ StringRef llvm::omp::getOpenMPClauseName(Clause C) { llvm_unreachable("Invalid OpenMP clause kind"); } +bool llvm::omp::isAllowedClauseForDirective(Directive D, Clause C, + unsigned Version) { + assert(unsigned(D) <= unsigned(OMPD_unknown)); + assert(unsigned(C) <= unsigned(OMPC_unknown)); +#define OMP_DIRECTIVE_CLAUSE(Dir, MinVersion, MaxVersion, Cl) \ + if (D == Dir && C == Cl && MinVersion <= Version && MaxVersion >= Version) \ + return true; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + return false; +} + /// Declarations for LLVM-IR types (simple, array, function and structure) are /// generated below. Their names are defined and used in OpenMPKinds.def. Here /// we provide the declarations, the initializeTypes function will provide the From llvm-branch-commits at lists.llvm.org Fri Apr 3 23:58:45 2020 From: llvm-branch-commits at lists.llvm.org (Johannes Doerfert via llvm-branch-commits) Date: Fri, 03 Apr 2020 23:58:45 -0700 (PDT) Subject: [llvm-branch-commits] [clang] d1fe204 - [OpenMP] Specialize OpenMP calls after template instantiation Message-ID: <5e883025.1c69fb81.e1c6d.3104@mx.google.com> Author: Johannes Doerfert Date: 2020-04-04T01:56:18-05:00 New Revision: d1fe2040b09288e1fc582fe87911ee5d4edc7aa0 URL: https://github.com/llvm/llvm-project/commit/d1fe2040b09288e1fc582fe87911ee5d4edc7aa0 DIFF: https://github.com/llvm/llvm-project/commit/d1fe2040b09288e1fc582fe87911ee5d4edc7aa0.diff LOG: [OpenMP] Specialize OpenMP calls after template instantiation Summary: As with regular calls, we want to specialize a call that went through template instantiation if it has an applicable OpenMP declare variant. Depends on D77113. Reviewers: kiranchandramohan, ABataev, RaviNarayanaswamy, gtbercea, grokos, sdmitriev, JonChesterfield, hfinkel, fghanim, aaron.ballman Subscribers: yaxunl, bollu, guansong, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77290 Added: clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp Modified: clang/lib/Sema/SemaTemplateInstantiate.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index e2b3ebba6bbe..7ed26042c16a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1056,6 +1056,7 @@ namespace { const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH); ExprResult TransformPredefinedExpr(PredefinedExpr *E); + ExprResult TransformCallExpr(CallExpr *E); ExprResult TransformDeclRefExpr(DeclRefExpr *E); ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E); @@ -1688,6 +1689,17 @@ TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E, return RebuildVarDeclRefExpr(cast(TransformedDecl), E->getExprLoc()); } +ExprResult TemplateInstantiator::TransformCallExpr(CallExpr *E) { + ExprResult R = TreeTransform::TransformCallExpr(E); + if (!SemaRef.getLangOpts().OpenMP || !R.isUsable() || !isa(R.get())) + return R; + + auto *CE = cast(R.get()); + return SemaRef.ActOnOpenMPCall(R, nullptr, CE->getRParenLoc(), + MultiExprArg(CE->getArgs(), CE->getNumArgs()), + CE->getRParenLoc(), nullptr); +} + ExprResult TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) { NamedDecl *D = E->getDecl(); diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp b/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp new file mode 100644 index 000000000000..4127500a0311 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp @@ -0,0 +1,160 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics + +int also_before() { + return 1; +} + +#pragma omp begin declare variant match(implementation={vendor(score(100):llvm)}) +int also_after(void) { + return 2; +} +int also_after(int) { + return 3; +} +int also_after(double) { + return 0; +} +#pragma omp end declare variant +#pragma omp begin declare variant match(implementation={vendor(score(0):llvm)}) +int also_before() { + return 0; +} +#pragma omp end declare variant + +int also_after(void) { + return 4; +} +int also_after(int) { + return 5; +} +int also_after(double) { + return 6; +} + +template +int test1() { + // Should return 0. + return also_after(T(0)); +} + +typedef int(*Ty)(); + +template +int test2() { + // Should return 0. + return fn(); +} + +int test() { + // Should return 0. + return test1() + test2(); +} + + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 implicit used also_before 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] col:5 implicit also_after 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_8:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_9:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_11:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_12:0x[a-z0-9]*]] 'int (int)' Function [[ADDR_13:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int (int)' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_14:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_15:0x[a-z0-9]*]] 'int (double)' Function [[ADDR_16:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int (double)' +// CHECK-NEXT: |-FunctionDecl [[ADDR_10]] line:10:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_17:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_18:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_19:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: |-FunctionDecl [[ADDR_13]] line:13:1 also_after[implementation={vendor(llvm)}] 'int (int)' +// CHECK-NEXT: | |-ParmVarDecl [[ADDR_20:0x[a-z0-9]*]] col:19 'int' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_21:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_22:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_23:0x[a-z0-9]*]] 'int' 3 +// CHECK-NEXT: |-FunctionDecl [[ADDR_16]] line:16:1 also_after[implementation={vendor(llvm)}] 'int (double)' +// CHECK-NEXT: | |-ParmVarDecl [[ADDR_24:0x[a-z0-9]*]] col:22 'double' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_25:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_26:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_27:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_6]] line:21:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_28:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_29:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_30:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_31:0x[a-z0-9]*]] prev [[ADDR_7]] line:26:5 also_after 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_32:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_33:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_34:0x[a-z0-9]*]] 'int' 4 +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_35:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_36:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_12]] 'int (int)' Function [[ADDR_13]] 'also_after[implementation={vendor(llvm)}]' 'int (int)' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_37:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_15]] 'int (double)' Function [[ADDR_16]] 'also_after[implementation={vendor(llvm)}]' 'int (double)' +// CHECK-NEXT: |-FunctionDecl [[ADDR_38:0x[a-z0-9]*]] line:29:5 also_after 'int (int)' +// CHECK-NEXT: | |-ParmVarDecl [[ADDR_39:0x[a-z0-9]*]] col:19 'int' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_40:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_41:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_42:0x[a-z0-9]*]] 'int' 5 +// CHECK-NEXT: |-FunctionDecl [[ADDR_43:0x[a-z0-9]*]] line:32:5 used also_after 'int (double)' +// CHECK-NEXT: | |-ParmVarDecl [[ADDR_44:0x[a-z0-9]*]] col:22 'double' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_45:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_46:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_47:0x[a-z0-9]*]] 'int' 6 +// CHECK-NEXT: |-FunctionTemplateDecl [[ADDR_48:0x[a-z0-9]*]] line:37:5 test1 +// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_49:0x[a-z0-9]*]] col:19 referenced typename depth 0 index 0 T +// CHECK-NEXT: | |-FunctionDecl [[ADDR_50:0x[a-z0-9]*]] line:37:5 test1 'int ({{.*}})' +// CHECK-NEXT: | | `-CompoundStmt [[ADDR_51:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_52:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-CallExpr [[ADDR_53:0x[a-z0-9]*]] '' +// CHECK-NEXT: | | |-UnresolvedLookupExpr [[ADDR_54:0x[a-z0-9]*]] '' {{.*}}(ADL) = 'also_after' [[ADDR_43]] [[ADDR_38]] [[ADDR_31]] +// CHECK-NEXT: | | `-CXXUnresolvedConstructExpr [[ADDR_55:0x[a-z0-9]*]] 'T' 'T' +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_56:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-FunctionDecl [[ADDR_57:0x[a-z0-9]*]] line:37:5 used test1 'int ({{.*}})' +// CHECK-NEXT: | |-TemplateArgument type 'double' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_58:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_59:0x[a-z0-9]*]] +// CHECK-NEXT: | `-CallExpr [[ADDR_60:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-ImplicitCastExpr [[ADDR_61:0x[a-z0-9]*]] 'int (*)(double)' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_62:0x[a-z0-9]*]] 'int (double)' {{.*}}Function [[ADDR_43]] 'also_after' 'int (double)' +// CHECK-NEXT: | `-CXXFunctionalCastExpr [[ADDR_63:0x[a-z0-9]*]] 'double':'double' functional cast to double +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_64:0x[a-z0-9]*]] 'double':'double' part_of_explicit_cast +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_56]] 'int' 0 +// CHECK-NEXT: |-TypedefDecl [[ADDR_65:0x[a-z0-9]*]] col:14 referenced Ty 'int (*)({{.*}})' +// CHECK-NEXT: | `-PointerType [[ADDR_66:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-ParenType [[ADDR_67:0x[a-z0-9]*]] 'int ({{.*}})' sugar +// CHECK-NEXT: | `-FunctionProtoType [[ADDR_68:0x[a-z0-9]*]] 'int ({{.*}})' cdecl +// CHECK-NEXT: | `-BuiltinType [[ADDR_69:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: |-FunctionTemplateDecl [[ADDR_70:0x[a-z0-9]*]] line:45:5 test2 +// CHECK-NEXT: | |-NonTypeTemplateParmDecl [[ADDR_71:0x[a-z0-9]*]] col:13 referenced 'Ty':'int (*)({{.*}})' depth 0 index 0 fn +// CHECK-NEXT: | |-FunctionDecl [[ADDR_72:0x[a-z0-9]*]] line:45:5 test2 'int ({{.*}})' +// CHECK-NEXT: | | `-CompoundStmt [[ADDR_73:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_74:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-CallExpr [[ADDR_75:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_76:0x[a-z0-9]*]] 'Ty':'int (*)({{.*}})' NonTypeTemplateParm [[ADDR_71]] 'fn' 'Ty':'int (*)({{.*}})' +// CHECK-NEXT: | `-FunctionDecl [[ADDR_77:0x[a-z0-9]*]] line:45:5 used test2 'int ({{.*}})' +// CHECK-NEXT: | |-TemplateArgument decl +// CHECK-NEXT: | | `-Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_78:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_79:0x[a-z0-9]*]] +// CHECK-NEXT: | `-PseudoObjectExpr [[ADDR_80:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_81:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-SubstNonTypeTemplateParmExpr [[ADDR_82:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-UnaryOperator [[ADDR_83:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_84:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_85:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_86:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_5]] 'int ({{.*}})' Function [[ADDR_6]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_87:0x[a-z0-9]*]] line:50:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_88:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_89:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_90:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-CallExpr [[ADDR_91:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_92:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_93:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_57]] 'test1' 'int ({{.*}})' (FunctionTemplate [[ADDR_48]] 'test1') +// CHECK-NEXT: `-CallExpr [[ADDR_94:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_95:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_96:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_77]] 'test2' 'int ({{.*}})' (FunctionTemplate [[ADDR_70]] 'test2') From llvm-branch-commits at lists.llvm.org Fri Apr 3 23:58:42 2020 From: llvm-branch-commits at lists.llvm.org (Johannes Doerfert via llvm-branch-commits) Date: Fri, 03 Apr 2020 23:58:42 -0700 (PDT) Subject: [llvm-branch-commits] [clang] 7d29ad3 - [OpenMP] Try to find an existing base for `omp begin/end declare variant` Message-ID: <5e883022.1c69fb81.17fce.10cb@mx.google.com> Author: Johannes Doerfert Date: 2020-04-04T01:56:15-05:00 New Revision: 7d29ad378f36284da426cc3c7d775bc208748bf4 URL: https://github.com/llvm/llvm-project/commit/7d29ad378f36284da426cc3c7d775bc208748bf4 DIFF: https://github.com/llvm/llvm-project/commit/7d29ad378f36284da426cc3c7d775bc208748bf4.diff LOG: [OpenMP] Try to find an existing base for `omp begin/end declare variant` Summary: If we have a function definition in `omp begin/end declare variant` it is a specialization of a base function with the same name and "compatible" type. Before, we just created a declaration for the base. With this patch we try to find an existing declaration first and only create a new one if we did not find any with a compatible type. This is preferable as we can tolerate slight mismatches, especially if the specialized version is "more constrained", e.g., constexpr. Reviewers: kiranchandramohan, ABataev, RaviNarayanaswamy, gtbercea, grokos, sdmitriev, JonChesterfield, hfinkel, fghanim, aaron.ballman Subscribers: yaxunl, bollu, guansong, openmp-commits, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77252 Added: clang/test/AST/ast-dump-openmp-begin-declare-variant_10.c clang/test/AST/ast-dump-openmp-begin-declare-variant_11.c clang/test/AST/ast-dump-openmp-begin-declare-variant_12.c clang/test/AST/ast-dump-openmp-begin-declare-variant_namespace_1.cpp Modified: clang/include/clang/AST/ASTContext.h clang/include/clang/Sema/Sema.h clang/lib/AST/ASTContext.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c clang/test/AST/ast-dump-openmp-begin-declare-variant_4.c clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 6360f18217c7..5e9f46046411 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2537,7 +2537,7 @@ class ASTContext : public RefCountedBase { QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified = false, bool BlockReturnType = false); QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, - bool Unqualified = false); + bool Unqualified = false, bool AllowCXX = false); QualType mergeFunctionParameterTypes(QualType, QualType, bool OfBlockPointer = false, bool Unqualified = false); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 10e2d69f3d9e..99c11eac6e66 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9868,18 +9868,22 @@ class Sema final { /// The current `omp begin/end declare variant` scopes. SmallVector OMPDeclareVariantScopes; - /// The declarator \p D defines a function in the scope \p S which is nested - /// in an `omp begin/end declare variant` scope. In this method we create a - /// declaration for \p D and rename \p D according to the OpenMP context - /// selector of the surrounding scope. - FunctionDecl * - ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, - Declarator &D); + /// The declarator \p D defines a function definition in an `omp begin/end + /// declare variant` scope. In this method we rename \p D according to the + /// OpenMP context selector of the surrounding scope which makes it a + /// specialization. ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope + /// will attach that specialization to a base function of the original name. + /// + /// \return The original identifier info of \p D (= the name of the base + /// function for which \p D is a specialization). + IdentifierInfo * + ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Declarator &D); - /// Register \p FD as specialization of \p BaseFD in the current `omp - /// begin/end declare variant` scope. + /// Register \p FD as specialization of the function with name \p BaseII in + /// the current `omp begin/end declare variant` scope. \p FD was declared in + /// the scope \p S with declarator \p D (which was renamed!). void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( - FunctionDecl *FD, FunctionDecl *BaseFD); + IdentifierInfo &BaseII, FunctionDecl *FD, Scope *S, Declarator &D); public: diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 06dcb6fa0580..06513fc4b234 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -8867,8 +8867,8 @@ QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs, } QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, - bool OfBlockPointer, - bool Unqualified) { + bool OfBlockPointer, bool Unqualified, + bool AllowCXX) { const auto *lbase = lhs->castAs(); const auto *rbase = rhs->castAs(); const auto *lproto = dyn_cast(lbase); @@ -8942,7 +8942,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, FunctionType::ExtInfo einfo = lbaseInfo.withNoReturn(NoReturn); if (lproto && rproto) { // two C99 style function prototypes - assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() && + assert((AllowCXX || + (!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec())) && "C++ shouldn't be here"); // Compatible functions must have the same number of parameters if (lproto->getNumParams() != rproto->getNumParams()) @@ -9006,7 +9007,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, const FunctionProtoType *proto = lproto ? lproto : rproto; if (proto) { - assert(!proto->hasExceptionSpec() && "C++ shouldn't be here"); + assert((AllowCXX || !proto->hasExceptionSpec()) && "C++ shouldn't be here"); if (proto->isVariadic()) return {}; // Check that the types are compatible with the types that diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 494a1cd1a685..cd6cf94278dd 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -13575,25 +13575,24 @@ Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D, Scope *ParentScope = FnBodyScope->getParent(); // Check if we are in an `omp begin/end declare variant` scope. If we are, and - // we define a non-templated function definition, we will create a declaration - // instead (=BaseFD), and emit the definition with a mangled name afterwards. - // The base function declaration will have the equivalent of an `omp declare - // variant` annotation which specifies the mangled definition as a + // we define a non-templated function definition, we will emit the definition + // with a mangled name instead. Afterwards, we'll look for an existing base + // function declaration or create one. It will have the equivalent of an `omp + // declare variant` annotation which specifies the mangled definition as a // specialization function under the OpenMP context defined as part of the // `omp begin declare variant`. - FunctionDecl *BaseFD = nullptr; + IdentifierInfo *BaseII = nullptr; if (LangOpts.OpenMP && isInOpenMPDeclareVariantScope() && TemplateParameterLists.empty()) - BaseFD = ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( - ParentScope, D); + BaseII = ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(D); D.setFunctionDefinitionKind(FDK_Definition); Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists); Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody); - if (BaseFD) + if (BaseII) ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( - cast(Dcl), BaseFD); + *BaseII, cast(Dcl), ParentScope, D); return Dcl; } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index dfb809e0aaa1..52687888af2d 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5548,10 +5548,10 @@ static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) : TI(&TI), NameSuffix(TI.getMangledName()) {} -FunctionDecl * -Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, - Declarator &D) { - auto *BaseFD = cast(ActOnDeclarator(S, D)); +IdentifierInfo * +Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Declarator &D) { + IdentifierInfo *BaseII = D.getIdentifier(); + OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); std::string MangledName; MangledName += D.getIdentifier()->getName(); @@ -5560,27 +5560,87 @@ Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, IdentifierInfo &VariantII = Context.Idents.get(MangledName); VariantII.setMangledOpenMPVariantName(true); - D.SetIdentifier(&VariantII, D.getBeginLoc()); - return BaseFD; + D.SetIdentifier(&VariantII, D.getIdentifierLoc()); + return BaseII; } void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( - FunctionDecl *FD, FunctionDecl *BaseFD) { - // Do not mark function as is used to prevent its emission if this is the - // only place where it is used. - EnterExpressionEvaluationContext Unevaluated( - *this, Sema::ExpressionEvaluationContext::Unevaluated); + IdentifierInfo &BaseII, FunctionDecl *FD, Scope *S, Declarator &D) { + + // Lookup the base name in order to find an existing, compatible, base + // declaration. If none was found we create one matching the type of the + // specialization FD. + LookupResult Lookup(*this, DeclarationName(&BaseII), FD->getLocation(), + LookupOrdinaryName); + LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); + + // Scan the candidates we found for one that has a type "compatible" with the + // type of FD. + // TODO: Investigate if we can merge this with the declare variant checks, + // this will require some refactoring but should be possible. + FunctionDecl *BaseFD = nullptr; + for (auto *Candidate : Lookup) { + auto *UDecl = dyn_cast(Candidate->getUnderlyingDecl()); + if (!UDecl) + continue; + + // Don't specialize constexpr/consteval functions with + // non-constexpr/consteval functions. + if (UDecl->isConstexpr() && !FD->isConstexpr()) + continue; + if (UDecl->isConsteval() && !FD->isConsteval()) + continue; - Expr *VariantFuncRef = DeclRefExpr::Create( - Context, NestedNameSpecifierLoc(), SourceLocation(), FD, - /* RefersToEnclosingVariableOrCapture */ false, - /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); + QualType NewType = Context.mergeFunctionTypes( + FD->getType(), UDecl->getType(), /* OfBlockPointer */ false, + /* Unqualified */ false, /* AllowCXX */ true); + if (NewType.isNull()) + continue; + + // Found a base! + BaseFD = UDecl; + break; + } + + if (!BaseFD) { + // TODO: Determine if we can reuse the declarator to create a declaration + // but with the BaseII name. For some reason this did not work immediatly. + BaseFD = + cast(DeclClonePragmaWeak(FD, &BaseII, FD->getLocation())); + BaseFD->setConstexprKind(FD->getConstexprKind()); + // Copied from DeclApplyPragmaWeak: + // FIXME: "hideous" code from Sema::LazilyCreateBuiltin + // to insert Decl at TU scope, sorry. + DeclContext *SavedContext = CurContext; + CurContext = FD->getLexicalDeclContext(); + BaseFD->setDeclContext(CurContext); + BaseFD->setLexicalDeclContext(CurContext); + PushOnScopeChains(BaseFD, S); + CurContext = SavedContext; + } + + // We need a expression that references the base for the OMPDeclareVariantAttr + // below. For `omp declare variant` we parse them, for scoped declare variants + // we need to create them. + Expr *VariantFuncRef; + { + // Do not mark function as is used to prevent its emission if this is the + // only place where it is used. + EnterExpressionEvaluationContext Unevaluated( + *this, Sema::ExpressionEvaluationContext::Unevaluated); + + VariantFuncRef = DeclRefExpr::Create( + Context, NestedNameSpecifierLoc(), SourceLocation(), FD, + /* RefersToEnclosingVariableOrCapture */ false, + /* NameLoc */ FD->getLocation(), FD->getType(), + ExprValueKind::VK_RValue); + } OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( Context, VariantFuncRef, DVScope.TI); - BaseFD->addAttr(OMPDeclareVariantA); + BaseFD->addAttr(OMPDeclareVariantA); BaseFD->setImplicit(true); } diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_10.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_10.c new file mode 100644 index 000000000000..9c8d8dc31eb4 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_10.c @@ -0,0 +1,203 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s --check-prefix=CXX +// expected-no-diagnostics + +#ifdef __cplusplus +#define CONST constexpr +#else +#define CONST __attribute__((const)) +#endif + +int also_before1(void) { + return 1; +} +int also_before2(void) { + return 2; +} +int also_before3(void) { + return 3; +} +int also_before4(void) { + return 4; +} + +#pragma omp begin declare variant match(implementation = {vendor(llvm)}) +CONST int also_before1(void) { + return 0; +} +static int also_before2(void) { + return 0; +} +__attribute__((nothrow)) int also_before3(void) { + return 0; +} +static CONST __attribute__((nothrow, always_inline)) __inline__ int also_before4(void) { + return 0; +} +#pragma omp end declare variant + + +int main() { + // Should return 0. + return also_before1() + also_before2() + also_before3() + also_before4(); +} + +// Make sure: +// - we see the specialization in the AST +// - we pick the right callees + +// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:13:1> line:11:5 implicit used also_before1 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:14:5 implicit used also_before2 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 2 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_11:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_12:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_13:0x[a-z0-9]*]] 'also_before2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] line:17:5 implicit used also_before3 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 3 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_18:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_19:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_20:0x[a-z0-9]*]] 'also_before3[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_21:0x[a-z0-9]*]] line:20:5 implicit used also_before4 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_22:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_23:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_24:0x[a-z0-9]*]] 'int' 4 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_25:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_26:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_27:0x[a-z0-9]*]] 'also_before4[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_6]] line:25:11 also_before1[implementation={vendor(llvm)}] 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_28:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_29:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_30:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-ConstAttr [[ADDR_31:0x[a-z0-9]*]] +// C-NEXT: |-FunctionDecl [[ADDR_13]] line:28:12 also_before2[implementation={vendor(llvm)}] 'int ({{.*}})' static +// C-NEXT: | `-CompoundStmt [[ADDR_32:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_33:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_34:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: |-FunctionDecl [[ADDR_20]] line:31:30 also_before3[implementation={vendor(llvm)}] 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_35:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_36:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_37:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-NoThrowAttr [[ADDR_38:0x[a-z0-9]*]] +// C-NEXT: |-FunctionDecl [[ADDR_27]] line:34:69 also_before4[implementation={vendor(llvm)}] 'int ({{.*}})' static inline +// C-NEXT: | |-CompoundStmt [[ADDR_39:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_40:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_41:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | |-ConstAttr [[ADDR_42:0x[a-z0-9]*]] +// C-NEXT: | |-NoThrowAttr [[ADDR_43:0x[a-z0-9]*]] +// C-NEXT: | `-AlwaysInlineAttr [[ADDR_44:0x[a-z0-9]*]] always_inline +// C-NEXT: `-FunctionDecl [[ADDR_45:0x[a-z0-9]*]] line:40:5 main 'int ({{.*}})' +// C-NEXT: `-CompoundStmt [[ADDR_46:0x[a-z0-9]*]] +// C-NEXT: `-ReturnStmt [[ADDR_47:0x[a-z0-9]*]] +// C-NEXT: `-BinaryOperator [[ADDR_48:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: |-BinaryOperator [[ADDR_49:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | |-BinaryOperator [[ADDR_50:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | | |-PseudoObjectExpr [[ADDR_51:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | |-CallExpr [[ADDR_52:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | | `-ImplicitCastExpr [[ADDR_53:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | | `-DeclRefExpr [[ADDR_54:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before1' 'int ({{.*}})' +// C-NEXT: | | | `-CallExpr [[ADDR_55:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_56:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_5]] 'int ({{.*}})' Function [[ADDR_6]] 'also_before1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: | | `-PseudoObjectExpr [[ADDR_57:0x[a-z0-9]*]] 'int' +// C-NEXT: | | |-CallExpr [[ADDR_58:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_59:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_60:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'also_before2' 'int ({{.*}})' +// C-NEXT: | | `-CallExpr [[ADDR_61:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_62:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_12]] 'int ({{.*}})' Function [[ADDR_13]] 'also_before2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: | `-PseudoObjectExpr [[ADDR_63:0x[a-z0-9]*]] 'int' +// C-NEXT: | |-CallExpr [[ADDR_64:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_65:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_66:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14]] 'also_before3' 'int ({{.*}})' +// C-NEXT: | `-CallExpr [[ADDR_67:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_68:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_19]] 'int ({{.*}})' Function [[ADDR_20]] 'also_before3[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: `-PseudoObjectExpr [[ADDR_69:0x[a-z0-9]*]] 'int' +// C-NEXT: |-CallExpr [[ADDR_70:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_71:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_72:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_21]] 'also_before4' 'int ({{.*}})' +// C-NEXT: `-CallExpr [[ADDR_73:0x[a-z0-9]*]] 'int' +// C-NEXT: `-ImplicitCastExpr [[ADDR_74:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: `-DeclRefExpr [[ADDR_26]] 'int ({{.*}})' Function [[ADDR_27]] 'also_before4[implementation={vendor(llvm)}]' 'int ({{.*}})' + +// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:13:1> line:11:5 implicit used also_before1 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:14:5 implicit used also_before2 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 2 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_11:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_12:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_13:0x[a-z0-9]*]] 'also_before2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] line:17:5 implicit used also_before3 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 3 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_18:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_19:0x[a-z0-9]*]] 'int ({{.*}}) __attribute__((nothrow))' Function [[ADDR_20:0x[a-z0-9]*]] 'also_before3[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: |-FunctionDecl [[ADDR_21:0x[a-z0-9]*]] line:20:5 implicit used also_before4 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_22:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_23:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_24:0x[a-z0-9]*]] 'int' 4 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_25:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_26:0x[a-z0-9]*]] 'int ({{.*}}) __attribute__((nothrow))' Function [[ADDR_27:0x[a-z0-9]*]] 'also_before4[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: |-FunctionDecl [[ADDR_6]] line:25:11 constexpr also_before1[implementation={vendor(llvm)}] 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_28:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_29:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_30:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_13]] line:28:12 also_before2[implementation={vendor(llvm)}] 'int ({{.*}})' static +// CXX-NEXT: | `-CompoundStmt [[ADDR_31:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_32:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_33:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_20]] line:31:30 also_before3[implementation={vendor(llvm)}] 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: | `-CompoundStmt [[ADDR_34:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_35:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_36:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_27]] line:34:69 constexpr also_before4[implementation={vendor(llvm)}] 'int ({{.*}}) __attribute__((nothrow))' static inline +// CXX-NEXT: | |-CompoundStmt [[ADDR_37:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_38:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_39:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-AlwaysInlineAttr [[ADDR_40:0x[a-z0-9]*]] always_inline +// CXX-NEXT: `-FunctionDecl [[ADDR_41:0x[a-z0-9]*]] line:40:5 main 'int ({{.*}})' +// CXX-NEXT: `-CompoundStmt [[ADDR_42:0x[a-z0-9]*]] +// CXX-NEXT: `-ReturnStmt [[ADDR_43:0x[a-z0-9]*]] +// CXX-NEXT: `-BinaryOperator [[ADDR_44:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: |-BinaryOperator [[ADDR_45:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | |-BinaryOperator [[ADDR_46:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | | |-PseudoObjectExpr [[ADDR_47:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | |-CallExpr [[ADDR_48:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | | `-ImplicitCastExpr [[ADDR_49:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_50:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before1' 'int ({{.*}})' +// CXX-NEXT: | | | `-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_5]] 'int ({{.*}})' Function [[ADDR_6]] 'also_before1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: | | `-PseudoObjectExpr [[ADDR_53:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | |-CallExpr [[ADDR_54:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_55:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_56:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_7]] 'also_before2' 'int ({{.*}})' +// CXX-NEXT: | | `-CallExpr [[ADDR_57:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_58:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_12]] 'int ({{.*}})' Function [[ADDR_13]] 'also_before2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: | `-PseudoObjectExpr [[ADDR_59:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | |-CallExpr [[ADDR_60:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_61:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_62:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'also_before3' 'int ({{.*}})' +// CXX-NEXT: | `-CallExpr [[ADDR_63:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_64:0x[a-z0-9]*]] 'int (*)({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_19]] 'int ({{.*}}) __attribute__((nothrow))' Function [[ADDR_20]] 'also_before3[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: `-PseudoObjectExpr [[ADDR_65:0x[a-z0-9]*]] 'int' +// CXX-NEXT: |-CallExpr [[ADDR_66:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_67:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_68:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_21]] 'also_before4' 'int ({{.*}})' +// CXX-NEXT: `-CallExpr [[ADDR_69:0x[a-z0-9]*]] 'int' +// CXX-NEXT: `-ImplicitCastExpr [[ADDR_70:0x[a-z0-9]*]] 'int (*)({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: `-DeclRefExpr [[ADDR_26]] 'int ({{.*}}) __attribute__((nothrow))' Function [[ADDR_27]] 'also_before4[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_11.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_11.c new file mode 100644 index 000000000000..cdc1d78a8fd0 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_11.c @@ -0,0 +1,228 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify=c_mode -ast-dump %s | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify=cxx_mode -ast-dump %s -x c++| FileCheck %s --check-prefix=CXX + +// c_mode-no-diagnostics + +#ifdef __cplusplus +#define CONST constexpr +#else +#define CONST __attribute__((const)) +#endif + +#pragma omp begin declare variant match(implementation = {vendor(llvm)}) +CONST int also_after1(void) { // cxx_mode-note {{previous declaration is here}} + return 0; +} +static int also_after2(void) { + return 0; +} +__attribute__((nothrow)) int also_after3(void) { + return 0; +} +static CONST __attribute__((nothrow, always_inline)) __inline__ int also_after4(void) { // cxx_mode-note {{previous declaration is here}} + return 0; +} +#pragma omp end declare variant + +int also_after1(void) { // cxx_mode-error {{non-constexpr declaration of 'also_after1' follows constexpr declaration}} + return 1; +} +int also_after2(void) { + return 2; +} +int also_after3(void) { + return 3; +} +int also_after4(void) { // cxx_mode-error {{non-constexpr declaration of 'also_after4' follows constexpr declaration}} + return 4; +} + + +int main() { + // Should return 0. + return also_after1() + also_after2() + also_after3() + also_after4(); +} + +// Make sure: +// - we see the specialization in the AST +// - we pick the right callees + +// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:15:1> line:13:11 also_after1[implementation={vendor(llvm)}] 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-ConstAttr [[ADDR_4:0x[a-z0-9]*]] +// C-NEXT: |-FunctionDecl [[ADDR_5:0x[a-z0-9]*]] col:11 implicit used also_after1 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_6:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_7:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_after1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_8:0x[a-z0-9]*]] line:16:12 also_after2[implementation={vendor(llvm)}] 'int ({{.*}})' static +// C-NEXT: | `-CompoundStmt [[ADDR_9:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_10:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_11:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: |-FunctionDecl [[ADDR_12:0x[a-z0-9]*]] col:12 implicit used also_after2 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_13:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_14:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_8]] 'also_after2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_15:0x[a-z0-9]*]] line:19:30 also_after3[implementation={vendor(llvm)}] 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_16:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_17:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_18:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-NoThrowAttr [[ADDR_19:0x[a-z0-9]*]] +// C-NEXT: |-FunctionDecl [[ADDR_20:0x[a-z0-9]*]] col:30 implicit used also_after3 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_21:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_22:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_15]] 'also_after3[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:69 also_after4[implementation={vendor(llvm)}] 'int ({{.*}})' static inline +// C-NEXT: | |-CompoundStmt [[ADDR_24:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_25:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_26:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | |-ConstAttr [[ADDR_27:0x[a-z0-9]*]] +// C-NEXT: | |-NoThrowAttr [[ADDR_28:0x[a-z0-9]*]] +// C-NEXT: | `-AlwaysInlineAttr [[ADDR_29:0x[a-z0-9]*]] always_inline +// C-NEXT: |-FunctionDecl [[ADDR_30:0x[a-z0-9]*]] col:69 implicit used also_after4 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_31:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_23]] 'also_after4[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_33:0x[a-z0-9]*]] prev [[ADDR_5]] line:27:5 used also_after1 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_34:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_35:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_36:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_37:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_7]] 'int ({{.*}})' Function [[ADDR_0]] 'also_after1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_38:0x[a-z0-9]*]] prev [[ADDR_12]] line:30:5 used also_after2 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_39:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_40:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_41:0x[a-z0-9]*]] 'int' 2 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_42:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_14]] 'int ({{.*}})' Function [[ADDR_8]] 'also_after2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_43:0x[a-z0-9]*]] prev [[ADDR_20]] line:33:5 used also_after3 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_44:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_45:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_46:0x[a-z0-9]*]] 'int' 3 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_47:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_22]] 'int ({{.*}})' Function [[ADDR_15]] 'also_after3[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_48:0x[a-z0-9]*]] prev [[ADDR_30]] line:36:5 used also_after4 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_49:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_50:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_51:0x[a-z0-9]*]] 'int' 4 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_52:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_32]] 'int ({{.*}})' Function [[ADDR_23]] 'also_after4[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: `-FunctionDecl [[ADDR_53:0x[a-z0-9]*]] line:41:5 main 'int ({{.*}})' +// C-NEXT: `-CompoundStmt [[ADDR_54:0x[a-z0-9]*]] +// C-NEXT: `-ReturnStmt [[ADDR_55:0x[a-z0-9]*]] +// C-NEXT: `-BinaryOperator [[ADDR_56:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: |-BinaryOperator [[ADDR_57:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | |-BinaryOperator [[ADDR_58:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | | |-PseudoObjectExpr [[ADDR_59:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | |-CallExpr [[ADDR_60:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | | `-ImplicitCastExpr [[ADDR_61:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | | `-DeclRefExpr [[ADDR_62:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_33]] 'also_after1' 'int ({{.*}})' +// C-NEXT: | | | `-CallExpr [[ADDR_63:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_64:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_7]] 'int ({{.*}})' Function [[ADDR_0]] 'also_after1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: | | `-PseudoObjectExpr [[ADDR_65:0x[a-z0-9]*]] 'int' +// C-NEXT: | | |-CallExpr [[ADDR_66:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_67:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_68:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_38]] 'also_after2' 'int ({{.*}})' +// C-NEXT: | | `-CallExpr [[ADDR_69:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_70:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_14]] 'int ({{.*}})' Function [[ADDR_8]] 'also_after2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: | `-PseudoObjectExpr [[ADDR_71:0x[a-z0-9]*]] 'int' +// C-NEXT: | |-CallExpr [[ADDR_72:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_73:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_74:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_43]] 'also_after3' 'int ({{.*}})' +// C-NEXT: | `-CallExpr [[ADDR_75:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_76:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_22]] 'int ({{.*}})' Function [[ADDR_15]] 'also_after3[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: `-PseudoObjectExpr [[ADDR_77:0x[a-z0-9]*]] 'int' +// C-NEXT: |-CallExpr [[ADDR_78:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_79:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_80:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_48]] 'also_after4' 'int ({{.*}})' +// C-NEXT: `-CallExpr [[ADDR_81:0x[a-z0-9]*]] 'int' +// C-NEXT: `-ImplicitCastExpr [[ADDR_82:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: `-DeclRefExpr [[ADDR_32]] 'int ({{.*}})' Function [[ADDR_23]] 'also_after4[implementation={vendor(llvm)}]' 'int ({{.*}})' + +// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:15:1> line:13:11 constexpr also_after1[implementation={vendor(llvm)}] 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:11 implicit used constexpr also_after1 'int ({{.*}})' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_after1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:16:12 also_after2[implementation={vendor(llvm)}] 'int ({{.*}})' static +// CXX-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] col:12 implicit used also_after2 'int ({{.*}})' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] line:19:30 also_after3[implementation={vendor(llvm)}] 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] col:30 implicit used also_after3 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_19:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_20:0x[a-z0-9]*]] 'int ({{.*}}) __attribute__((nothrow))' Function [[ADDR_14]] 'also_after3[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: |-FunctionDecl [[ADDR_21:0x[a-z0-9]*]] line:22:69 constexpr also_after4[implementation={vendor(llvm)}] 'int ({{.*}}) __attribute__((nothrow))' static inline +// CXX-NEXT: | |-CompoundStmt [[ADDR_22:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_23:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_24:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-AlwaysInlineAttr [[ADDR_25:0x[a-z0-9]*]] always_inline +// CXX-NEXT: |-FunctionDecl [[ADDR_26:0x[a-z0-9]*]] col:69 implicit used constexpr also_after4 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_27:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_28:0x[a-z0-9]*]] 'int ({{.*}}) __attribute__((nothrow))' Function [[ADDR_21]] 'also_after4[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: |-FunctionDecl [[ADDR_29:0x[a-z0-9]*]] line:27:5 invalid also_after1 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_30:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_31:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_32:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_33:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_0]] 'also_after1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_34:0x[a-z0-9]*]] prev [[ADDR_11]] line:30:5 used also_after2 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_35:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_36:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_37:0x[a-z0-9]*]] 'int' 2 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_38:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_39:0x[a-z0-9]*]] prev [[ADDR_18]] line:33:5 used also_after3 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_40:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_41:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_42:0x[a-z0-9]*]] 'int' 3 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_43:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_20]] 'int ({{.*}}) __attribute__((nothrow))' Function [[ADDR_14]] 'also_after3[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: |-FunctionDecl [[ADDR_44:0x[a-z0-9]*]] line:36:5 invalid also_after4 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_45:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_46:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_47:0x[a-z0-9]*]] 'int' 4 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_48:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_28]] 'int ({{.*}}) __attribute__((nothrow))' Function [[ADDR_21]] 'also_after4[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: `-FunctionDecl [[ADDR_49:0x[a-z0-9]*]] line:41:5 main 'int ({{.*}})' +// CXX-NEXT: `-CompoundStmt [[ADDR_50:0x[a-z0-9]*]] +// CXX-NEXT: `-ReturnStmt [[ADDR_51:0x[a-z0-9]*]] +// CXX-NEXT: `-BinaryOperator [[ADDR_52:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: |-BinaryOperator [[ADDR_53:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | |-BinaryOperator [[ADDR_54:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | | |-PseudoObjectExpr [[ADDR_55:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | |-CallExpr [[ADDR_56:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | | `-ImplicitCastExpr [[ADDR_57:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_58:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_4]] 'also_after1' 'int ({{.*}})' +// CXX-NEXT: | | | `-CallExpr [[ADDR_59:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_60:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_0]] 'also_after1[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: | | `-PseudoObjectExpr [[ADDR_61:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | |-CallExpr [[ADDR_62:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_63:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_64:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_34]] 'also_after2' 'int ({{.*}})' +// CXX-NEXT: | | `-CallExpr [[ADDR_65:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_66:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after2[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: | `-PseudoObjectExpr [[ADDR_67:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | |-CallExpr [[ADDR_68:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_69:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_70:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_39]] 'also_after3' 'int ({{.*}})' +// CXX-NEXT: | `-CallExpr [[ADDR_71:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_72:0x[a-z0-9]*]] 'int (*)({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_20]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'also_after3[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: `-PseudoObjectExpr [[ADDR_73:0x[a-z0-9]*]] 'int' +// CXX-NEXT: |-CallExpr [[ADDR_74:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_75:0x[a-z0-9]*]] 'int (*)({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_76:0x[a-z0-9]*]] 'int ({{.*}}) __attribute__((nothrow))' {{.*}}Function [[ADDR_26]] 'also_after4' 'int ({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: `-CallExpr [[ADDR_77:0x[a-z0-9]*]] 'int' +// CXX-NEXT: `-ImplicitCastExpr [[ADDR_78:0x[a-z0-9]*]] 'int (*)({{.*}}) __attribute__((nothrow))' +// CXX-NEXT: `-DeclRefExpr [[ADDR_28]] 'int ({{.*}}) __attribute__((nothrow))' Function [[ADDR_21]] 'also_after4[implementation={vendor(llvm)}]' 'int ({{.*}}) __attribute__((nothrow))' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_12.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_12.c new file mode 100644 index 000000000000..e59091431ba9 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_12.c @@ -0,0 +1,263 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s --check-prefix=CXX +// expected-no-diagnostics + +#ifdef __cplusplus +#define OVERLOADABLE +#else +#define OVERLOADABLE __attribute__((overloadable)) +#endif + +OVERLOADABLE +int also_before(void) { + return 1; +} +OVERLOADABLE +int also_before(int i) { + return 2; +} +OVERLOADABLE +int also_before(float f) { + return 0; +} +OVERLOADABLE +int also_before(double d) { + return 3; +} +OVERLOADABLE +int also_before(long l) { + return 4; +} + +#pragma omp begin declare variant match(implementation = {vendor(llvm)}) +OVERLOADABLE +int also_before(void) { + return 0; +} +OVERLOADABLE +int also_before(int i) { + return 0; +} +// No float! +OVERLOADABLE +int also_before(double d) { + return 0; +} +OVERLOADABLE +int also_before(long l) { + return 0; +} +#pragma omp end declare variant + + +int main() { + // Should return 0. + return also_before() + also_before(1) + also_before(2.0f) + also_before(3.0) + also_before(4L); +} + +// Make sure: +// - we see the specialization in the AST +// - we pick the right callees + +// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:14:1> line:12:5 implicit used also_before 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: | |-OverloadableAttr [[ADDR_4:0x[a-z0-9]*]] +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_8:0x[a-z0-9]*]] line:16:5 implicit used also_before 'int (int)' +// C-NEXT: | |-ParmVarDecl [[ADDR_9:0x[a-z0-9]*]] col:21 i 'int' +// C-NEXT: | |-CompoundStmt [[ADDR_10:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_11:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_12:0x[a-z0-9]*]] 'int' 2 +// C-NEXT: | |-OverloadableAttr [[ADDR_13:0x[a-z0-9]*]] +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_14:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_15:0x[a-z0-9]*]] 'int (int)' Function [[ADDR_16:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int (int)' +// C-NEXT: |-FunctionDecl [[ADDR_17:0x[a-z0-9]*]] line:20:5 used also_before 'int (float)' +// C-NEXT: | |-ParmVarDecl [[ADDR_18:0x[a-z0-9]*]] col:23 f 'float' +// C-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OverloadableAttr [[ADDR_22:0x[a-z0-9]*]] +// C-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:24:5 implicit used also_before 'int (double)' +// C-NEXT: | |-ParmVarDecl [[ADDR_24:0x[a-z0-9]*]] col:24 d 'double' +// C-NEXT: | |-CompoundStmt [[ADDR_25:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_26:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_27:0x[a-z0-9]*]] 'int' 3 +// C-NEXT: | |-OverloadableAttr [[ADDR_28:0x[a-z0-9]*]] +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_29:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_30:0x[a-z0-9]*]] 'int (double)' Function [[ADDR_31:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int (double)' +// C-NEXT: |-FunctionDecl [[ADDR_32:0x[a-z0-9]*]] line:28:5 implicit used also_before 'int (long)' +// C-NEXT: | |-ParmVarDecl [[ADDR_33:0x[a-z0-9]*]] col:22 l 'long' +// C-NEXT: | |-CompoundStmt [[ADDR_34:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_35:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_36:0x[a-z0-9]*]] 'int' 4 +// C-NEXT: | |-OverloadableAttr [[ADDR_37:0x[a-z0-9]*]] +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_38:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int (long)' Function [[ADDR_40:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int (long)' +// C-NEXT: |-FunctionDecl [[ADDR_7]] line:34:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_41:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_42:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_43:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OverloadableAttr [[ADDR_44:0x[a-z0-9]*]] +// C-NEXT: |-FunctionDecl [[ADDR_16]] line:38:5 also_before[implementation={vendor(llvm)}] 'int (int)' +// C-NEXT: | |-ParmVarDecl [[ADDR_45:0x[a-z0-9]*]] col:21 i 'int' +// C-NEXT: | |-CompoundStmt [[ADDR_46:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_47:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_48:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OverloadableAttr [[ADDR_49:0x[a-z0-9]*]] +// C-NEXT: |-FunctionDecl [[ADDR_31]] line:43:5 also_before[implementation={vendor(llvm)}] 'int (double)' +// C-NEXT: | |-ParmVarDecl [[ADDR_50:0x[a-z0-9]*]] col:24 d 'double' +// C-NEXT: | |-CompoundStmt [[ADDR_51:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_52:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_53:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OverloadableAttr [[ADDR_54:0x[a-z0-9]*]] +// C-NEXT: |-FunctionDecl [[ADDR_40]] line:47:5 also_before[implementation={vendor(llvm)}] 'int (long)' +// C-NEXT: | |-ParmVarDecl [[ADDR_55:0x[a-z0-9]*]] col:22 l 'long' +// C-NEXT: | |-CompoundStmt [[ADDR_56:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_57:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_58:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OverloadableAttr [[ADDR_59:0x[a-z0-9]*]] +// C-NEXT: `-FunctionDecl [[ADDR_60:0x[a-z0-9]*]] line:53:5 main 'int ({{.*}})' +// C-NEXT: `-CompoundStmt [[ADDR_61:0x[a-z0-9]*]] +// C-NEXT: `-ReturnStmt [[ADDR_62:0x[a-z0-9]*]] +// C-NEXT: `-BinaryOperator [[ADDR_63:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: |-BinaryOperator [[ADDR_64:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | |-BinaryOperator [[ADDR_65:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | | |-BinaryOperator [[ADDR_66:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | | | |-PseudoObjectExpr [[ADDR_67:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | | |-CallExpr [[ADDR_68:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | | | `-ImplicitCastExpr [[ADDR_69:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | | | `-DeclRefExpr [[ADDR_70:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// C-NEXT: | | | | `-CallExpr [[ADDR_71:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | | `-ImplicitCastExpr [[ADDR_72:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: | | | `-PseudoObjectExpr [[ADDR_73:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | |-CallExpr [[ADDR_74:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | | |-ImplicitCastExpr [[ADDR_75:0x[a-z0-9]*]] 'int (*)(int)' +// C-NEXT: | | | | | `-DeclRefExpr [[ADDR_76:0x[a-z0-9]*]] 'int (int)' {{.*}}Function [[ADDR_8]] 'also_before' 'int (int)' +// C-NEXT: | | | | `-IntegerLiteral [[ADDR_77:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: | | | `-CallExpr [[ADDR_78:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | |-ImplicitCastExpr [[ADDR_79:0x[a-z0-9]*]] 'int (*)(int)' +// C-NEXT: | | | | `-DeclRefExpr [[ADDR_15]] 'int (int)' Function [[ADDR_16]] 'also_before[implementation={vendor(llvm)}]' 'int (int)' +// C-NEXT: | | | `-IntegerLiteral [[ADDR_77]] 'int' 1 +// C-NEXT: | | `-CallExpr [[ADDR_80:0x[a-z0-9]*]] 'int' +// C-NEXT: | | |-ImplicitCastExpr [[ADDR_81:0x[a-z0-9]*]] 'int (*)(float)' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_82:0x[a-z0-9]*]] 'int (float)' {{.*}}Function [[ADDR_17]] 'also_before' 'int (float)' +// C-NEXT: | | `-FloatingLiteral [[ADDR_83:0x[a-z0-9]*]] 'float' 2.000000e+00 +// C-NEXT: | `-PseudoObjectExpr [[ADDR_84:0x[a-z0-9]*]] 'int' +// C-NEXT: | |-CallExpr [[ADDR_85:0x[a-z0-9]*]] 'int' +// C-NEXT: | | |-ImplicitCastExpr [[ADDR_86:0x[a-z0-9]*]] 'int (*)(double)' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_87:0x[a-z0-9]*]] 'int (double)' {{.*}}Function [[ADDR_23]] 'also_before' 'int (double)' +// C-NEXT: | | `-FloatingLiteral [[ADDR_88:0x[a-z0-9]*]] 'double' 3.000000e+00 +// C-NEXT: | `-CallExpr [[ADDR_89:0x[a-z0-9]*]] 'int' +// C-NEXT: | |-ImplicitCastExpr [[ADDR_90:0x[a-z0-9]*]] 'int (*)(double)' +// C-NEXT: | | `-DeclRefExpr [[ADDR_30]] 'int (double)' Function [[ADDR_31]] 'also_before[implementation={vendor(llvm)}]' 'int (double)' +// C-NEXT: | `-FloatingLiteral [[ADDR_88]] 'double' 3.000000e+00 +// C-NEXT: `-PseudoObjectExpr [[ADDR_91:0x[a-z0-9]*]] 'int' +// C-NEXT: |-CallExpr [[ADDR_92:0x[a-z0-9]*]] 'int' +// C-NEXT: | |-ImplicitCastExpr [[ADDR_93:0x[a-z0-9]*]] 'int (*)(long)' +// C-NEXT: | | `-DeclRefExpr [[ADDR_94:0x[a-z0-9]*]] 'int (long)' {{.*}}Function [[ADDR_32]] 'also_before' 'int (long)' +// C-NEXT: | `-IntegerLiteral [[ADDR_95:0x[a-z0-9]*]] 'long' 4 +// C-NEXT: `-CallExpr [[ADDR_96:0x[a-z0-9]*]] 'int' +// C-NEXT: |-ImplicitCastExpr [[ADDR_97:0x[a-z0-9]*]] 'int (*)(long)' +// C-NEXT: | `-DeclRefExpr [[ADDR_39]] 'int (long)' Function [[ADDR_40]] 'also_before[implementation={vendor(llvm)}]' 'int (long)' +// C-NEXT: `-IntegerLiteral [[ADDR_95]] 'long' 4 + +// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:14:1> line:12:5 implicit used also_before 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:16:5 implicit used also_before 'int (int)' +// CXX-NEXT: | |-ParmVarDecl [[ADDR_8:0x[a-z0-9]*]] col:21 i 'int' +// CXX-NEXT: | |-CompoundStmt [[ADDR_9:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_10:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_11:0x[a-z0-9]*]] 'int' 2 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int (int)' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int (int)' +// CXX-NEXT: |-FunctionDecl [[ADDR_15:0x[a-z0-9]*]] line:20:5 used also_before 'int (float)' +// CXX-NEXT: | |-ParmVarDecl [[ADDR_16:0x[a-z0-9]*]] col:23 f 'float' +// CXX-NEXT: | `-CompoundStmt [[ADDR_17:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_18:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_19:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_20:0x[a-z0-9]*]] line:24:5 implicit used also_before 'int (double)' +// CXX-NEXT: | |-ParmVarDecl [[ADDR_21:0x[a-z0-9]*]] col:24 d 'double' +// CXX-NEXT: | |-CompoundStmt [[ADDR_22:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_23:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_24:0x[a-z0-9]*]] 'int' 3 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_25:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_26:0x[a-z0-9]*]] 'int (double)' Function [[ADDR_27:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int (double)' +// CXX-NEXT: |-FunctionDecl [[ADDR_28:0x[a-z0-9]*]] line:28:5 implicit used also_before 'int (long)' +// CXX-NEXT: | |-ParmVarDecl [[ADDR_29:0x[a-z0-9]*]] col:22 l 'long' +// CXX-NEXT: | |-CompoundStmt [[ADDR_30:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_31:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_32:0x[a-z0-9]*]] 'int' 4 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_33:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_34:0x[a-z0-9]*]] 'int (long)' Function [[ADDR_35:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int (long)' +// CXX-NEXT: |-FunctionDecl [[ADDR_6]] line:34:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_36:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_37:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_38:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_14]] line:38:5 also_before[implementation={vendor(llvm)}] 'int (int)' +// CXX-NEXT: | |-ParmVarDecl [[ADDR_39:0x[a-z0-9]*]] col:21 i 'int' +// CXX-NEXT: | `-CompoundStmt [[ADDR_40:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_41:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_42:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_27]] line:43:5 also_before[implementation={vendor(llvm)}] 'int (double)' +// CXX-NEXT: | |-ParmVarDecl [[ADDR_43:0x[a-z0-9]*]] col:24 d 'double' +// CXX-NEXT: | `-CompoundStmt [[ADDR_44:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_45:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_46:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_35]] line:47:5 also_before[implementation={vendor(llvm)}] 'int (long)' +// CXX-NEXT: | |-ParmVarDecl [[ADDR_47:0x[a-z0-9]*]] col:22 l 'long' +// CXX-NEXT: | `-CompoundStmt [[ADDR_48:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_49:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_50:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: `-FunctionDecl [[ADDR_51:0x[a-z0-9]*]] line:53:5 main 'int ({{.*}})' +// CXX-NEXT: `-CompoundStmt [[ADDR_52:0x[a-z0-9]*]] +// CXX-NEXT: `-ReturnStmt [[ADDR_53:0x[a-z0-9]*]] +// CXX-NEXT: `-BinaryOperator [[ADDR_54:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: |-BinaryOperator [[ADDR_55:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | |-BinaryOperator [[ADDR_56:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | | |-BinaryOperator [[ADDR_57:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | | | |-PseudoObjectExpr [[ADDR_58:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | | |-CallExpr [[ADDR_59:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | | | `-ImplicitCastExpr [[ADDR_60:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | | | `-DeclRefExpr [[ADDR_61:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// CXX-NEXT: | | | | `-CallExpr [[ADDR_62:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | | `-ImplicitCastExpr [[ADDR_63:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_5]] 'int ({{.*}})' Function [[ADDR_6]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: | | | `-PseudoObjectExpr [[ADDR_64:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | |-CallExpr [[ADDR_65:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | | |-ImplicitCastExpr [[ADDR_66:0x[a-z0-9]*]] 'int (*)(int)' +// CXX-NEXT: | | | | | `-DeclRefExpr [[ADDR_67:0x[a-z0-9]*]] 'int (int)' {{.*}}Function [[ADDR_7]] 'also_before' 'int (int)' +// CXX-NEXT: | | | | `-IntegerLiteral [[ADDR_68:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: | | | `-CallExpr [[ADDR_69:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | |-ImplicitCastExpr [[ADDR_70:0x[a-z0-9]*]] 'int (*)(int)' +// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_13]] 'int (int)' Function [[ADDR_14]] 'also_before[implementation={vendor(llvm)}]' 'int (int)' +// CXX-NEXT: | | | `-IntegerLiteral [[ADDR_68]] 'int' 1 +// CXX-NEXT: | | `-CallExpr [[ADDR_71:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_72:0x[a-z0-9]*]] 'int (*)(float)' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_73:0x[a-z0-9]*]] 'int (float)' {{.*}}Function [[ADDR_15]] 'also_before' 'int (float)' +// CXX-NEXT: | | `-FloatingLiteral [[ADDR_74:0x[a-z0-9]*]] 'float' 2.000000e+00 +// CXX-NEXT: | `-PseudoObjectExpr [[ADDR_75:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | |-CallExpr [[ADDR_76:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_77:0x[a-z0-9]*]] 'int (*)(double)' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_78:0x[a-z0-9]*]] 'int (double)' {{.*}}Function [[ADDR_20]] 'also_before' 'int (double)' +// CXX-NEXT: | | `-FloatingLiteral [[ADDR_79:0x[a-z0-9]*]] 'double' 3.000000e+00 +// CXX-NEXT: | `-CallExpr [[ADDR_80:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | |-ImplicitCastExpr [[ADDR_81:0x[a-z0-9]*]] 'int (*)(double)' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_26]] 'int (double)' Function [[ADDR_27]] 'also_before[implementation={vendor(llvm)}]' 'int (double)' +// CXX-NEXT: | `-FloatingLiteral [[ADDR_79]] 'double' 3.000000e+00 +// CXX-NEXT: `-PseudoObjectExpr [[ADDR_82:0x[a-z0-9]*]] 'int' +// CXX-NEXT: |-CallExpr [[ADDR_83:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | |-ImplicitCastExpr [[ADDR_84:0x[a-z0-9]*]] 'int (*)(long)' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_85:0x[a-z0-9]*]] 'int (long)' {{.*}}Function [[ADDR_28]] 'also_before' 'int (long)' +// CXX-NEXT: | `-IntegerLiteral [[ADDR_86:0x[a-z0-9]*]] 'long' 4 +// CXX-NEXT: `-CallExpr [[ADDR_87:0x[a-z0-9]*]] 'int' +// CXX-NEXT: |-ImplicitCastExpr [[ADDR_88:0x[a-z0-9]*]] 'int (*)(long)' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_34]] 'int (long)' Function [[ADDR_35]] 'also_before[implementation={vendor(llvm)}]' 'int (long)' +// CXX-NEXT: `-IntegerLiteral [[ADDR_86]] 'long' 4 diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c index fda973b1e6c4..497fc3da1efe 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c @@ -33,50 +33,47 @@ int test() { // - we do see the ast nodes for the llvm vendor // - we pick the right callees -// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:21> col:5 implicit used also_before 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_1:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_2:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_3:0x[a-z0-9]*]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_3]] line:6:1 also_before[device={kind(cpu)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_4:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_5:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_6:0x[a-z0-9]*]] 'int' 0 -// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_8:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_10]] line:12:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:8:1> line:6:5 also_before[device={kind(cpu)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_before 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_7:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_8:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_9:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_10:0x[a-z0-9]*]] line:12:5 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' // CHECK-NEXT: | `-CompoundStmt [[ADDR_11:0x[a-z0-9]*]] // CHECK-NEXT: | `-ReturnStmt [[ADDR_12:0x[a-z0-9]*]] // CHECK-NEXT: | `-IntegerLiteral [[ADDR_13:0x[a-z0-9]*]] 'int' 0 -// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' -// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_15:0x[a-z0-9]*]] <> Inherited Implicit device={kind(cpu)} -// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_16:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_18]] line:17:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 1 -// CHECK-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] prev [[ADDR_7]] line:22:5 used also_after 'int ({{.*}})' -// CHECK-NEXT: | |-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] -// CHECK-NEXT: | | `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] -// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_25:0x[a-z0-9]*]] 'int' 2 -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_26:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(100): llvm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: `-FunctionDecl [[ADDR_27:0x[a-z0-9]*]] line:26:5 test 'int ({{.*}})' -// CHECK-NEXT: `-CompoundStmt [[ADDR_28:0x[a-z0-9]*]] -// CHECK-NEXT: `-ReturnStmt [[ADDR_29:0x[a-z0-9]*]] -// CHECK-NEXT: `-BinaryOperator [[ADDR_30:0x[a-z0-9]*]] 'int' '+' -// CHECK-NEXT: |-PseudoObjectExpr [[ADDR_31:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | |-CallExpr [[ADDR_32:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_33:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_34:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_22]] 'also_after' 'int ({{.*}})' -// CHECK-NEXT: | `-CallExpr [[ADDR_35:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_36:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_37:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: |-CallExpr [[ADDR_38:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'also_before' 'int ({{.*}})' -// CHECK-NEXT: `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_15:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_16:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_9]] line:17:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_17:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_18:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_19:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_20:0x[a-z0-9]*]] prev [[ADDR_14]] line:22:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_21:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_22:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_23:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_24:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_16]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_25:0x[a-z0-9]*]] line:26:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_26:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_27:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_28:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-PseudoObjectExpr [[ADDR_29:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_30:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_31:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_20]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_33:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_34:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_16]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_4]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_39:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_40:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c index efedd2f9bb74..68ebf896a44e 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c @@ -33,50 +33,47 @@ int test() { // - we do see the ast nodes for the llvm vendor // - we pick the right callees -// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:21> col:5 implicit used also_before 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_1:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_2:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_3:0x[a-z0-9]*]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_3]] line:6:1 also_before[device={kind(cpu)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_4:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_5:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_6:0x[a-z0-9]*]] 'int' 1 -// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_8:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_10]] line:12:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:8:1> line:6:5 also_before[device={kind(cpu)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_before 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_7:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_8:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_9:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_10:0x[a-z0-9]*]] line:12:5 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' // CHECK-NEXT: | `-CompoundStmt [[ADDR_11:0x[a-z0-9]*]] // CHECK-NEXT: | `-ReturnStmt [[ADDR_12:0x[a-z0-9]*]] // CHECK-NEXT: | `-IntegerLiteral [[ADDR_13:0x[a-z0-9]*]] 'int' 0 -// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' -// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_15:0x[a-z0-9]*]] <> Inherited Implicit device={kind(cpu)} -// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_16:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_18]] line:17:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 -// CHECK-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] prev [[ADDR_7]] line:22:5 used also_after 'int ({{.*}})' -// CHECK-NEXT: | |-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] -// CHECK-NEXT: | | `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] -// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_25:0x[a-z0-9]*]] 'int' 2 -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_26:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(0): llvm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: `-FunctionDecl [[ADDR_27:0x[a-z0-9]*]] line:26:5 test 'int ({{.*}})' -// CHECK-NEXT: `-CompoundStmt [[ADDR_28:0x[a-z0-9]*]] -// CHECK-NEXT: `-ReturnStmt [[ADDR_29:0x[a-z0-9]*]] -// CHECK-NEXT: `-BinaryOperator [[ADDR_30:0x[a-z0-9]*]] 'int' '+' -// CHECK-NEXT: |-PseudoObjectExpr [[ADDR_31:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | |-CallExpr [[ADDR_32:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_33:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_34:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_22]] 'also_after' 'int ({{.*}})' -// CHECK-NEXT: | `-CallExpr [[ADDR_35:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_36:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_37:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: |-CallExpr [[ADDR_38:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'also_before' 'int ({{.*}})' -// CHECK-NEXT: `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: `-DeclRefExpr [[ADDR_17]] 'int ({{.*}})' Function [[ADDR_18]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_15:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_16:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_9]] line:17:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_17:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_18:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_19:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_20:0x[a-z0-9]*]] prev [[ADDR_14]] line:22:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_21:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_22:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_23:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_24:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_16]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_25:0x[a-z0-9]*]] line:26:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_26:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_27:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_28:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-PseudoObjectExpr [[ADDR_29:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_30:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_31:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_20]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_33:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_34:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_16]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_4]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_39:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_40:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_8]] 'int ({{.*}})' Function [[ADDR_9]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_4.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_4.c index b35433478e49..01e97c2e3615 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_4.c +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_4.c @@ -21,13 +21,13 @@ int test() { // - we do see the ast nodes for the cpu kind // - we pick the right callees -// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:21> col:5 implicit used also_before 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_1:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_2:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_3:0x[a-z0-9]*]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_3]] line:6:1 also_before[device={kind(cpu)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_4:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_5:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_6:0x[a-z0-9]*]] 'int' 0 +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:8:1> line:6:5 also_before[device={kind(cpu)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_before 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' // CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:11:5 used also_after 'int ({{.*}})' // CHECK-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] // CHECK-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] @@ -42,7 +42,7 @@ int test() { // CHECK-NEXT: `-PseudoObjectExpr [[ADDR_18:0x[a-z0-9]*]] 'int' // CHECK-NEXT: |-CallExpr [[ADDR_19:0x[a-z0-9]*]] 'int' // CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_20:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_21:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' -// CHECK-NEXT: `-CallExpr [[ADDR_22:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_23:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_21:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_4]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_22:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_23:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c index b2a1cb0b3c86..cb01511d015c 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c @@ -31,128 +31,126 @@ int main() { // - we see the specialization in the AST // - we pick the right callees -// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' -// C-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] -// C-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] -// C-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 -// C-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// C-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 implicit used also_before 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:10:5 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' // C-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] // C-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] // C-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 0 -// C-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' // C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// C-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' -// C-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] -// C-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] -// C-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 0 -// C-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' -// C-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// C-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// C-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 2 -// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} -// C-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: `-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 main 'int ({{.*}})' -// C-NEXT: `-CompoundStmt [[ADDR_24:0x[a-z0-9]*]] -// C-NEXT: `-ReturnStmt [[ADDR_25:0x[a-z0-9]*]] -// C-NEXT: `-BinaryOperator [[ADDR_26:0x[a-z0-9]*]] 'int' '+' -// C-NEXT: |-BinaryOperator [[ADDR_27:0x[a-z0-9]*]] 'int' '+' -// C-NEXT: | |-BinaryOperator [[ADDR_28:0x[a-z0-9]*]] 'int' '+' -// C-NEXT: | | |-PseudoObjectExpr [[ADDR_29:0x[a-z0-9]*]] 'int' -// C-NEXT: | | | |-CallExpr [[ADDR_30:0x[a-z0-9]*]] 'int' -// C-NEXT: | | | | `-ImplicitCastExpr [[ADDR_31:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | | | | `-ParenExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' -// C-NEXT: | | | | `-DeclRefExpr [[ADDR_33:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// C-NEXT: | | | `-CallExpr [[ADDR_34:0x[a-z0-9]*]] 'int' -// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_35:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | | | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: | | `-PseudoObjectExpr [[ADDR_36:0x[a-z0-9]*]] 'int' -// C-NEXT: | | |-CallExpr [[ADDR_37:0x[a-z0-9]*]] 'int' -// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | | | `-ParenExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' -// C-NEXT: | | | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' -// C-NEXT: | | `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' -// C-NEXT: | | `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_14]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: | `-PseudoObjectExpr [[ADDR_43:0x[a-z0-9]*]] 'int' -// C-NEXT: | |-CallExpr [[ADDR_44:0x[a-z0-9]*]] 'int' -// C-NEXT: | | `-ParenExpr [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | | `-UnaryOperator [[ADDR_46:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// C-NEXT: | | `-DeclRefExpr [[ADDR_47:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// C-NEXT: | `-CallExpr [[ADDR_48:0x[a-z0-9]*]] 'int' -// C-NEXT: | `-ImplicitCastExpr [[ADDR_49:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: `-PseudoObjectExpr [[ADDR_50:0x[a-z0-9]*]] 'int' -// C-NEXT: |-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' -// C-NEXT: | `-ParenExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | `-UnaryOperator [[ADDR_53:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// C-NEXT: | `-DeclRefExpr [[ADDR_54:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' -// C-NEXT: `-CallExpr [[ADDR_55:0x[a-z0-9]*]] 'int' -// C-NEXT: `-ImplicitCastExpr [[ADDR_56:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_14]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_6]] line:13:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_14:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_15:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_16:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: |-FunctionDecl [[ADDR_17:0x[a-z0-9]*]] prev [[ADDR_11]] line:18:5 used also_after 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_18:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_19:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_20:0x[a-z0-9]*]] 'int' 2 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_21:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: `-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] line:22:5 main 'int ({{.*}})' +// C-NEXT: `-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] +// C-NEXT: `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] +// C-NEXT: `-BinaryOperator [[ADDR_25:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: |-BinaryOperator [[ADDR_26:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | |-BinaryOperator [[ADDR_27:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | | |-PseudoObjectExpr [[ADDR_28:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | |-CallExpr [[ADDR_29:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | | `-ImplicitCastExpr [[ADDR_30:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | | `-ParenExpr [[ADDR_31:0x[a-z0-9]*]] 'int ({{.*}})' +// C-NEXT: | | | | `-DeclRefExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// C-NEXT: | | | `-CallExpr [[ADDR_33:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_34:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: | | `-PseudoObjectExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// C-NEXT: | | |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-ParenExpr [[ADDR_38:0x[a-z0-9]*]] 'int ({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// C-NEXT: | | `-CallExpr [[ADDR_40:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_41:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_5]] 'int ({{.*}})' Function [[ADDR_6]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: | `-PseudoObjectExpr [[ADDR_42:0x[a-z0-9]*]] 'int' +// C-NEXT: | |-CallExpr [[ADDR_43:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ParenExpr [[ADDR_44:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-UnaryOperator [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: | | `-DeclRefExpr [[ADDR_46:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// C-NEXT: | `-CallExpr [[ADDR_47:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_48:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: `-PseudoObjectExpr [[ADDR_49:0x[a-z0-9]*]] 'int' +// C-NEXT: |-CallExpr [[ADDR_50:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ParenExpr [[ADDR_51:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-UnaryOperator [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: | `-DeclRefExpr [[ADDR_53:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// C-NEXT: `-CallExpr [[ADDR_54:0x[a-z0-9]*]] 'int' +// C-NEXT: `-ImplicitCastExpr [[ADDR_55:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: `-DeclRefExpr [[ADDR_5]] 'int ({{.*}})' Function [[ADDR_6]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' -// CXX-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] -// CXX-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] -// CXX-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 -// CXX-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// CXX-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 implicit used also_before 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:10:5 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' // CXX-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] // CXX-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] // CXX-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 0 -// CXX-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' // CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' -// CXX-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] -// CXX-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] -// CXX-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 0 -// CXX-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' -// CXX-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// CXX-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// CXX-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 2 -// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} -// CXX-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: `-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 main 'int ({{.*}})' -// CXX-NEXT: `-CompoundStmt [[ADDR_24:0x[a-z0-9]*]] -// CXX-NEXT: `-ReturnStmt [[ADDR_25:0x[a-z0-9]*]] -// CXX-NEXT: `-BinaryOperator [[ADDR_26:0x[a-z0-9]*]] 'int' '+' -// CXX-NEXT: |-BinaryOperator [[ADDR_27:0x[a-z0-9]*]] 'int' '+' -// CXX-NEXT: | |-BinaryOperator [[ADDR_28:0x[a-z0-9]*]] 'int' '+' -// CXX-NEXT: | | |-PseudoObjectExpr [[ADDR_29:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | | |-CallExpr [[ADDR_30:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | | | `-ImplicitCastExpr [[ADDR_31:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | | | | `-ParenExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' lvalue -// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_33:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// CXX-NEXT: | | | `-CallExpr [[ADDR_34:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_35:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: | | `-PseudoObjectExpr [[ADDR_36:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | |-CallExpr [[ADDR_37:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | | | `-ParenExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' lvalue -// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' -// CXX-NEXT: | | `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_14]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: | `-PseudoObjectExpr [[ADDR_43:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | |-CallExpr [[ADDR_44:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | `-ParenExpr [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | | `-UnaryOperator [[ADDR_46:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// CXX-NEXT: | | `-DeclRefExpr [[ADDR_47:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// CXX-NEXT: | `-CallExpr [[ADDR_48:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_49:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: `-PseudoObjectExpr [[ADDR_50:0x[a-z0-9]*]] 'int' -// CXX-NEXT: |-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | `-ParenExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | `-UnaryOperator [[ADDR_53:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// CXX-NEXT: | `-DeclRefExpr [[ADDR_54:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' -// CXX-NEXT: `-CallExpr [[ADDR_55:0x[a-z0-9]*]] 'int' -// CXX-NEXT: `-ImplicitCastExpr [[ADDR_56:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_14]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_6]] line:13:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_14:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_15:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_16:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_17:0x[a-z0-9]*]] prev [[ADDR_11]] line:18:5 used also_after 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_18:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_19:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_20:0x[a-z0-9]*]] 'int' 2 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_21:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: `-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] line:22:5 main 'int ({{.*}})' +// CXX-NEXT: `-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] +// CXX-NEXT: `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] +// CXX-NEXT: `-BinaryOperator [[ADDR_25:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: |-BinaryOperator [[ADDR_26:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | |-BinaryOperator [[ADDR_27:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | | |-PseudoObjectExpr [[ADDR_28:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | |-CallExpr [[ADDR_29:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | | `-ImplicitCastExpr [[ADDR_30:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | | `-ParenExpr [[ADDR_31:0x[a-z0-9]*]] 'int ({{.*}})' lvalue +// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: | | | `-CallExpr [[ADDR_33:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_34:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: | | `-PseudoObjectExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-ParenExpr [[ADDR_38:0x[a-z0-9]*]] 'int ({{.*}})' lvalue +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// CXX-NEXT: | | `-CallExpr [[ADDR_40:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_41:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_5]] 'int ({{.*}})' Function [[ADDR_6]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: | `-PseudoObjectExpr [[ADDR_42:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | |-CallExpr [[ADDR_43:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ParenExpr [[ADDR_44:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-UnaryOperator [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_46:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: | `-CallExpr [[ADDR_47:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_48:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: `-PseudoObjectExpr [[ADDR_49:0x[a-z0-9]*]] 'int' +// CXX-NEXT: |-CallExpr [[ADDR_50:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ParenExpr [[ADDR_51:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-UnaryOperator [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: | `-DeclRefExpr [[ADDR_53:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// CXX-NEXT: `-CallExpr [[ADDR_54:0x[a-z0-9]*]] 'int' +// CXX-NEXT: `-ImplicitCastExpr [[ADDR_55:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: `-DeclRefExpr [[ADDR_5]] 'int ({{.*}})' Function [[ADDR_6]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c index 1e5241bc2c58..ffcd236244b2 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c @@ -28,37 +28,36 @@ int main() { // - we see the specialization in the AST // - we do use the original pointers for the calls as the variants are not applicable (this is not the ibm compiler). -// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 -// CHECK-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(ibm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after[implementation={vendor(ibm)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after[implementation={vendor(ibm)}] 'int ({{.*}})' +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 implicit used also_before 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(ibm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before[implementation={vendor(ibm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:10:5 also_after[implementation={vendor(ibm)}] 'int ({{.*}})' // CHECK-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] // CHECK-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] // CHECK-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 -// CHECK-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' // CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(ibm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before[implementation={vendor(ibm)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before[implementation={vendor(ibm)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 -// CHECK-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' -// CHECK-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// CHECK-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(ibm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(ibm)}]' 'int ({{.*}})' -// CHECK-NEXT: `-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 main 'int ({{.*}})' -// CHECK-NEXT: `-CompoundStmt [[ADDR_24:0x[a-z0-9]*]] -// CHECK-NEXT: `-ReturnStmt [[ADDR_25:0x[a-z0-9]*]] -// CHECK-NEXT: `-BinaryOperator [[ADDR_26:0x[a-z0-9]*]] 'int' '+' -// CHECK-NEXT: |-CallExpr [[ADDR_27:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_28:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_29:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// CHECK-NEXT: `-CallExpr [[ADDR_30:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_31:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: `-DeclRefExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(ibm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_6]] line:13:5 also_before[implementation={vendor(ibm)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_14:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_15:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_16:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: |-FunctionDecl [[ADDR_17:0x[a-z0-9]*]] prev [[ADDR_11]] line:18:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_18:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_19:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_20:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_21:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(ibm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(ibm)}]' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] line:22:5 main 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_25:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-CallExpr [[ADDR_26:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_27:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_28:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_29:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_30:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_31:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c index cf5c1f3f62c1..070770ace337 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c @@ -34,49 +34,48 @@ int test() { // We will issue an error during code generation instead. This is similar to the // diagnosis in other multi-versioning schemes. -// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:14> col:5 used OK_1 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_1:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used OK_1 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_2:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_3:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_4:0x[a-z0-9]*]] 'OK_1[implementation={vendor(intel)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_4]] line:8:1 OK_1[implementation={vendor(intel)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_5:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_6:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_7:0x[a-z0-9]*]] 'int' 1 -// CHECK-NEXT: |-FunctionDecl [[ADDR_8:0x[a-z0-9]*]] col:5 implicit OK_2 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_9:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_10:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11:0x[a-z0-9]*]] 'OK_2[implementation={vendor(intel)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_11]] line:11:1 OK_2[implementation={vendor(intel)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_12:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_13:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_14:0x[a-z0-9]*]] 'int' 1 -// CHECK-NEXT: |-FunctionDecl [[ADDR_15:0x[a-z0-9]*]] col:5 implicit used not_OK 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_16:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18:0x[a-z0-9]*]] 'not_OK[implementation={vendor(intel)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_18]] line:14:1 not_OK[implementation={vendor(intel)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 1 -// CHECK-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] col:5 implicit used OK_3 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_23:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_24:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_25:0x[a-z0-9]*]] 'OK_3[implementation={vendor(intel)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_25]] line:17:1 OK_3[implementation={vendor(intel)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_26:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_27:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_28:0x[a-z0-9]*]] 'int' 1 -// CHECK-NEXT: |-FunctionDecl [[ADDR_29:0x[a-z0-9]*]] prev [[ADDR_22]] col:5 used OK_3 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_30:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(intel)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_24]] 'int ({{.*}})' Function [[ADDR_25]] 'OK_3[implementation={vendor(intel)}]' 'int ({{.*}})' -// CHECK-NEXT: `-FunctionDecl [[ADDR_31:0x[a-z0-9]*]] line:24:5 test 'int ({{.*}})' -// CHECK-NEXT: `-CompoundStmt [[ADDR_32:0x[a-z0-9]*]] -// CHECK-NEXT: `-ReturnStmt [[ADDR_33:0x[a-z0-9]*]] -// CHECK-NEXT: `-BinaryOperator [[ADDR_34:0x[a-z0-9]*]] 'int' '+' -// CHECK-NEXT: |-BinaryOperator [[ADDR_35:0x[a-z0-9]*]] 'int' '+' -// CHECK-NEXT: | |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_1]] 'OK_1' 'int ({{.*}})' -// CHECK-NEXT: | `-CallExpr [[ADDR_39:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_40:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_41:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_15]] 'not_OK' 'int ({{.*}})' -// CHECK-NEXT: `-CallExpr [[ADDR_42:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_43:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: `-DeclRefExpr [[ADDR_44:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_29]] 'OK_3' 'int ({{.*}})' +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:14> col:5 implicit used OK_1 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_1:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_2:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_3:0x[a-z0-9]*]] 'OK_1[implementation={vendor(intel)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_3]] line:8:5 OK_1[implementation={vendor(intel)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_4:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_5:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_6:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:11:5 OK_2[implementation={vendor(intel)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] col:5 implicit OK_2 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'OK_2[implementation={vendor(intel)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] line:14:5 not_OK[implementation={vendor(intel)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] col:5 implicit used not_OK 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_19:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_20:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14]] 'not_OK[implementation={vendor(intel)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_21:0x[a-z0-9]*]] line:17:5 OK_3[implementation={vendor(intel)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_22:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_23:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_24:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_25:0x[a-z0-9]*]] col:5 implicit used OK_3 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_26:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_27:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_21]] 'OK_3[implementation={vendor(intel)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_28:0x[a-z0-9]*]] prev [[ADDR_25]] col:5 used OK_3 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_29:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_27]] 'int ({{.*}})' Function [[ADDR_21]] 'OK_3[implementation={vendor(intel)}]' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_30:0x[a-z0-9]*]] line:24:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_31:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_32:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-BinaryOperator [[ADDR_34:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | |-CallExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_36:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_37:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'OK_1' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_38:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'not_OK' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_43:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_28]] 'OK_3' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c index efedd2f9bb74..68ebf896a44e 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c @@ -33,50 +33,47 @@ int test() { // - we do see the ast nodes for the llvm vendor // - we pick the right callees -// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:21> col:5 implicit used also_before 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_1:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_2:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_3:0x[a-z0-9]*]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_3]] line:6:1 also_before[device={kind(cpu)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_4:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_5:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_6:0x[a-z0-9]*]] 'int' 1 -// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_8:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_10]] line:12:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:8:1> line:6:5 also_before[device={kind(cpu)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_before 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_7:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_8:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_9:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_10:0x[a-z0-9]*]] line:12:5 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' // CHECK-NEXT: | `-CompoundStmt [[ADDR_11:0x[a-z0-9]*]] // CHECK-NEXT: | `-ReturnStmt [[ADDR_12:0x[a-z0-9]*]] // CHECK-NEXT: | `-IntegerLiteral [[ADDR_13:0x[a-z0-9]*]] 'int' 0 -// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' -// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_15:0x[a-z0-9]*]] <> Inherited Implicit device={kind(cpu)} -// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before[device={kind(cpu)}]' 'int ({{.*}})' -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_16:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: |-FunctionDecl [[ADDR_18]] line:17:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// CHECK-NEXT: | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// CHECK-NEXT: | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 -// CHECK-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] prev [[ADDR_7]] line:22:5 used also_after 'int ({{.*}})' -// CHECK-NEXT: | |-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] -// CHECK-NEXT: | | `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] -// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_25:0x[a-z0-9]*]] 'int' 2 -// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_26:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(0): llvm)} -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: `-FunctionDecl [[ADDR_27:0x[a-z0-9]*]] line:26:5 test 'int ({{.*}})' -// CHECK-NEXT: `-CompoundStmt [[ADDR_28:0x[a-z0-9]*]] -// CHECK-NEXT: `-ReturnStmt [[ADDR_29:0x[a-z0-9]*]] -// CHECK-NEXT: `-BinaryOperator [[ADDR_30:0x[a-z0-9]*]] 'int' '+' -// CHECK-NEXT: |-PseudoObjectExpr [[ADDR_31:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | |-CallExpr [[ADDR_32:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_33:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_34:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_22]] 'also_after' 'int ({{.*}})' -// CHECK-NEXT: | `-CallExpr [[ADDR_35:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_36:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_37:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: |-CallExpr [[ADDR_38:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'also_before' 'int ({{.*}})' -// CHECK-NEXT: `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' -// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: `-DeclRefExpr [[ADDR_17]] 'int ({{.*}})' Function [[ADDR_18]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_15:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_16:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_9]] line:17:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_17:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_18:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_19:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_20:0x[a-z0-9]*]] prev [[ADDR_14]] line:22:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_21:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_22:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_23:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_24:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_16]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_25:0x[a-z0-9]*]] line:26:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_26:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_27:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_28:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-PseudoObjectExpr [[ADDR_29:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_30:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_31:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_20]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_33:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_34:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_16]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_4]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_39:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_40:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_8]] 'int ({{.*}})' Function [[ADDR_9]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c index af61859ae306..d6b5ccece796 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c @@ -35,150 +35,148 @@ int main() { // - we see the specialization in the AST // - we pick the right callees -// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' -// C-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] -// C-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] -// C-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 -// C-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// C-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 implicit used also_before 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:10:5 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' // C-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] // C-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] // C-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 -// C-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' // C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// C-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' -// C-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] -// C-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] -// C-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 -// C-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' -// C-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// C-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// C-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 -// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} -// C-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] col:6 used foo 'void ({{.*}})' -// C-NEXT: |-TypedefDecl [[ADDR_24:0x[a-z0-9]*]] col:14 referenced fd 'int (*)({{.*}})' -// C-NEXT: | `-PointerType [[ADDR_25:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | `-ParenType [[ADDR_26:0x[a-z0-9]*]] 'int ({{.*}})' sugar -// C-NEXT: | `-FunctionProtoType [[ADDR_27:0x[a-z0-9]*]] 'int ({{.*}})' cdecl -// C-NEXT: | `-BuiltinType [[ADDR_28:0x[a-z0-9]*]] 'int' -// C-NEXT: `-FunctionDecl [[ADDR_29:0x[a-z0-9]*]] line:24:5 main 'int ({{.*}})' -// C-NEXT: `-CompoundStmt [[ADDR_30:0x[a-z0-9]*]] -// C-NEXT: |-DeclStmt [[ADDR_31:0x[a-z0-9]*]] -// C-NEXT: | `-VarDecl [[ADDR_32:0x[a-z0-9]*]] col:6 used fns 'fd [2]' -// C-NEXT: |-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' '=' -// C-NEXT: | |-ArraySubscriptExpr [[ADDR_34:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// C-NEXT: | | |-ImplicitCastExpr [[ADDR_35:0x[a-z0-9]*]] 'fd *' -// C-NEXT: | | | `-DeclRefExpr [[ADDR_36:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' -// C-NEXT: | | `-IntegerLiteral [[ADDR_37:0x[a-z0-9]*]] 'int' 0 -// C-NEXT: | `-UnaryOperator [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// C-NEXT: | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' -// C-NEXT: |-BinaryOperator [[ADDR_40:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' '=' -// C-NEXT: | |-ArraySubscriptExpr [[ADDR_41:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// C-NEXT: | | |-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'fd *' -// C-NEXT: | | | `-DeclRefExpr [[ADDR_43:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' -// C-NEXT: | | `-IntegerLiteral [[ADDR_44:0x[a-z0-9]*]] 'int' 1 -// C-NEXT: | `-ImplicitCastExpr [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | `-DeclRefExpr [[ADDR_46:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// C-NEXT: `-ReturnStmt [[ADDR_47:0x[a-z0-9]*]] -// C-NEXT: `-BinaryOperator [[ADDR_48:0x[a-z0-9]*]] 'int' '+' -// C-NEXT: |-BinaryOperator [[ADDR_49:0x[a-z0-9]*]] 'int' '+' -// C-NEXT: | |-CallExpr [[ADDR_50:0x[a-z0-9]*]] 'int' -// C-NEXT: | | `-ParenExpr [[ADDR_51:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | | `-BinaryOperator [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' ',' -// C-NEXT: | | |-CallExpr [[ADDR_53:0x[a-z0-9]*]] 'void' -// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_54:0x[a-z0-9]*]] 'void (*)({{.*}})' -// C-NEXT: | | | `-DeclRefExpr [[ADDR_55:0x[a-z0-9]*]] 'void ({{.*}})' Function [[ADDR_23]] 'foo' 'void ({{.*}})' -// C-NEXT: | | `-ImplicitCastExpr [[ADDR_56:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | | `-DeclRefExpr [[ADDR_57:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// C-NEXT: | `-CallExpr [[ADDR_58:0x[a-z0-9]*]] 'int' -// C-NEXT: | `-ImplicitCastExpr [[ADDR_59:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' -// C-NEXT: | `-ParenExpr [[ADDR_60:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// C-NEXT: | `-ArraySubscriptExpr [[ADDR_61:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// C-NEXT: | |-ImplicitCastExpr [[ADDR_62:0x[a-z0-9]*]] 'fd *' -// C-NEXT: | | `-DeclRefExpr [[ADDR_63:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' -// C-NEXT: | `-IntegerLiteral [[ADDR_64:0x[a-z0-9]*]] 'int' 0 -// C-NEXT: `-CallExpr [[ADDR_65:0x[a-z0-9]*]] 'int' -// C-NEXT: `-ImplicitCastExpr [[ADDR_66:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' -// C-NEXT: `-ParenExpr [[ADDR_67:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// C-NEXT: `-ArraySubscriptExpr [[ADDR_68:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// C-NEXT: |-IntegerLiteral [[ADDR_69:0x[a-z0-9]*]] 'int' 1 -// C-NEXT: `-ImplicitCastExpr [[ADDR_70:0x[a-z0-9]*]] 'fd *' -// C-NEXT: `-DeclRefExpr [[ADDR_71:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' +// C-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_6]] line:13:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_14:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_15:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_16:0x[a-z0-9]*]] 'int' 2 +// C-NEXT: |-FunctionDecl [[ADDR_17:0x[a-z0-9]*]] prev [[ADDR_11]] line:18:5 used also_after 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_18:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_19:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_20:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_21:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] col:6 used foo 'void ({{.*}})' +// C-NEXT: |-TypedefDecl [[ADDR_23:0x[a-z0-9]*]] col:14 referenced fd 'int (*)({{.*}})' +// C-NEXT: | `-PointerType [[ADDR_24:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-ParenType [[ADDR_25:0x[a-z0-9]*]] 'int ({{.*}})' sugar +// C-NEXT: | `-FunctionProtoType [[ADDR_26:0x[a-z0-9]*]] 'int ({{.*}})' cdecl +// C-NEXT: | `-BuiltinType [[ADDR_27:0x[a-z0-9]*]] 'int' +// C-NEXT: `-FunctionDecl [[ADDR_28:0x[a-z0-9]*]] line:24:5 main 'int ({{.*}})' +// C-NEXT: `-CompoundStmt [[ADDR_29:0x[a-z0-9]*]] +// C-NEXT: |-DeclStmt [[ADDR_30:0x[a-z0-9]*]] +// C-NEXT: | `-VarDecl [[ADDR_31:0x[a-z0-9]*]] col:6 used fns 'fd [2]' +// C-NEXT: |-BinaryOperator [[ADDR_32:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' '=' +// C-NEXT: | |-ArraySubscriptExpr [[ADDR_33:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: | | |-ImplicitCastExpr [[ADDR_34:0x[a-z0-9]*]] 'fd *' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_35:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_31]] 'fns' 'fd [2]' +// C-NEXT: | | `-IntegerLiteral [[ADDR_36:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-UnaryOperator [[ADDR_37:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// C-NEXT: |-BinaryOperator [[ADDR_39:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' '=' +// C-NEXT: | |-ArraySubscriptExpr [[ADDR_40:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: | | |-ImplicitCastExpr [[ADDR_41:0x[a-z0-9]*]] 'fd *' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_42:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_31]] 'fns' 'fd [2]' +// C-NEXT: | | `-IntegerLiteral [[ADDR_43:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: | `-ImplicitCastExpr [[ADDR_44:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_45:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// C-NEXT: `-ReturnStmt [[ADDR_46:0x[a-z0-9]*]] +// C-NEXT: `-BinaryOperator [[ADDR_47:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: |-BinaryOperator [[ADDR_48:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | |-CallExpr [[ADDR_49:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ParenExpr [[ADDR_50:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-BinaryOperator [[ADDR_51:0x[a-z0-9]*]] 'int (*)({{.*}})' ',' +// C-NEXT: | | |-CallExpr [[ADDR_52:0x[a-z0-9]*]] 'void' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_53:0x[a-z0-9]*]] 'void (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_54:0x[a-z0-9]*]] 'void ({{.*}})' Function [[ADDR_22]] 'foo' 'void ({{.*}})' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_55:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_56:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// C-NEXT: | `-CallExpr [[ADDR_57:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_58:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' +// C-NEXT: | `-ParenExpr [[ADDR_59:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: | `-ArraySubscriptExpr [[ADDR_60:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: | |-ImplicitCastExpr [[ADDR_61:0x[a-z0-9]*]] 'fd *' +// C-NEXT: | | `-DeclRefExpr [[ADDR_62:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_31]] 'fns' 'fd [2]' +// C-NEXT: | `-IntegerLiteral [[ADDR_63:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: `-CallExpr [[ADDR_64:0x[a-z0-9]*]] 'int' +// C-NEXT: `-ImplicitCastExpr [[ADDR_65:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' +// C-NEXT: `-ParenExpr [[ADDR_66:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: `-ArraySubscriptExpr [[ADDR_67:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: |-IntegerLiteral [[ADDR_68:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: `-ImplicitCastExpr [[ADDR_69:0x[a-z0-9]*]] 'fd *' +// C-NEXT: `-DeclRefExpr [[ADDR_70:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_31]] 'fns' 'fd [2]' -// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' -// CXX-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] -// CXX-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] -// CXX-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 -// CXX-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// CXX-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 implicit used also_before 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:10:5 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' // CXX-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] // CXX-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] // CXX-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 -// CXX-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' // CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' -// CXX-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] -// CXX-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] -// CXX-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 -// CXX-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' -// CXX-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// CXX-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// CXX-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 -// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} -// CXX-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] col:6 used foo 'void ({{.*}})' -// CXX-NEXT: |-TypedefDecl [[ADDR_24:0x[a-z0-9]*]] col:14 referenced fd 'int (*)({{.*}})' -// CXX-NEXT: | `-PointerType [[ADDR_25:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | `-ParenType [[ADDR_26:0x[a-z0-9]*]] 'int ({{.*}})' sugar -// CXX-NEXT: | `-FunctionProtoType [[ADDR_27:0x[a-z0-9]*]] 'int ({{.*}})' cdecl -// CXX-NEXT: | `-BuiltinType [[ADDR_28:0x[a-z0-9]*]] 'int' -// CXX-NEXT: `-FunctionDecl [[ADDR_29:0x[a-z0-9]*]] line:24:5 main 'int ({{.*}})' -// CXX-NEXT: `-CompoundStmt [[ADDR_30:0x[a-z0-9]*]] -// CXX-NEXT: |-DeclStmt [[ADDR_31:0x[a-z0-9]*]] -// CXX-NEXT: | `-VarDecl [[ADDR_32:0x[a-z0-9]*]] col:6 used fns 'fd [2]' -// CXX-NEXT: |-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' {{.*}}'=' -// CXX-NEXT: | |-ArraySubscriptExpr [[ADDR_34:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_35:0x[a-z0-9]*]] 'fd *' -// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_36:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' -// CXX-NEXT: | | `-IntegerLiteral [[ADDR_37:0x[a-z0-9]*]] 'int' 0 -// CXX-NEXT: | `-UnaryOperator [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// CXX-NEXT: | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' -// CXX-NEXT: |-BinaryOperator [[ADDR_40:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' {{.*}}'=' -// CXX-NEXT: | |-ArraySubscriptExpr [[ADDR_41:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'fd *' -// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_43:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' -// CXX-NEXT: | | `-IntegerLiteral [[ADDR_44:0x[a-z0-9]*]] 'int' 1 -// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | `-DeclRefExpr [[ADDR_46:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// CXX-NEXT: `-ReturnStmt [[ADDR_47:0x[a-z0-9]*]] -// CXX-NEXT: `-BinaryOperator [[ADDR_48:0x[a-z0-9]*]] 'int' '+' -// CXX-NEXT: |-BinaryOperator [[ADDR_49:0x[a-z0-9]*]] 'int' '+' -// CXX-NEXT: | |-CallExpr [[ADDR_50:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_51:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | | `-ParenExpr [[ADDR_52:0x[a-z0-9]*]] 'int ({{.*}})' lvalue -// CXX-NEXT: | | `-BinaryOperator [[ADDR_53:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}',' -// CXX-NEXT: | | |-CallExpr [[ADDR_54:0x[a-z0-9]*]] 'void' -// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_55:0x[a-z0-9]*]] 'void (*)({{.*}})' -// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_56:0x[a-z0-9]*]] 'void ({{.*}})' {{.*}}Function [[ADDR_23]] 'foo' 'void ({{.*}})' -// CXX-NEXT: | | `-DeclRefExpr [[ADDR_57:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// CXX-NEXT: | `-CallExpr [[ADDR_58:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_59:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' -// CXX-NEXT: | `-ParenExpr [[ADDR_60:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// CXX-NEXT: | `-ArraySubscriptExpr [[ADDR_61:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// CXX-NEXT: | |-ImplicitCastExpr [[ADDR_62:0x[a-z0-9]*]] 'fd *' -// CXX-NEXT: | | `-DeclRefExpr [[ADDR_63:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' -// CXX-NEXT: | `-IntegerLiteral [[ADDR_64:0x[a-z0-9]*]] 'int' 0 -// CXX-NEXT: `-CallExpr [[ADDR_65:0x[a-z0-9]*]] 'int' -// CXX-NEXT: `-ImplicitCastExpr [[ADDR_66:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' -// CXX-NEXT: `-ParenExpr [[ADDR_67:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// CXX-NEXT: `-ArraySubscriptExpr [[ADDR_68:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue -// CXX-NEXT: |-IntegerLiteral [[ADDR_69:0x[a-z0-9]*]] 'int' 1 -// CXX-NEXT: `-ImplicitCastExpr [[ADDR_70:0x[a-z0-9]*]] 'fd *' -// CXX-NEXT: `-DeclRefExpr [[ADDR_71:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_6]] line:13:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_14:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_15:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_16:0x[a-z0-9]*]] 'int' 2 +// CXX-NEXT: |-FunctionDecl [[ADDR_17:0x[a-z0-9]*]] prev [[ADDR_11]] line:18:5 used also_after 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_18:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_19:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_20:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_21:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] col:6 used foo 'void ({{.*}})' +// CXX-NEXT: |-TypedefDecl [[ADDR_23:0x[a-z0-9]*]] col:14 referenced fd 'int (*)({{.*}})' +// CXX-NEXT: | `-PointerType [[ADDR_24:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-ParenType [[ADDR_25:0x[a-z0-9]*]] 'int ({{.*}})' sugar +// CXX-NEXT: | `-FunctionProtoType [[ADDR_26:0x[a-z0-9]*]] 'int ({{.*}})' cdecl +// CXX-NEXT: | `-BuiltinType [[ADDR_27:0x[a-z0-9]*]] 'int' +// CXX-NEXT: `-FunctionDecl [[ADDR_28:0x[a-z0-9]*]] line:24:5 main 'int ({{.*}})' +// CXX-NEXT: `-CompoundStmt [[ADDR_29:0x[a-z0-9]*]] +// CXX-NEXT: |-DeclStmt [[ADDR_30:0x[a-z0-9]*]] +// CXX-NEXT: | `-VarDecl [[ADDR_31:0x[a-z0-9]*]] col:6 used fns 'fd [2]' +// CXX-NEXT: |-BinaryOperator [[ADDR_32:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' {{.*}}'=' +// CXX-NEXT: | |-ArraySubscriptExpr [[ADDR_33:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_34:0x[a-z0-9]*]] 'fd *' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_35:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_31]] 'fns' 'fd [2]' +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_36:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-UnaryOperator [[ADDR_37:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// CXX-NEXT: |-BinaryOperator [[ADDR_39:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' {{.*}}'=' +// CXX-NEXT: | |-ArraySubscriptExpr [[ADDR_40:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_41:0x[a-z0-9]*]] 'fd *' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_42:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_31]] 'fns' 'fd [2]' +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_43:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_44:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_45:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: `-ReturnStmt [[ADDR_46:0x[a-z0-9]*]] +// CXX-NEXT: `-BinaryOperator [[ADDR_47:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: |-BinaryOperator [[ADDR_48:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | |-CallExpr [[ADDR_49:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_50:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-ParenExpr [[ADDR_51:0x[a-z0-9]*]] 'int ({{.*}})' lvalue +// CXX-NEXT: | | `-BinaryOperator [[ADDR_52:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}',' +// CXX-NEXT: | | |-CallExpr [[ADDR_53:0x[a-z0-9]*]] 'void' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_54:0x[a-z0-9]*]] 'void (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_55:0x[a-z0-9]*]] 'void ({{.*}})' {{.*}}Function [[ADDR_22]] 'foo' 'void ({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_56:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: | `-CallExpr [[ADDR_57:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_58:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' +// CXX-NEXT: | `-ParenExpr [[ADDR_59:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: | `-ArraySubscriptExpr [[ADDR_60:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: | |-ImplicitCastExpr [[ADDR_61:0x[a-z0-9]*]] 'fd *' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_62:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_31]] 'fns' 'fd [2]' +// CXX-NEXT: | `-IntegerLiteral [[ADDR_63:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: `-CallExpr [[ADDR_64:0x[a-z0-9]*]] 'int' +// CXX-NEXT: `-ImplicitCastExpr [[ADDR_65:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' +// CXX-NEXT: `-ParenExpr [[ADDR_66:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: `-ArraySubscriptExpr [[ADDR_67:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: |-IntegerLiteral [[ADDR_68:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: `-ImplicitCastExpr [[ADDR_69:0x[a-z0-9]*]] 'fd *' +// CXX-NEXT: `-DeclRefExpr [[ADDR_70:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_31]] 'fns' 'fd [2]' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c index 1cb39dac3c7f..731753f9cb2d 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c @@ -34,118 +34,116 @@ int main() { // - we see the specialization in the AST // - we pick the right callees -// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' -// CXX-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] -// CXX-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] -// CXX-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 -// CXX-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// CXX-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' -// CXX-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] -// CXX-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] -// CXX-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 -// CXX-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' -// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' -// CXX-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] -// CXX-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] -// CXX-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 -// CXX-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' -// CXX-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// CXX-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// CXX-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 -// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} -// CXX-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// CXX-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 used test 'int (int (*)({{.*}}))' -// CXX-NEXT: | |-ParmVarDecl [[ADDR_24:0x[a-z0-9]*]] col:16 used fd 'int (*)({{.*}})' -// CXX-NEXT: | `-CompoundStmt [[ADDR_25:0x[a-z0-9]*]] -// CXX-NEXT: | `-ReturnStmt [[ADDR_26:0x[a-z0-9]*]] -// CXX-NEXT: | `-CallExpr [[ADDR_27:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_28:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | `-DeclRefExpr [[ADDR_29:0x[a-z0-9]*]] 'int (*)({{.*}})' {{.*}}ParmVar [[ADDR_24]] 'fd' 'int (*)({{.*}})' -// CXX-NEXT: `-FunctionDecl [[ADDR_30:0x[a-z0-9]*]] line:25:5 main 'int ({{.*}})' -// CXX-NEXT: `-CompoundStmt [[ADDR_31:0x[a-z0-9]*]] -// CXX-NEXT: `-ReturnStmt [[ADDR_32:0x[a-z0-9]*]] -// CXX-NEXT: `-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'int' '+' -// CXX-NEXT: |-BinaryOperator [[ADDR_34:0x[a-z0-9]*]] 'int' '+' -// CXX-NEXT: | |-BinaryOperator [[ADDR_35:0x[a-z0-9]*]] 'int' '+' -// CXX-NEXT: | | |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | | |-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' -// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' -// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// CXX-NEXT: | | `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' -// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_43:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' -// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_44:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CXX-NEXT: | | `-DeclRefExpr [[ADDR_45:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' -// CXX-NEXT: | `-CallExpr [[ADDR_46:0x[a-z0-9]*]] 'int' -// CXX-NEXT: | |-ImplicitCastExpr [[ADDR_47:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' -// CXX-NEXT: | | `-DeclRefExpr [[ADDR_48:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' -// CXX-NEXT: | `-UnaryOperator [[ADDR_49:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// CXX-NEXT: | `-DeclRefExpr [[ADDR_50:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// CXX-NEXT: `-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' -// CXX-NEXT: |-ImplicitCastExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' -// CXX-NEXT: | `-DeclRefExpr [[ADDR_53:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' -// CXX-NEXT: `-UnaryOperator [[ADDR_54:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// CXX-NEXT: `-DeclRefExpr [[ADDR_55:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' - -// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' -// C-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] -// C-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] -// C-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 -// C-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' -// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// C-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 implicit used also_before 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:10:5 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' // C-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] // C-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] // C-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 -// C-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 implicit used also_before 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' // C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} -// C-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' -// C-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] -// C-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] -// C-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 -// C-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' -// C-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] -// C-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] -// C-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 -// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} -// C-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' -// C-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 used test 'int (int (*)({{.*}}))' -// C-NEXT: | |-ParmVarDecl [[ADDR_24:0x[a-z0-9]*]] col:16 used fd 'int (*)({{.*}})' -// C-NEXT: | `-CompoundStmt [[ADDR_25:0x[a-z0-9]*]] -// C-NEXT: | `-ReturnStmt [[ADDR_26:0x[a-z0-9]*]] -// C-NEXT: | `-CallExpr [[ADDR_27:0x[a-z0-9]*]] 'int' -// C-NEXT: | `-ImplicitCastExpr [[ADDR_28:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | `-DeclRefExpr [[ADDR_29:0x[a-z0-9]*]] 'int (*)({{.*}})' {{.*}}ParmVar [[ADDR_24]] 'fd' 'int (*)({{.*}})' -// C-NEXT: `-FunctionDecl [[ADDR_30:0x[a-z0-9]*]] line:25:5 main 'int ({{.*}})' -// C-NEXT: `-CompoundStmt [[ADDR_31:0x[a-z0-9]*]] -// C-NEXT: `-ReturnStmt [[ADDR_32:0x[a-z0-9]*]] -// C-NEXT: `-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'int' '+' -// C-NEXT: |-BinaryOperator [[ADDR_34:0x[a-z0-9]*]] 'int' '+' -// C-NEXT: | |-BinaryOperator [[ADDR_35:0x[a-z0-9]*]] 'int' '+' -// C-NEXT: | | |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' -// C-NEXT: | | | |-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' -// C-NEXT: | | | | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' -// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | | | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// C-NEXT: | | `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' -// C-NEXT: | | |-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' -// C-NEXT: | | | `-DeclRefExpr [[ADDR_43:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' -// C-NEXT: | | `-ImplicitCastExpr [[ADDR_44:0x[a-z0-9]*]] 'int (*)({{.*}})' -// C-NEXT: | | `-DeclRefExpr [[ADDR_45:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' -// C-NEXT: | `-CallExpr [[ADDR_46:0x[a-z0-9]*]] 'int' -// C-NEXT: | |-ImplicitCastExpr [[ADDR_47:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' -// C-NEXT: | | `-DeclRefExpr [[ADDR_48:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' -// C-NEXT: | `-UnaryOperator [[ADDR_49:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// C-NEXT: | `-DeclRefExpr [[ADDR_50:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' -// C-NEXT: `-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' -// C-NEXT: |-ImplicitCastExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' -// C-NEXT: | `-DeclRefExpr [[ADDR_53:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' -// C-NEXT: `-UnaryOperator [[ADDR_54:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow -// C-NEXT: `-DeclRefExpr [[ADDR_55:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_6]] line:13:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_14:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_15:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_16:0x[a-z0-9]*]] 'int' 2 +// C-NEXT: |-FunctionDecl [[ADDR_17:0x[a-z0-9]*]] prev [[ADDR_11]] line:18:5 used also_after 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_18:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_19:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_20:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_21:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] line:22:5 used test 'int (int (*)({{.*}}))' +// C-NEXT: | |-ParmVarDecl [[ADDR_23:0x[a-z0-9]*]] col:16 used fd 'int (*)({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_24:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_25:0x[a-z0-9]*]] +// C-NEXT: | `-CallExpr [[ADDR_26:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_27:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_28:0x[a-z0-9]*]] 'int (*)({{.*}})' {{.*}}ParmVar [[ADDR_23]] 'fd' 'int (*)({{.*}})' +// C-NEXT: `-FunctionDecl [[ADDR_29:0x[a-z0-9]*]] line:25:5 main 'int ({{.*}})' +// C-NEXT: `-CompoundStmt [[ADDR_30:0x[a-z0-9]*]] +// C-NEXT: `-ReturnStmt [[ADDR_31:0x[a-z0-9]*]] +// C-NEXT: `-BinaryOperator [[ADDR_32:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: |-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | |-BinaryOperator [[ADDR_34:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | | |-CallExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | |-ImplicitCastExpr [[ADDR_36:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// C-NEXT: | | | | `-DeclRefExpr [[ADDR_37:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_22]] 'test' 'int (int (*)({{.*}}))' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// C-NEXT: | | `-CallExpr [[ADDR_40:0x[a-z0-9]*]] 'int' +// C-NEXT: | | |-ImplicitCastExpr [[ADDR_41:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_42:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_22]] 'test' 'int (int (*)({{.*}}))' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_43:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_44:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// C-NEXT: | `-CallExpr [[ADDR_45:0x[a-z0-9]*]] 'int' +// C-NEXT: | |-ImplicitCastExpr [[ADDR_46:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// C-NEXT: | | `-DeclRefExpr [[ADDR_47:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_22]] 'test' 'int (int (*)({{.*}}))' +// C-NEXT: | `-UnaryOperator [[ADDR_48:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: | `-DeclRefExpr [[ADDR_49:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// C-NEXT: `-CallExpr [[ADDR_50:0x[a-z0-9]*]] 'int' +// C-NEXT: |-ImplicitCastExpr [[ADDR_51:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// C-NEXT: | `-DeclRefExpr [[ADDR_52:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_22]] 'test' 'int (int (*)({{.*}}))' +// C-NEXT: `-UnaryOperator [[ADDR_53:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: `-DeclRefExpr [[ADDR_54:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_0]] 'also_before' 'int ({{.*}})' + +// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 implicit used also_before 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_4:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_5:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_6:0x[a-z0-9]*]] 'also_before[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:10:5 also_after[implementation={vendor(llvm)}] 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] col:5 implicit used also_after 'int ({{.*}})' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_6]] line:13:5 also_before[implementation={vendor(llvm)}] 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_14:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_15:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_16:0x[a-z0-9]*]] 'int' 2 +// CXX-NEXT: |-FunctionDecl [[ADDR_17:0x[a-z0-9]*]] prev [[ADDR_11]] line:18:5 used also_after 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_18:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_19:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_20:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_21:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] line:22:5 used test 'int (int (*)({{.*}}))' +// CXX-NEXT: | |-ParmVarDecl [[ADDR_23:0x[a-z0-9]*]] col:16 used fd 'int (*)({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_24:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_25:0x[a-z0-9]*]] +// CXX-NEXT: | `-CallExpr [[ADDR_26:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_27:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_28:0x[a-z0-9]*]] 'int (*)({{.*}})' {{.*}}ParmVar [[ADDR_23]] 'fd' 'int (*)({{.*}})' +// CXX-NEXT: `-FunctionDecl [[ADDR_29:0x[a-z0-9]*]] line:25:5 main 'int ({{.*}})' +// CXX-NEXT: `-CompoundStmt [[ADDR_30:0x[a-z0-9]*]] +// CXX-NEXT: `-ReturnStmt [[ADDR_31:0x[a-z0-9]*]] +// CXX-NEXT: `-BinaryOperator [[ADDR_32:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: |-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | |-BinaryOperator [[ADDR_34:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | | |-CallExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | |-ImplicitCastExpr [[ADDR_36:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_37:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_22]] 'test' 'int (int (*)({{.*}}))' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: | | `-CallExpr [[ADDR_40:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_41:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_42:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_22]] 'test' 'int (int (*)({{.*}}))' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_43:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_44:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// CXX-NEXT: | `-CallExpr [[ADDR_45:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | |-ImplicitCastExpr [[ADDR_46:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_47:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_22]] 'test' 'int (int (*)({{.*}}))' +// CXX-NEXT: | `-UnaryOperator [[ADDR_48:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: | `-DeclRefExpr [[ADDR_49:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_17]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: `-CallExpr [[ADDR_50:0x[a-z0-9]*]] 'int' +// CXX-NEXT: |-ImplicitCastExpr [[ADDR_51:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_52:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_22]] 'test' 'int (int (*)({{.*}}))' +// CXX-NEXT: `-UnaryOperator [[ADDR_53:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: `-DeclRefExpr [[ADDR_54:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_namespace_1.cpp b/clang/test/AST/ast-dump-openmp-begin-declare-variant_namespace_1.cpp new file mode 100644 index 000000000000..f1a4ff1c3f11 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_namespace_1.cpp @@ -0,0 +1,162 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++ | FileCheck %s + +namespace A { +int foo(void) { // expected-note {{candidate function}} + return 0; +} +} // namespace A + +namespace B { +int bar(void) { + return 1; +} +} // namespace B + +namespace C { +int baz(void) { + return 2; +} +} // namespace C + +#pragma omp begin declare variant match(implementation = {vendor(llvm)}) + +// This will *not* be a specialization of A::foo(void). +int foo(void) { // expected-note {{candidate function}} + return 3; +} + +namespace B { +// This will *not* be a specialization of A::foo(void). +int foo(void) { + return 4; +} +// This will be a specialization of B::bar(void). +int bar(void) { + return 0; +} +} // namespace B + +using namespace C; + +// This will be a specialization of C::baz(void). +int baz(void) { + return 0; +} +#pragma omp end declare variant + + +int explicit1() { + // Should return 0. + return A::foo() + B::bar() + C::baz(); +} + +int implicit2() { + using namespace A; + using namespace B; + // Should return 0. + foo(); // expected-error {{call to 'foo' is ambiguous}} + return bar() + baz(); +} + +int main() { + // Should return 0. + return explicit1() + implicit2(); +} + +// CHECK: |-NamespaceDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:3:11 A +// CHECK-NEXT: | `-FunctionDecl [[ADDR_1:0x[a-z0-9]*]] line:4:5 used foo 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_3:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_4:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-NamespaceDecl [[ADDR_5:0x[a-z0-9]*]] line:9:11 B +// CHECK-NEXT: | `-FunctionDecl [[ADDR_6:0x[a-z0-9]*]] line:10:5 implicit used bar 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_7:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_8:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_9:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_10:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_11:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_12:0x[a-z0-9]*]] 'bar[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-NamespaceDecl [[ADDR_13:0x[a-z0-9]*]] line:15:11 C +// CHECK-NEXT: | `-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] line:16:5 implicit used baz 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_18:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_19:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_20:0x[a-z0-9]*]] 'baz[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_21:0x[a-z0-9]*]] line:24:5 foo[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_22:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_23:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_24:0x[a-z0-9]*]] 'int' 3 +// CHECK-NEXT: |-FunctionDecl [[ADDR_25:0x[a-z0-9]*]] col:5 implicit foo 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_26:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_27:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_21]] 'foo[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_28:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_29:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_30:0x[a-z0-9]*]] 'foo[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-NamespaceDecl [[ADDR_31:0x[a-z0-9]*]] prev [[ADDR_5]] line:28:11 B +// CHECK-NEXT: | |-original Namespace [[ADDR_5]] 'B' +// CHECK-NEXT: | |-FunctionDecl [[ADDR_30]] line:30:5 foo[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK-NEXT: | | `-CompoundStmt [[ADDR_32:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_33:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_34:0x[a-z0-9]*]] 'int' 4 +// CHECK-NEXT: | `-FunctionDecl [[ADDR_12]] line:34:5 bar[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_35:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_36:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_37:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-UsingDirectiveDecl [[ADDR_38:0x[a-z0-9]*]] col:17 Namespace [[ADDR_13]] 'C' +// CHECK-NEXT: |-FunctionDecl [[ADDR_20]] line:42:5 baz[implementation={vendor(llvm)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_39:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_40:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_41:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_42:0x[a-z0-9]*]] line:48:5 used explicit1 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_43:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_44:0x[a-z0-9]*]] +// CHECK-NEXT: | `-BinaryOperator [[ADDR_45:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | |-BinaryOperator [[ADDR_46:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | |-CallExpr [[ADDR_47:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | `-ImplicitCastExpr [[ADDR_48:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | `-DeclRefExpr [[ADDR_49:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_1]] 'foo' 'int ({{.*}})' +// CHECK-NEXT: | | `-PseudoObjectExpr [[ADDR_50:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | |-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | `-ImplicitCastExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | `-DeclRefExpr [[ADDR_53:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_6]] 'bar' 'int ({{.*}})' +// CHECK-NEXT: | | `-CallExpr [[ADDR_54:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_55:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_11]] 'int ({{.*}})' Function [[ADDR_12]] 'bar[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: | `-PseudoObjectExpr [[ADDR_56:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_57:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_58:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_59:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'baz' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_60:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_61:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_19]] 'int ({{.*}})' Function [[ADDR_20]] 'baz[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_62:0x[a-z0-9]*]] line:53:5 used implicit2 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_63:0x[a-z0-9]*]] +// CHECK-NEXT: | |-DeclStmt [[ADDR_64:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-UsingDirectiveDecl [[ADDR_65:0x[a-z0-9]*]] col:19 Namespace [[ADDR_0]] 'A' +// CHECK-NEXT: | |-DeclStmt [[ADDR_66:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-UsingDirectiveDecl [[ADDR_67:0x[a-z0-9]*]] col:19 Namespace [[ADDR_5]] 'B' +// CHECK-NEXT: | `-ReturnStmt [[ADDR_68:0x[a-z0-9]*]] +// CHECK-NEXT: | `-BinaryOperator [[ADDR_69:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | |-PseudoObjectExpr [[ADDR_70:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | |-CallExpr [[ADDR_71:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | `-ImplicitCastExpr [[ADDR_72:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | `-DeclRefExpr [[ADDR_73:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_6]] 'bar' 'int ({{.*}})' +// CHECK-NEXT: | | `-CallExpr [[ADDR_74:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_75:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_11]] 'int ({{.*}})' Function [[ADDR_12]] 'bar[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: | `-PseudoObjectExpr [[ADDR_76:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_77:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_78:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_79:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'baz' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_80:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_81:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_19]] 'int ({{.*}})' Function [[ADDR_20]] 'baz[implementation={vendor(llvm)}]' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_82:0x[a-z0-9]*]] line:61:5 main 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_83:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_84:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_85:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-CallExpr [[ADDR_86:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_87:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_88:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_42]] 'explicit1' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_89:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_90:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_91:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_62]] 'implicit2' 'int ({{.*}})' From llvm-branch-commits at lists.llvm.org Fri Apr 3 23:58:46 2020 From: llvm-branch-commits at lists.llvm.org (Johannes Doerfert via llvm-branch-commits) Date: Fri, 03 Apr 2020 23:58:46 -0700 (PDT) Subject: [llvm-branch-commits] [clang] 544ffda - [WIP][OpenMP] Do not crash if no auxiliary target was given Message-ID: <5e883026.1c69fb81.a790b.03d2@mx.google.com> Author: Johannes Doerfert Date: 2020-04-04T01:56:18-05:00 New Revision: 544ffda5ec21371d3fdace2c11378993e56f6b5b URL: https://github.com/llvm/llvm-project/commit/544ffda5ec21371d3fdace2c11378993e56f6b5b DIFF: https://github.com/llvm/llvm-project/commit/544ffda5ec21371d3fdace2c11378993e56f6b5b.diff LOG: [WIP][OpenMP] Do not crash if no auxiliary target was given Added: Modified: clang/lib/AST/ASTContext.cpp clang/lib/AST/ItaniumMangle.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 06513fc4b234..bafbfde01e26 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1652,11 +1652,11 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { case BuiltinType::Float: return Target->getFloatFormat(); case BuiltinType::Double: return Target->getDoubleFormat(); case BuiltinType::LongDouble: - if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice) + if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && AuxTarget) return AuxTarget->getLongDoubleFormat(); return Target->getLongDoubleFormat(); case BuiltinType::Float128: - if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice) + if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && AuxTarget) return AuxTarget->getFloat128Format(); return Target->getFloat128Format(); } @@ -2032,7 +2032,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { case BuiltinType::Float16: case BuiltinType::Half: if (Target->hasFloat16Type() || !getLangOpts().OpenMP || - !getLangOpts().OpenMPIsDevice) { + !getLangOpts().OpenMPIsDevice || !AuxTarget) { Width = Target->getHalfWidth(); Align = Target->getHalfAlign(); } else { @@ -2051,7 +2051,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Align = Target->getDoubleAlign(); break; case BuiltinType::LongDouble: - if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && + if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && AuxTarget && (Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() || Target->getLongDoubleAlign() != AuxTarget->getLongDoubleAlign())) { Width = AuxTarget->getLongDoubleWidth(); @@ -2063,7 +2063,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { break; case BuiltinType::Float128: if (Target->hasFloat128Type() || !getLangOpts().OpenMP || - !getLangOpts().OpenMPIsDevice) { + !getLangOpts().OpenMPIsDevice || !AuxTarget) { Width = Target->getFloat128Width(); Align = Target->getFloat128Align(); } else { diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index cb7bd61574ef..1b32738212e3 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2731,18 +2731,22 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { Out << 'd'; break; case BuiltinType::LongDouble: { - const TargetInfo *TI = getASTContext().getLangOpts().OpenMP && - getASTContext().getLangOpts().OpenMPIsDevice - ? getASTContext().getAuxTargetInfo() - : &getASTContext().getTargetInfo(); + const TargetInfo *TI = + getASTContext().getLangOpts().OpenMP && + getASTContext().getLangOpts().OpenMPIsDevice && + getASTContext().getAuxTargetInfo() + ? getASTContext().getAuxTargetInfo() + : &getASTContext().getTargetInfo(); Out << TI->getLongDoubleMangling(); break; } case BuiltinType::Float128: { - const TargetInfo *TI = getASTContext().getLangOpts().OpenMP && - getASTContext().getLangOpts().OpenMPIsDevice - ? getASTContext().getAuxTargetInfo() - : &getASTContext().getTargetInfo(); + const TargetInfo *TI = + getASTContext().getLangOpts().OpenMP && + getASTContext().getLangOpts().OpenMPIsDevice && + getASTContext().getAuxTargetInfo() + ? getASTContext().getAuxTargetInfo() + : &getASTContext().getTargetInfo(); Out << TI->getFloat128Mangling(); break; } From llvm-branch-commits at lists.llvm.org Fri Apr 3 23:58:48 2020 From: llvm-branch-commits at lists.llvm.org (Johannes Doerfert via llvm-branch-commits) Date: Fri, 03 Apr 2020 23:58:48 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] ddd8783 - [OpenMP] Add match_{all, any, none} declare variant selector extensions. Message-ID: <5e883028.1c69fb81.933ef.2192@mx.google.com> Author: Johannes Doerfert Date: 2020-04-04T01:56:19-05:00 New Revision: ddd878365b31d31264cb46fdd4e2f0f708ab8548 URL: https://github.com/llvm/llvm-project/commit/ddd878365b31d31264cb46fdd4e2f0f708ab8548 DIFF: https://github.com/llvm/llvm-project/commit/ddd878365b31d31264cb46fdd4e2f0f708ab8548.diff LOG: [OpenMP] Add match_{all,any,none} declare variant selector extensions. Summary: By default, all traits in the OpenMP context selector have to match for it to be acceptable. Though, we sometimes want a single property out of multiple to match (=any) or no match at all (=none). We offer these choices as extensions via `implementation={extension(match_{all,any,none})}` to the user. The choice will affect the entire context selector not only the traits following the match property. The first user will be D75788. There we can replace ``` #pragma omp begin declare variant match(device={arch(nvptx64)}) #define __CUDA__ #include <__clang_cuda_cmath.h> // TODO: Hack until we support an extension to the match clause that allows "or". #undef __CLANG_CUDA_CMATH_H__ #undef __CUDA__ #pragma omp end declare variant #pragma omp begin declare variant match(device={arch(nvptx)}) #define __CUDA__ #include <__clang_cuda_cmath.h> #undef __CUDA__ #pragma omp end declare variant ``` with the much simpler ``` #pragma omp begin declare variant match(device={arch(nvptx, nvptx64)}, implementation={extension(match_any)}) #define __CUDA__ #include <__clang_cuda_cmath.h> #undef __CUDA__ #pragma omp end declare variant ``` Reviewers: mikerice, kiranchandramohan, ABataev, RaviNarayanaswamy, gtbercea, grokos, sdmitriev, JonChesterfield, hfinkel, fghanim, aaron.ballman Subscribers: yaxunl, hiraditya, bollu, guansong, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77414 Added: clang/test/AST/ast-dump-openmp-declare-variant-extensions-messages.c clang/test/AST/ast-dump-openmp-declare-variant-extensions.c Modified: clang/include/clang/AST/OpenMPClause.h clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticParseKinds.td clang/lib/AST/OpenMPClause.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/OpenMP/declare_variant_ast_print.c clang/test/OpenMP/declare_variant_messages.c llvm/include/llvm/Frontend/OpenMP/OMPContext.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPContext.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 9f5ff5a85182..f276611e3d0c 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -7229,11 +7229,9 @@ class OMPTraitInfo { /// former is a flat representation the actual main diff erence is that the /// latter uses clang::Expr to store the score/condition while the former is /// independent of clang. Thus, expressions and conditions are evaluated in - /// this method. If \p DeviceSetOnly is true, only the device selector set, if - /// present, is put in \p VMI, otherwise all selector sets are put in \p VMI. + /// this method. void getAsVariantMatchInfo(ASTContext &ASTCtx, - llvm::omp::VariantMatchInfo &VMI, - bool DeviceSetOnly) const; + llvm::omp::VariantMatchInfo &VMI) const; /// Return a string representation identifying this context selector. std::string getMangledName() const; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index fb1c82a80115..9a35bea6e58e 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3394,6 +3394,20 @@ where clause is one of the following: and where `variant-func-id` is the name of a function variant that is either a base language identifier or, for C++, a template-id. +Clang provides the following context selector extensions, used via `implementation={extension(EXTENSION)}`: + + .. code-block:: none + + match_all + match_any + match_none + +The match extensions change when the *entire* context selector is considered a +match for an OpenMP context. The default is `all`, with `none` no trait in the +selector is allowed to be in the OpenMP context, with `any` a single trait in +both the selector and OpenMP context is sufficient. Only a single match +extension trait is allowed per context selector. + }]; } diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index f3741531c8b5..a1311d7776c6 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1313,6 +1313,8 @@ def warn_omp_ctx_incompatible_score_for_property def warn_omp_more_one_device_type_clause : Warning<"more than one 'device_type' clause is specified">, InGroup; +def err_omp_variant_ctx_second_match_extension : Error< + "only a single match extension allowed per OpenMP context selector">; // Pragma loop support. def err_pragma_loop_missing_argument : Error< diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 0fdbec634103..893656b4c34c 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1883,11 +1883,8 @@ void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) { } void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx, - VariantMatchInfo &VMI, - bool DeviceSetOnly) const { + VariantMatchInfo &VMI) const { for (const OMPTraitSet &Set : Sets) { - if (DeviceSetOnly && Set.Kind != TraitSet::device) - continue; for (const OMPTraitSelector &Selector : Set.Selectors) { // User conditions are special as we evaluate the condition here. diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 4da1b4146af3..2dd58f71106c 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -935,6 +935,41 @@ void Parser::parseOMPTraitPropertyKind( << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector); } +static void checkExtensionProperty(Parser &P, SourceLocation Loc, + OMPTraitInfo::OMPTraitProperty &TIProperty, + OMPTraitInfo::OMPTraitSelector &TISelector, + llvm::StringMap &Seen) { + assert(TISelector.Kind == + llvm::omp::TraitSelector::implementation_extension && + "Only for extension properties, e.g., " + "`implementation={extension(PROPERTY)}`"); + + if (TIProperty.Kind == + llvm::omp::TraitProperty::implementation_extension_match_all || + TIProperty.Kind == + llvm::omp::TraitProperty::implementation_extension_match_any || + TIProperty.Kind == + llvm::omp::TraitProperty::implementation_extension_match_none) { + for (OMPTraitInfo::OMPTraitProperty &SeenProp : TISelector.Properties) + if (SeenProp.Kind == + llvm::omp::TraitProperty::implementation_extension_match_all || + SeenProp.Kind == + llvm::omp::TraitProperty::implementation_extension_match_any || + SeenProp.Kind == + llvm::omp::TraitProperty::implementation_extension_match_none) { + P.Diag(Loc, diag::err_omp_variant_ctx_second_match_extension); + StringRef SeenName = + llvm::omp::getOpenMPContextTraitPropertyName(SeenProp.Kind); + SourceLocation SeenLoc = Seen[SeenName]; + P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here) + << CONTEXT_TRAIT_LVL << SeenName; + } + return; + } + + llvm_unreachable("Unknown extension property!"); +} + void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector, llvm::omp::TraitSet Set, llvm::StringMap &Seen) { @@ -955,6 +990,10 @@ void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector, if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.Kind, TISelector.Kind, Set)) { + if (TISelector.Kind == llvm::omp::TraitSelector::implementation_extension) + checkExtensionProperty(*this, Tok.getLocation(), TIProperty, TISelector, + Seen); + // If we make it here the property, selector, set, score, condition, ... are // all valid (or have been corrected). Thus we can record the property. TISelector.Properties.push_back(TIProperty); @@ -1783,11 +1822,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( VariantMatchInfo VMI; ASTContext &ASTCtx = Actions.getASTContext(); - TI.getAsVariantMatchInfo(ASTCtx, VMI, /* DeviceSetOnly */ true); + TI.getAsVariantMatchInfo(ASTCtx, VMI); OMPContext OMPCtx(ASTCtx.getLangOpts().OpenMPIsDevice, ASTCtx.getTargetInfo().getTriple()); - if (isVariantApplicableInContext(VMI, OMPCtx)) { + if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) { Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI); break; } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 52687888af2d..bb63db31d042 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5674,8 +5674,8 @@ ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, VariantMatchInfo VMI; OMPTraitInfo &TI = A->getTraitInfo(); - TI.getAsVariantMatchInfo(Context, VMI, /* DeviceSetOnly */ false); - if (!isVariantApplicableInContext(VMI, OMPCtx)) + TI.getAsVariantMatchInfo(Context, VMI); + if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false)) continue; VMIs.push_back(VMI); diff --git a/clang/test/AST/ast-dump-openmp-declare-variant-extensions-messages.c b/clang/test/AST/ast-dump-openmp-declare-variant-extensions-messages.c new file mode 100644 index 000000000000..ee4d18f76c92 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-declare-variant-extensions-messages.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify %s -x c++ + +int dummy() { return 1; } + +#pragma omp declare variant(dummy) match(implementation={extension(match_any,match_all)}, device={kind(cpu, gpu)}) // expected-error {{only a single match extension allowed per OpenMP context selector}} expected-note {{the previous context property 'match_any' used here}} +int base1() { return 2; } + +#pragma omp declare variant(dummy) match(implementation={extension(match_none,match_none)}, device={kind(gpu, fpga)}) // expected-warning {{the context property 'match_none' was used already in the same 'omp declare variant' directive; property ignored}} expected-note {{the previous context property 'match_none' used here}} expected-note {{the ignored property spans until here}} +int base2() { return 3; } + +#pragma omp declare variant(dummy) match(implementation={vendor(pgi), extension(match_none,match_any)}, device={kind(cpu, gpu)}) // expected-error {{only a single match extension allowed per OpenMP context selector}} expected-note {{the previous context property 'match_none' used here}} +int base3() { return 4; } + + +int test() { + return base1() + base2() + base3(); +} diff --git a/clang/test/AST/ast-dump-openmp-declare-variant-extensions.c b/clang/test/AST/ast-dump-openmp-declare-variant-extensions.c new file mode 100644 index 000000000000..9de53965a114 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-declare-variant-extensions.c @@ -0,0 +1,343 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics + +int picked1() { return 0; } +int picked2() { return 0; } +int picked3(); +int picked4(); +int picked5() { return 0; } +int picked6() { return 0; } +int picked7() { return 0; } +int not_picked1() { return 1; } +int not_picked2() { return 2; } +int not_picked3(); +int not_picked4(); +int not_picked5(); +int not_picked6(); + +#pragma omp declare variant(picked1) match(implementation={extension(match_any)}, device={kind(cpu, gpu)}) +int base1() { return 3; } + +#pragma omp declare variant(picked2) match(implementation={extension(match_none)}, device={kind(gpu, fpga)}) +int base2() { return 4; } + +#pragma omp declare variant(picked3) match(implementation={vendor(pgi), extension(match_any)}, device={kind(cpu, gpu)}) +int base3() { return 5; } + +#pragma omp declare variant(picked4) match(user={condition(0)}, implementation={extension(match_none)}, device={kind(gpu, fpga)}) +int base4() { return 6; } + +#pragma omp declare variant(picked5) match(user={condition(1)}, implementation={extension(match_all)}, device={kind(cpu)}) +int base5() { return 7; } + +#pragma omp declare variant(not_picked1) match(implementation={extension(match_any)}, device={kind(gpu, fpga)}) +int base6() { return 0; } + +#pragma omp declare variant(not_picked2) match(implementation={extension(match_none)}, device={kind(gpu, cpu)}) +int base7() { return 0; } + +#pragma omp declare variant(not_picked3) match(implementation={vendor(llvm), extension(match_any)}, device={kind(fpga, gpu)}) +int base8() { return 0; } + +#pragma omp declare variant(not_picked4) match(user={condition(1)}, implementation={extension(match_none)}, device={kind(gpu, fpga)}) +int base9() { return 0; } + +#pragma omp declare variant(not_picked5) match(user={condition(1)}, implementation={extension(match_all)}, device={kind(cpu, gpu)}) +int base10() { return 0; } + +#pragma omp declare variant(not_picked6) match(implementation={extension(match_any)}) +int base11() { return 0; } + +#pragma omp declare variant(picked6) match(implementation={extension(match_all)}) +int base12() { return 8; } + +#pragma omp declare variant(picked7) match(implementation={extension(match_none)}) +int base13() { return 9; } + +#pragma omp begin declare variant match(implementation={extension(match_any)}, device={kind(cpu, gpu)}) +int overloaded1() { return 0; } +#pragma omp end declare variant + +int overloaded2() { return 1; } +#pragma omp begin declare variant match(implementation={extension(match_none)}, device={kind(fpga, gpu)}) +int overloaded2() { return 0; } +#pragma omp end declare variant + +#pragma omp begin declare variant match(implementation={extension(match_none)}, device={kind(cpu)}) +NOT PARSED +#pragma omp end declare variant + + +int picked3() { return 0; } +int picked4() { return 0; } +int not_picked3() { return 10; } +int not_picked4() { return 11; } +int not_picked5() { return 12; } +int not_picked6() { return 13; } + +int test() { + // Should return 0. + return base1() + base2() + base3() + base4() + base5() + base6() + base7() + + base8() + base9() + base10() + base11() + base12() + base13() + + overloaded1() + overloaded2(); +} + +// 1) All "picked" versions are called but none of the "non_picked" ones is. +// 2) The overloaded functions that return 0 are called. + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:27> col:5 referenced picked1 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 referenced picked2 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_5:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_6:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_7:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_8:0x[a-z0-9]*]] col:5 referenced picked3 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_9:0x[a-z0-9]*]] col:5 referenced picked4 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_10:0x[a-z0-9]*]] col:5 referenced picked5 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_11:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_12:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_13:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] col:5 referenced picked6 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] col:5 referenced picked7 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] col:5 referenced not_picked1 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_25:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_26:0x[a-z0-9]*]] col:5 referenced not_picked2 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_27:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_28:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_29:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: |-FunctionDecl [[ADDR_30:0x[a-z0-9]*]] col:5 referenced not_picked3 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_31:0x[a-z0-9]*]] col:5 referenced not_picked4 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_32:0x[a-z0-9]*]] col:5 referenced not_picked5 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_33:0x[a-z0-9]*]] col:5 referenced not_picked6 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_34:0x[a-z0-9]*]] col:5 used base1 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_35:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_36:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_37:0x[a-z0-9]*]] 'int' 3 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_38:0x[a-z0-9]*]] Implicit implementation={extension(match_any)}, device={kind(cpu, gpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'picked1' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_40:0x[a-z0-9]*]] col:5 used base2 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_41:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_42:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_43:0x[a-z0-9]*]] 'int' 4 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_44:0x[a-z0-9]*]] Implicit implementation={extension(match_none)}, device={kind(gpu, fpga)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_45:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_4]] 'picked2' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_46:0x[a-z0-9]*]] col:5 used base3 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_47:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_48:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_49:0x[a-z0-9]*]] 'int' 5 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_50:0x[a-z0-9]*]] Implicit implementation={vendor(pgi), extension(match_any)}, device={kind(cpu, gpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_51:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_8]] 'picked3' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_52:0x[a-z0-9]*]] col:5 used base4 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_53:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_54:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_55:0x[a-z0-9]*]] 'int' 6 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_56:0x[a-z0-9]*]] Implicit user={condition(0)}, implementation={extension(match_none)}, device={kind(gpu, fpga)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_57:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_9]] 'picked4' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_58:0x[a-z0-9]*]] col:5 used base5 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_59:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_60:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_61:0x[a-z0-9]*]] 'int' 7 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_62:0x[a-z0-9]*]] Implicit user={condition(1)}, implementation={extension(match_all)}, device={kind(cpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_63:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_10]] 'picked5' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_64:0x[a-z0-9]*]] col:5 used base6 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_65:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_66:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_67:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_68:0x[a-z0-9]*]] Implicit implementation={extension(match_any)}, device={kind(gpu, fpga)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_69:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_22]] 'not_picked1' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_70:0x[a-z0-9]*]] col:5 used base7 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_71:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_72:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_73:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_74:0x[a-z0-9]*]] Implicit implementation={extension(match_none)}, device={kind(gpu, cpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_75:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_26]] 'not_picked2' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_76:0x[a-z0-9]*]] col:5 used base8 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_77:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_78:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_79:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_80:0x[a-z0-9]*]] Implicit implementation={vendor(llvm), extension(match_any)}, device={kind(fpga, gpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_81:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_30]] 'not_picked3' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_82:0x[a-z0-9]*]] col:5 used base9 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_83:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_84:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_85:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_86:0x[a-z0-9]*]] Implicit user={condition(1)}, implementation={extension(match_none)}, device={kind(gpu, fpga)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_87:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_31]] 'not_picked4' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_88:0x[a-z0-9]*]] col:5 used base10 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_89:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_90:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_91:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_92:0x[a-z0-9]*]] Implicit user={condition(1)}, implementation={extension(match_all)}, device={kind(cpu, gpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_93:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_32]] 'not_picked5' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_94:0x[a-z0-9]*]] col:5 used base11 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_95:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_96:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_97:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_98:0x[a-z0-9]*]] Implicit implementation={extension(match_any)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_99:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_33]] 'not_picked6' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_100:0x[a-z0-9]*]] col:5 used base12 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_101:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_102:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_103:0x[a-z0-9]*]] 'int' 8 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_104:0x[a-z0-9]*]] Implicit implementation={extension(match_all)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_105:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'picked6' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_106:0x[a-z0-9]*]] col:5 used base13 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_107:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_108:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_109:0x[a-z0-9]*]] 'int' 9 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_110:0x[a-z0-9]*]] Implicit implementation={extension(match_none)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_111:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'picked7' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: |-FunctionDecl [[ADDR_112:0x[a-z0-9]*]] col:5 overloaded1[implementation={extension(match_any)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_113:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_114:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_115:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_116:0x[a-z0-9]*]] col:5 implicit used overloaded1 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_117:0x[a-z0-9]*]] <> Implicit implementation={extension(match_any)}, device={kind(cpu, gpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_118:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_112]] 'overloaded1[implementation={extension(match_any)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_119:0x[a-z0-9]*]] col:5 implicit used overloaded2 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_120:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_121:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_122:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_123:0x[a-z0-9]*]] <> Implicit implementation={extension(match_none)}, device={kind(fpga, gpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_124:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_125:0x[a-z0-9]*]] 'overloaded2[implementation={extension(match_none)}]' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_125]] col:5 overloaded2[implementation={extension(match_none)}] 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_126:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_127:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_128:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_129:0x[a-z0-9]*]] prev [[ADDR_8]] col:5 picked3 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_130:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_131:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_132:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_133:0x[a-z0-9]*]] prev [[ADDR_9]] col:5 picked4 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_134:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_135:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_136:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_137:0x[a-z0-9]*]] prev [[ADDR_30]] col:5 not_picked3 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_138:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_139:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_140:0x[a-z0-9]*]] 'int' 10 +// CHECK-NEXT: |-FunctionDecl [[ADDR_141:0x[a-z0-9]*]] prev [[ADDR_31]] col:5 not_picked4 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_142:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_143:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_144:0x[a-z0-9]*]] 'int' 11 +// CHECK-NEXT: |-FunctionDecl [[ADDR_145:0x[a-z0-9]*]] prev [[ADDR_32]] col:5 not_picked5 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_146:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_147:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_148:0x[a-z0-9]*]] 'int' 12 +// CHECK-NEXT: |-FunctionDecl [[ADDR_149:0x[a-z0-9]*]] prev [[ADDR_33]] col:5 not_picked6 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_150:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_151:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_152:0x[a-z0-9]*]] 'int' 13 +// CHECK-NEXT: `-FunctionDecl [[ADDR_153:0x[a-z0-9]*]] line:79:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_154:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_155:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_156:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-BinaryOperator [[ADDR_157:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | |-BinaryOperator [[ADDR_158:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | |-BinaryOperator [[ADDR_159:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | |-BinaryOperator [[ADDR_160:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | |-BinaryOperator [[ADDR_161:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | | |-BinaryOperator [[ADDR_162:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | | | |-BinaryOperator [[ADDR_163:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | | | | |-BinaryOperator [[ADDR_164:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | | | | | |-BinaryOperator [[ADDR_165:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | | | | | | |-BinaryOperator [[ADDR_166:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | | | | | | | |-BinaryOperator [[ADDR_167:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | | | | | | | | |-BinaryOperator [[ADDR_168:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | | | | | | | | | |-BinaryOperator [[ADDR_169:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | | | | | | | | | | | | | |-PseudoObjectExpr [[ADDR_170:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | | | |-CallExpr [[ADDR_171:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | | | | `-ImplicitCastExpr [[ADDR_172:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | | | | `-DeclRefExpr [[ADDR_173:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_34]] 'base1' 'int ({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | | | `-CallExpr [[ADDR_174:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | | | `-ImplicitCastExpr [[ADDR_175:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | | | `-DeclRefExpr [[ADDR_39]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'picked1' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: | | | | | | | | | | | | | `-PseudoObjectExpr [[ADDR_176:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | | |-CallExpr [[ADDR_177:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | | | `-ImplicitCastExpr [[ADDR_178:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | | | `-DeclRefExpr [[ADDR_179:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_40]] 'base2' 'int ({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | | `-CallExpr [[ADDR_180:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | | `-ImplicitCastExpr [[ADDR_181:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | | `-DeclRefExpr [[ADDR_45]] 'int ({{.*}})' {{.*}}Function [[ADDR_4]] 'picked2' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: | | | | | | | | | | | | `-PseudoObjectExpr [[ADDR_182:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | |-CallExpr [[ADDR_183:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | | `-ImplicitCastExpr [[ADDR_184:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | | `-DeclRefExpr [[ADDR_185:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_46]] 'base3' 'int ({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | `-CallExpr [[ADDR_186:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | `-ImplicitCastExpr [[ADDR_187:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | `-DeclRefExpr [[ADDR_51]] 'int ({{.*}})' {{.*}}Function [[ADDR_8]] 'picked3' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: | | | | | | | | | | | `-PseudoObjectExpr [[ADDR_188:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | |-CallExpr [[ADDR_189:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | | `-ImplicitCastExpr [[ADDR_190:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | | `-DeclRefExpr [[ADDR_191:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_52]] 'base4' 'int ({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | `-CallExpr [[ADDR_192:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | `-ImplicitCastExpr [[ADDR_193:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr [[ADDR_57]] 'int ({{.*}})' {{.*}}Function [[ADDR_9]] 'picked4' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: | | | | | | | | | | `-PseudoObjectExpr [[ADDR_194:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | |-CallExpr [[ADDR_195:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | | `-ImplicitCastExpr [[ADDR_196:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr [[ADDR_197:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_58]] 'base5' 'int ({{.*}})' +// CHECK-NEXT: | | | | | | | | | | `-CallExpr [[ADDR_198:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr [[ADDR_199:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr [[ADDR_63]] 'int ({{.*}})' {{.*}}Function [[ADDR_10]] 'picked5' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: | | | | | | | | | `-CallExpr [[ADDR_200:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr [[ADDR_201:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr [[ADDR_202:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_64]] 'base6' 'int ({{.*}})' +// CHECK-NEXT: | | | | | | | | `-CallExpr [[ADDR_203:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr [[ADDR_204:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | `-DeclRefExpr [[ADDR_205:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_70]] 'base7' 'int ({{.*}})' +// CHECK-NEXT: | | | | | | | `-PseudoObjectExpr [[ADDR_206:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | |-CallExpr [[ADDR_207:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr [[ADDR_208:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | | `-DeclRefExpr [[ADDR_209:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_76]] 'base8' 'int ({{.*}})' +// CHECK-NEXT: | | | | | | | `-CallExpr [[ADDR_210:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr [[ADDR_211:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | | `-DeclRefExpr [[ADDR_81]] 'int ({{.*}})' {{.*}}Function [[ADDR_30]] 'not_picked3' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: | | | | | | `-CallExpr [[ADDR_212:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | | `-ImplicitCastExpr [[ADDR_213:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | | `-DeclRefExpr [[ADDR_214:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_82]] 'base9' 'int ({{.*}})' +// CHECK-NEXT: | | | | | `-CallExpr [[ADDR_215:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | | `-ImplicitCastExpr [[ADDR_216:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | | `-DeclRefExpr [[ADDR_217:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_88]] 'base10' 'int ({{.*}})' +// CHECK-NEXT: | | | | `-CallExpr [[ADDR_218:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | `-ImplicitCastExpr [[ADDR_219:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | `-DeclRefExpr [[ADDR_220:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_94]] 'base11' 'int ({{.*}})' +// CHECK-NEXT: | | | `-PseudoObjectExpr [[ADDR_221:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | |-CallExpr [[ADDR_222:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | | `-ImplicitCastExpr [[ADDR_223:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | | `-DeclRefExpr [[ADDR_224:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_100]] 'base12' 'int ({{.*}})' +// CHECK-NEXT: | | | `-CallExpr [[ADDR_225:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | `-ImplicitCastExpr [[ADDR_226:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | `-DeclRefExpr [[ADDR_105]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'picked6' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: | | `-PseudoObjectExpr [[ADDR_227:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | |-CallExpr [[ADDR_228:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | | `-ImplicitCastExpr [[ADDR_229:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | | `-DeclRefExpr [[ADDR_230:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_106]] 'base13' 'int ({{.*}})' +// CHECK-NEXT: | | `-CallExpr [[ADDR_231:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_232:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_111]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'picked7' 'int ({{.*}})' non_odr_use_unevaluated +// CHECK-NEXT: | `-PseudoObjectExpr [[ADDR_233:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_234:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_235:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_236:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_116]] 'overloaded1' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_237:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_238:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_118]] 'int ({{.*}})' Function [[ADDR_112]] 'overloaded1[implementation={extension(match_any)}]' 'int ({{.*}})' +// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_239:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: |-CallExpr [[ADDR_240:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_241:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_242:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_119]] 'overloaded2' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_243:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_244:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_124]] 'int ({{.*}})' Function [[ADDR_125]] 'overloaded2[implementation={extension(match_none)}]' 'int ({{.*}})' diff --git a/clang/test/OpenMP/declare_variant_ast_print.c b/clang/test/OpenMP/declare_variant_ast_print.c index 515d3167627c..5184557a8071 100644 --- a/clang/test/OpenMP/declare_variant_ast_print.c +++ b/clang/test/OpenMP/declare_variant_ast_print.c @@ -14,9 +14,15 @@ int foo(void); #pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm, xxx, ibm)}, device={kind(cpu, nohost)}) #pragma omp declare variant(foo) match(device={kind(host)}) #pragma omp declare variant(foo) match(device={kind(nohost), xxx}) +#pragma omp declare variant(foo) match(implementation={extension(match_all)}) +#pragma omp declare variant(foo) match(implementation={extension(match_any)}) +#pragma omp declare variant(foo) match(implementation={extension(match_none)}) int bar(void); // CHECK: int foo(); +// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_none)}) +// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_any)}) +// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_all)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(nohost)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(host)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm)}, device={kind(cpu, nohost)}) diff --git a/clang/test/OpenMP/declare_variant_messages.c b/clang/test/OpenMP/declare_variant_messages.c index fc9f5eb32cf2..ecbf022351a7 100644 --- a/clang/test/OpenMP/declare_variant_messages.c +++ b/clang/test/OpenMP/declare_variant_messages.c @@ -46,7 +46,7 @@ int foo(void); #pragma omp declare variant(foo) match(device={kind(score(foo()) ibm)}) // expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('foo()'); score ignored}} expected-warning {{'ibm' is not a valid context property for the context selector 'kind' and the context set 'device'; property ignored}} expected-note {{try 'match(implementation={vendor(ibm)})'}} expected-note {{the ignored property spans until here}} #pragma omp declare variant(foo) match(device={kind(score(5): host), kind(llvm)}) // expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('5'); score ignored}} expected-warning {{the context selector 'kind' was used already in the same 'omp declare variant' directive; selector ignored}} expected-note {{the previous context selector 'kind' used here}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foo) match(device={kind(score(5): nohost), vendor(llvm)}) // expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('5'); score ignored}} expected-warning {{the context selector 'vendor' is not valid for the context set 'device'; selector ignored}} expected-note {{the context selector 'vendor' can be nested in the context set 'implementation'; try 'match(implementation={vendor(property)})'}} expected-note {{the ignored selector spans until here}} -#pragma omp declare variant(foo) match(implementation={extension("aaa")}) // expected-warning {{'aaa' is not a valid context property for the context selector 'extension' and the context set 'implementation'; property ignored}} expected-note {{context property options are: }} expected-note {{the ignored property spans until here}} +#pragma omp declare variant(foo) match(implementation={extension("aaa")}) // expected-warning {{'aaa' is not a valid context property for the context selector 'extension' and the context set 'implementation'; property ignored}} expected-note {{context property options are: 'match_all' 'match_any' 'match_none'}} expected-note {{the ignored property spans until here}} int bar(void); #pragma omp declare variant(foo) match(implementation = {vendor(score(foo) :llvm)}) // expected-warning {{score expressions in the OpenMP context selector need to be constant; foo is not and will be ignored}} diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPContext.h b/llvm/include/llvm/Frontend/OpenMP/OMPContext.h index 0a9d9c277d99..1a42d189db44 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPContext.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPContext.h @@ -154,9 +154,12 @@ struct OMPContext { }; /// Return true if \p VMI is applicable in \p Ctx, that is, all traits required -/// by \p VMI are available in the OpenMP context \p Ctx. +/// by \p VMI are available in the OpenMP context \p Ctx. If \p DeviceSetOnly is +/// true, only the device selector set, if present, are checked. Note that we +/// still honor extension traits provided by the user. bool isVariantApplicableInContext(const VariantMatchInfo &VMI, - const OMPContext &Ctx); + const OMPContext &Ctx, + bool DeviceSetOnly = false); /// Return the index (into \p VMIs) of the variant with the highest score /// from the ones applicble in \p Ctx. See llvm::isVariantApplicableInContext. diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index 7ac614e99201..1a82d772d26a 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -664,6 +664,9 @@ __OMP_TRAIT_PROPERTY(implementation, vendor, ti) __OMP_TRAIT_PROPERTY(implementation, vendor, unknown) __OMP_TRAIT_SELECTOR(implementation, extension, true) +__OMP_TRAIT_PROPERTY(implementation, extension, match_all) +__OMP_TRAIT_PROPERTY(implementation, extension, match_any) +__OMP_TRAIT_PROPERTY(implementation, extension, match_none) __OMP_TRAIT_SET(user) diff --git a/llvm/lib/Frontend/OpenMP/OMPContext.cpp b/llvm/lib/Frontend/OpenMP/OMPContext.cpp index dd3292ab776e..6d2cf41f904c 100644 --- a/llvm/lib/Frontend/OpenMP/OMPContext.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPContext.cpp @@ -137,52 +137,119 @@ static bool isStrictSubset(const VariantMatchInfo &VMI0, static int isVariantApplicableInContextHelper( const VariantMatchInfo &VMI, const OMPContext &Ctx, - SmallVectorImpl *ConstructMatches) { + SmallVectorImpl *ConstructMatches, bool DeviceSetOnly) { + + // The match kind determines if we need to match all traits, any of the + // traits, or none of the traits for it to be an applicable context. + enum MatchKind { MK_ALL, MK_ANY, MK_NONE }; + + MatchKind MK = MK_ALL; + // Determine the match kind the user wants, "all" is the default and provided + // to the user only for completeness. + if (VMI.RequiredTraits.test( + unsigned(TraitProperty::implementation_extension_match_any))) + MK = MK_ANY; + if (VMI.RequiredTraits.test( + unsigned(TraitProperty::implementation_extension_match_none))) + MK = MK_NONE; + + // Helper to deal with a single property that was (not) found in the OpenMP + // context based on the match kind selected by the user via + // `implementation={extensions(match_[all,any,none])}' + auto HandleTrait = [MK](TraitProperty Property, + bool WasFound) -> Optional /* Result */ { + // For kind "any" a single match is enough but we ignore non-matched properties. + if (MK == MK_ANY) { + if (WasFound) + return true; + return None; + } + + // In "all" or "none" mode we accept a matching or non-matching property + // respectively and move on. We are not done yet! + if ((WasFound && MK == MK_ALL) || (!WasFound && MK == MK_NONE)) + return None; + + // We missed a property, provide some debug output and indicate failure. + LLVM_DEBUG({ + if (MK == MK_ALL) + dbgs() << "[" << DEBUG_TYPE << "] Property " + << getOpenMPContextTraitPropertyName(Property) + << " was not in the OpenMP context but match kind is all.\n"; + if (MK == MK_NONE) + dbgs() << "[" << DEBUG_TYPE << "] Property " + << getOpenMPContextTraitPropertyName(Property) + << " was in the OpenMP context but match kind is none.\n"; + }); + return false; + }; for (unsigned Bit : VMI.RequiredTraits.set_bits()) { TraitProperty Property = TraitProperty(Bit); + if (DeviceSetOnly && + getOpenMPContextTraitSetForProperty(Property) != TraitSet::device) + continue; + + // So far all extensions are handled elsewhere, we skip them here as they + // are not part of the OpenMP context. + if (getOpenMPContextTraitSelectorForProperty(Property) == + TraitSelector::implementation_extension) + continue; bool IsActiveTrait = Ctx.ActiveTraits.test(unsigned(Property)); - if (!IsActiveTrait) { - LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] Property " - << getOpenMPContextTraitPropertyName(Property) - << " was not in the OpenMP context.\n"); - return false; - } + Optional Result = HandleTrait(Property, IsActiveTrait); + if (Result.hasValue()) + return Result.getValue(); } - // We could use isSubset here but we also want to record the match locations. - unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size(); - for (TraitProperty Property : VMI.ConstructTraits) { - assert(getOpenMPContextTraitSetForProperty(Property) == - TraitSet::construct && - "Variant context is ill-formed!"); - - // Verify the nesting. - bool FoundInOrder = false; - while (!FoundInOrder && ConstructIdx != NoConstructTraits) - FoundInOrder = (Ctx.ConstructTraits[ConstructIdx++] == Property); - if (ConstructMatches) - ConstructMatches->push_back(ConstructIdx - 1); - - if (!FoundInOrder) { - LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] Construct property " - << getOpenMPContextTraitPropertyName(Property) - << " was not nested properly.\n"); - return false; + if (!DeviceSetOnly) { + // We could use isSubset here but we also want to record the match + // locations. + unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size(); + for (TraitProperty Property : VMI.ConstructTraits) { + assert(getOpenMPContextTraitSetForProperty(Property) == + TraitSet::construct && + "Variant context is ill-formed!"); + + // Verify the nesting. + bool FoundInOrder = false; + while (!FoundInOrder && ConstructIdx != NoConstructTraits) + FoundInOrder = (Ctx.ConstructTraits[ConstructIdx++] == Property); + if (ConstructMatches) + ConstructMatches->push_back(ConstructIdx - 1); + + Optional Result = HandleTrait(Property, FoundInOrder); + if (Result.hasValue()) + return Result.getValue(); + + if (!FoundInOrder) { + LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] Construct property " + << getOpenMPContextTraitPropertyName(Property) + << " was not nested properly.\n"); + return false; + } + + // TODO: Verify SIMD } - // TODO: Verify SIMD + assert(isSubset(VMI.ConstructTraits, Ctx.ConstructTraits) && + "Broken invariant!"); + } + + if (MK == MK_ANY) { + LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE + << "] None of the properties was in the OpenMP context " + "but match kind is any.\n"); + return false; } - assert(isSubset(VMI.ConstructTraits, Ctx.ConstructTraits) && - "Broken invariant!"); return true; } bool llvm::omp::isVariantApplicableInContext(const VariantMatchInfo &VMI, - const OMPContext &Ctx) { - return isVariantApplicableInContextHelper(VMI, Ctx, nullptr); + const OMPContext &Ctx, + bool DeviceSetOnly) { + return isVariantApplicableInContextHelper(VMI, Ctx, nullptr, DeviceSetOnly); } static APInt getVariantMatchScore(const VariantMatchInfo &VMI, @@ -267,7 +334,8 @@ int llvm::omp::getBestVariantMatchForContext( SmallVector ConstructMatches; // If the variant is not applicable its not the best. - if (!isVariantApplicableInContextHelper(VMI, Ctx, &ConstructMatches)) + if (!isVariantApplicableInContextHelper(VMI, Ctx, &ConstructMatches, + /* DeviceSetOnly */ false)) continue; // Check if its clearly not the best. APInt Score = getVariantMatchScore(VMI, Ctx, ConstructMatches); From llvm-branch-commits at lists.llvm.org Fri Apr 3 23:58:51 2020 From: llvm-branch-commits at lists.llvm.org (Johannes Doerfert via llvm-branch-commits) Date: Fri, 03 Apr 2020 23:58:51 -0700 (PDT) Subject: [llvm-branch-commits] [clang] 06aecc7 - [OpenMP] Provide math functions in OpenMP device code via OpenMP variants Message-ID: <5e88302b.1c69fb81.0c9f.267e@mx.google.com> Author: Johannes Doerfert Date: 2020-04-04T01:56:19-05:00 New Revision: 06aecc71870f2c65d35614d74e4b8701fac2919e URL: https://github.com/llvm/llvm-project/commit/06aecc71870f2c65d35614d74e4b8701fac2919e DIFF: https://github.com/llvm/llvm-project/commit/06aecc71870f2c65d35614d74e4b8701fac2919e.diff LOG: [OpenMP] Provide math functions in OpenMP device code via OpenMP variants Summary: For OpenMP target regions to piggy back on the CUDA/AMDGPU/... implementation of math functions, we include the appropriate definitions inside of an `omp begin/end declare variant match(device={arch(nvptx)})` scope. This way, the vendor specific math functions will become specialized versions of the system math functions. When a system math function is called and specialized version is available the selection logic introduced in D75779 instead call the specialized version. In contrast to the code path we used so far, the system header is actually included. This means functions without specialized versions are available and so are macro definitions. This should address PR42061, PR42798, and PR42799. Reviewers: kiranchandramohan, ABataev, RaviNarayanaswamy, gtbercea, grokos, sdmitriev, JonChesterfield, hfinkel, fghanim, aaron.ballman Subscribers: tpr, tra, mgorny, bollu, guansong, openmp-commits, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D75788 Added: clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h clang/lib/Headers/openmp_wrappers/time.h clang/test/Headers/Inputs/include/climits clang/test/Headers/nvptx_device_math_complex.c clang/test/Headers/nvptx_device_math_macro.cpp clang/test/Headers/nvptx_device_math_modf.cpp clang/test/Headers/nvptx_device_math_sin.c clang/test/Headers/nvptx_device_math_sin.cpp clang/test/Headers/nvptx_device_math_sin_cos.cpp clang/test/Headers/nvptx_device_math_sincos.cpp Modified: clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Headers/CMakeLists.txt clang/lib/Headers/__clang_cuda_cmath.h clang/lib/Headers/__clang_cuda_device_functions.h clang/lib/Headers/__clang_cuda_math.h clang/lib/Headers/__clang_cuda_math_forward_declares.h clang/lib/Headers/openmp_wrappers/cmath clang/lib/Headers/openmp_wrappers/math.h clang/test/Headers/Inputs/include/cmath clang/test/Headers/Inputs/include/cstdlib clang/test/Headers/Inputs/include/math.h clang/test/Headers/Inputs/include/stdlib.h clang/test/Headers/nvptx_device_cmath_functions.c clang/test/Headers/nvptx_device_cmath_functions.cpp clang/test/Headers/nvptx_device_cmath_functions_cxx17.cpp clang/test/Headers/nvptx_device_math_functions.c clang/test/Headers/nvptx_device_math_functions.cpp clang/test/Headers/nvptx_device_math_functions_cxx17.cpp Removed: clang/lib/Headers/openmp_wrappers/__clang_openmp_math.h clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h ################################################################################ diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 4d825301be41..2b368131f5cc 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1216,7 +1216,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, } CmdArgs.push_back("-include"); - CmdArgs.push_back("__clang_openmp_math_declares.h"); + CmdArgs.push_back("__clang_openmp_device_functions.h"); } // Add -i* options, and automatically translate to diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 6851957600e0..d6c8ed5e1fc6 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -145,8 +145,7 @@ set(ppc_wrapper_files set(openmp_wrapper_files openmp_wrappers/math.h openmp_wrappers/cmath - openmp_wrappers/__clang_openmp_math.h - openmp_wrappers/__clang_openmp_math_declares.h + openmp_wrappers/__clang_openmp_device_functions.h openmp_wrappers/new ) diff --git a/clang/lib/Headers/__clang_cuda_cmath.h b/clang/lib/Headers/__clang_cuda_cmath.h index 834a2e3fd134..d0a4aa122efc 100644 --- a/clang/lib/Headers/__clang_cuda_cmath.h +++ b/clang/lib/Headers/__clang_cuda_cmath.h @@ -12,7 +12,9 @@ #error "This file is for CUDA compilation only." #endif +#ifndef _OPENMP #include +#endif // CUDA lets us use various std math functions on the device side. This file // works in concert with __clang_cuda_math_forward_declares.h to make this work. @@ -31,31 +33,15 @@ // std covers all of the known knowns. #ifdef _OPENMP -#define __DEVICE__ static __attribute__((always_inline)) +#define __DEVICE__ static constexpr __attribute__((always_inline, nothrow)) #else #define __DEVICE__ static __device__ __inline__ __attribute__((always_inline)) #endif -// For C++ 17 we need to include noexcept attribute to be compatible -// with the header-defined version. This may be removed once -// variant is supported. -#if defined(_OPENMP) && defined(__cplusplus) && __cplusplus >= 201703L -#define __NOEXCEPT noexcept -#else -#define __NOEXCEPT -#endif - -#if !(defined(_OPENMP) && defined(__cplusplus)) __DEVICE__ long long abs(long long __n) { return ::llabs(__n); } __DEVICE__ long abs(long __n) { return ::labs(__n); } __DEVICE__ float abs(float __x) { return ::fabsf(__x); } __DEVICE__ double abs(double __x) { return ::fabs(__x); } -#endif -// TODO: remove once variat is supported. -#if defined(_OPENMP) && defined(__cplusplus) -__DEVICE__ const float abs(const float __x) { return ::fabsf((float)__x); } -__DEVICE__ const double abs(const double __x) { return ::fabs((double)__x); } -#endif __DEVICE__ float acos(float __x) { return ::acosf(__x); } __DEVICE__ float asin(float __x) { return ::asinf(__x); } __DEVICE__ float atan(float __x) { return ::atanf(__x); } @@ -64,11 +50,9 @@ __DEVICE__ float ceil(float __x) { return ::ceilf(__x); } __DEVICE__ float cos(float __x) { return ::cosf(__x); } __DEVICE__ float cosh(float __x) { return ::coshf(__x); } __DEVICE__ float exp(float __x) { return ::expf(__x); } -__DEVICE__ float fabs(float __x) __NOEXCEPT { return ::fabsf(__x); } +__DEVICE__ float fabs(float __x) { return ::fabsf(__x); } __DEVICE__ float floor(float __x) { return ::floorf(__x); } __DEVICE__ float fmod(float __x, float __y) { return ::fmodf(__x, __y); } -// TODO: remove when variant is supported -#ifndef _OPENMP __DEVICE__ int fpclassify(float __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); @@ -77,7 +61,6 @@ __DEVICE__ int fpclassify(double __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } -#endif __DEVICE__ float frexp(float __arg, int *__exp) { return ::frexpf(__arg, __exp); } @@ -161,6 +144,8 @@ __DEVICE__ float tanh(float __x) { return ::tanhf(__x); } // libdevice doesn't provide an implementation, and we don't want to be in the // business of implementing tricky libm functions in this header. +#ifndef _OPENMP + // Now we've defined everything we promised we'd define in // __clang_cuda_math_forward_declares.h. We need to do two additional things to // fix up our math functions. @@ -457,10 +442,7 @@ using ::remainderf; using ::remquof; using ::rintf; using ::roundf; -// TODO: remove once variant is supported -#ifndef _OPENMP using ::scalblnf; -#endif using ::scalbnf; using ::sinf; using ::sinhf; @@ -479,7 +461,8 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif -#undef __NOEXCEPT +#endif // _OPENMP + #undef __DEVICE__ #endif diff --git a/clang/lib/Headers/__clang_cuda_device_functions.h b/clang/lib/Headers/__clang_cuda_device_functions.h index d15f6b61d6ef..effa42a38b76 100644 --- a/clang/lib/Headers/__clang_cuda_device_functions.h +++ b/clang/lib/Headers/__clang_cuda_device_functions.h @@ -21,7 +21,7 @@ // functions and __forceinline__ helps inlining these wrappers at -O1. #pragma push_macro("__DEVICE__") #ifdef _OPENMP -#define __DEVICE__ static __attribute__((always_inline)) +#define __DEVICE__ static __attribute__((always_inline, nothrow)) #else #define __DEVICE__ static __device__ __forceinline__ #endif @@ -33,7 +33,7 @@ __DEVICE__ unsigned int __brev(unsigned int __a) { return __nv_brev(__a); } __DEVICE__ unsigned long long __brevll(unsigned long long __a) { return __nv_brevll(__a); } -#if defined(__cplusplus) +#if !defined(_OPENMP) && defined(__cplusplus) __DEVICE__ void __brkpt() { asm volatile("brkpt;"); } __DEVICE__ void __brkpt(int __a) { __brkpt(); } #else diff --git a/clang/lib/Headers/__clang_cuda_math.h b/clang/lib/Headers/__clang_cuda_math.h index 7956135bfad5..ec56ac233936 100644 --- a/clang/lib/Headers/__clang_cuda_math.h +++ b/clang/lib/Headers/__clang_cuda_math.h @@ -23,11 +23,29 @@ // functions and __forceinline__ helps inlining these wrappers at -O1. #pragma push_macro("__DEVICE__") #ifdef _OPENMP -#define __DEVICE__ static __inline__ __attribute__((always_inline)) +#if defined(__cplusplus) +#define __DEVICE__ static constexpr __attribute__((always_inline, nothrow)) +#else +#define __DEVICE__ static __attribute__((always_inline, nothrow)) +#endif #else #define __DEVICE__ static __device__ __forceinline__ #endif +// Specialized version of __DEVICE__ for functions with void return type. Needed +// because the OpenMP overlay requires constexpr functions here but prior to +// c++14 void return functions could not be constexpr. +#pragma push_macro("__DEVICE_VOID__") +#ifdef _OPENMP +#if defined(__cplusplus) && __cplusplus >= 201402L +#define __DEVICE_VOID__ static constexpr __attribute__((always_inline, nothrow)) +#else +#define __DEVICE_VOID__ static __attribute__((always_inline, nothrow)) +#endif +#else +#define __DEVICE_VOID__ __DEVICE__ +#endif + // libdevice provides fast low precision and slow full-recision implementations // for some functions. Which one gets selected depends on // __CLANG_CUDA_APPROX_TRANSCENDENTALS__ which gets defined by clang if @@ -39,17 +57,8 @@ #define __FAST_OR_SLOW(fast, slow) slow #endif -// For C++ 17 we need to include noexcept attribute to be compatible -// with the header-defined version. This may be removed once -// variant is supported. -#if defined(_OPENMP) && defined(__cplusplus) && __cplusplus >= 201703L -#define __NOEXCEPT noexcept -#else -#define __NOEXCEPT -#endif - -__DEVICE__ int abs(int __a) __NOEXCEPT { return __nv_abs(__a); } -__DEVICE__ double fabs(double __a) __NOEXCEPT { return __nv_fabs(__a); } +__DEVICE__ int abs(int __a) { return __nv_abs(__a); } +__DEVICE__ double fabs(double __a) { return __nv_fabs(__a); } __DEVICE__ double acos(double __a) { return __nv_acos(__a); } __DEVICE__ float acosf(float __a) { return __nv_acosf(__a); } __DEVICE__ double acosh(double __a) { return __nv_acosh(__a); } @@ -68,6 +77,12 @@ __DEVICE__ double cbrt(double __a) { return __nv_cbrt(__a); } __DEVICE__ float cbrtf(float __a) { return __nv_cbrtf(__a); } __DEVICE__ double ceil(double __a) { return __nv_ceil(__a); } __DEVICE__ float ceilf(float __a) { return __nv_ceilf(__a); } +// For OpenMP we require the user to include as we need to know what +// clock_t is on the system. +#ifndef _OPENMP +__DEVICE__ /* clock_t= */ int clock() { return __nvvm_read_ptx_sreg_clock(); } +#endif +__DEVICE__ long long clock64() { return __nvvm_read_ptx_sreg_clock64(); } __DEVICE__ double copysign(double __a, double __b) { return __nv_copysign(__a, __b); } @@ -104,7 +119,7 @@ __DEVICE__ float exp2f(float __a) { return __nv_exp2f(__a); } __DEVICE__ float expf(float __a) { return __nv_expf(__a); } __DEVICE__ double expm1(double __a) { return __nv_expm1(__a); } __DEVICE__ float expm1f(float __a) { return __nv_expm1f(__a); } -__DEVICE__ float fabsf(float __a) __NOEXCEPT { return __nv_fabsf(__a); } +__DEVICE__ float fabsf(float __a) { return __nv_fabsf(__a); } __DEVICE__ double fdim(double __a, double __b) { return __nv_fdim(__a, __b); } __DEVICE__ float fdimf(float __a, float __b) { return __nv_fdimf(__a, __b); } __DEVICE__ double fdivide(double __a, double __b) { return __a / __b; } @@ -142,15 +157,15 @@ __DEVICE__ float j1f(float __a) { return __nv_j1f(__a); } __DEVICE__ double jn(int __n, double __a) { return __nv_jn(__n, __a); } __DEVICE__ float jnf(int __n, float __a) { return __nv_jnf(__n, __a); } #if defined(__LP64__) || defined(_WIN64) -__DEVICE__ long labs(long __a) __NOEXCEPT { return __nv_llabs(__a); }; +__DEVICE__ long labs(long __a) { return __nv_llabs(__a); }; #else -__DEVICE__ long labs(long __a) __NOEXCEPT { return __nv_abs(__a); }; +__DEVICE__ long labs(long __a) { return __nv_abs(__a); }; #endif __DEVICE__ double ldexp(double __a, int __b) { return __nv_ldexp(__a, __b); } __DEVICE__ float ldexpf(float __a, int __b) { return __nv_ldexpf(__a, __b); } __DEVICE__ double lgamma(double __a) { return __nv_lgamma(__a); } __DEVICE__ float lgammaf(float __a) { return __nv_lgammaf(__a); } -__DEVICE__ long long llabs(long long __a) __NOEXCEPT { return __nv_llabs(__a); } +__DEVICE__ long long llabs(long long __a) { return __nv_llabs(__a); } __DEVICE__ long long llmax(long long __a, long long __b) { return __nv_llmax(__a, __b); } @@ -187,6 +202,16 @@ __DEVICE__ long lround(double __a) { return round(__a); } __DEVICE__ long lroundf(float __a) { return roundf(__a); } #endif __DEVICE__ int max(int __a, int __b) { return __nv_max(__a, __b); } +// These functions shouldn't be declared when including this header +// for math function resolution purposes. +#ifndef _OPENMP +__DEVICE__ void *memcpy(void *__a, const void *__b, size_t __c) { + return __builtin_memcpy(__a, __b, __c); +} +__DEVICE__ void *memset(void *__a, int __b, size_t __c) { + return __builtin_memset(__a, __b, __c); +} +#endif __DEVICE__ int min(int __a, int __b) { return __nv_min(__a, __b); } __DEVICE__ double modf(double __a, double *__b) { return __nv_modf(__a, __b); } __DEVICE__ float modff(float __a, float *__b) { return __nv_modff(__a, __b); } @@ -270,8 +295,6 @@ __DEVICE__ double rsqrt(double __a) { return __nv_rsqrt(__a); } __DEVICE__ float rsqrtf(float __a) { return __nv_rsqrtf(__a); } __DEVICE__ double scalbn(double __a, int __b) { return __nv_scalbn(__a, __b); } __DEVICE__ float scalbnf(float __a, int __b) { return __nv_scalbnf(__a, __b); } -// TODO: remove once variant is supported -#ifndef _OPENMP __DEVICE__ double scalbln(double __a, long __b) { if (__b > INT_MAX) return __a > 0 ? HUGE_VAL : -HUGE_VAL; @@ -286,18 +309,17 @@ __DEVICE__ float scalblnf(float __a, long __b) { return __a > 0 ? 0.f : -0.f; return scalbnf(__a, (int)__b); } -#endif __DEVICE__ double sin(double __a) { return __nv_sin(__a); } -__DEVICE__ void sincos(double __a, double *__s, double *__c) { +__DEVICE_VOID__ void sincos(double __a, double *__s, double *__c) { return __nv_sincos(__a, __s, __c); } -__DEVICE__ void sincosf(float __a, float *__s, float *__c) { +__DEVICE_VOID__ void sincosf(float __a, float *__s, float *__c) { return __FAST_OR_SLOW(__nv_fast_sincosf, __nv_sincosf)(__a, __s, __c); } -__DEVICE__ void sincospi(double __a, double *__s, double *__c) { +__DEVICE_VOID__ void sincospi(double __a, double *__s, double *__c) { return __nv_sincospi(__a, __s, __c); } -__DEVICE__ void sincospif(float __a, float *__s, float *__c) { +__DEVICE_VOID__ void sincospif(float __a, float *__s, float *__c) { return __nv_sincospif(__a, __s, __c); } __DEVICE__ float sinf(float __a) { @@ -339,7 +361,7 @@ __DEVICE__ double yn(int __a, double __b) { return __nv_yn(__a, __b); } __DEVICE__ float ynf(int __a, float __b) { return __nv_ynf(__a, __b); } #pragma pop_macro("__DEVICE__") +#pragma pop_macro("__DEVICE_VOID__") #pragma pop_macro("__FAST_OR_SLOW") -#undef __NOEXCEPT #endif // __CLANG_CUDA_DEVICE_FUNCTIONS_H__ diff --git a/clang/lib/Headers/__clang_cuda_math_forward_declares.h b/clang/lib/Headers/__clang_cuda_math_forward_declares.h index 0afe4db556db..3d6d0b9115a1 100644 --- a/clang/lib/Headers/__clang_cuda_math_forward_declares.h +++ b/clang/lib/Headers/__clang_cuda_math_forward_declares.h @@ -20,37 +20,14 @@ // would preclude the use of our own __device__ overloads for these functions. #pragma push_macro("__DEVICE__") -#ifdef _OPENMP -#define __DEVICE__ static __inline__ __attribute__((always_inline)) -#else #define __DEVICE__ \ static __inline__ __attribute__((always_inline)) __attribute__((device)) -#endif - -// For C++ 17 we need to include noexcept attribute to be compatible -// with the header-defined version. This may be removed once -// variant is supported. -#if defined(_OPENMP) && defined(__cplusplus) && __cplusplus >= 201703L -#define __NOEXCEPT noexcept -#else -#define __NOEXCEPT -#endif -#if !(defined(_OPENMP) && defined(__cplusplus)) __DEVICE__ long abs(long); __DEVICE__ long long abs(long long); __DEVICE__ double abs(double); __DEVICE__ float abs(float); -#endif -// While providing the CUDA declarations and definitions for math functions, -// we may manually define additional functions. -// TODO: Once variant is supported the additional functions will have -// to be removed. -#if defined(_OPENMP) && defined(__cplusplus) -__DEVICE__ const double abs(const double); -__DEVICE__ const float abs(const float); -#endif -__DEVICE__ int abs(int) __NOEXCEPT; +__DEVICE__ int abs(int); __DEVICE__ double acos(double); __DEVICE__ float acos(float); __DEVICE__ double acosh(double); @@ -85,8 +62,8 @@ __DEVICE__ double exp(double); __DEVICE__ float exp(float); __DEVICE__ double expm1(double); __DEVICE__ float expm1(float); -__DEVICE__ double fabs(double) __NOEXCEPT; -__DEVICE__ float fabs(float) __NOEXCEPT; +__DEVICE__ double fabs(double); +__DEVICE__ float fabs(float); __DEVICE__ double fdim(double, double); __DEVICE__ float fdim(float, float); __DEVICE__ double floor(double); @@ -136,12 +113,12 @@ __DEVICE__ bool isnormal(double); __DEVICE__ bool isnormal(float); __DEVICE__ bool isunordered(double, double); __DEVICE__ bool isunordered(float, float); -__DEVICE__ long labs(long) __NOEXCEPT; +__DEVICE__ long labs(long); __DEVICE__ double ldexp(double, int); __DEVICE__ float ldexp(float, int); __DEVICE__ double lgamma(double); __DEVICE__ float lgamma(float); -__DEVICE__ long long llabs(long long) __NOEXCEPT; +__DEVICE__ long long llabs(long long); __DEVICE__ long long llrint(double); __DEVICE__ long long llrint(float); __DEVICE__ double log10(double); @@ -152,9 +129,6 @@ __DEVICE__ double log2(double); __DEVICE__ float log2(float); __DEVICE__ double logb(double); __DEVICE__ float logb(float); -#if defined(_OPENMP) && defined(__cplusplus) -__DEVICE__ long double log(long double); -#endif __DEVICE__ double log(double); __DEVICE__ float log(float); __DEVICE__ long lrint(double); @@ -302,7 +276,6 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif -#undef __NOEXCEPT #pragma pop_macro("__DEVICE__") #endif diff --git a/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h b/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h new file mode 100644 index 000000000000..6250c833b122 --- /dev/null +++ b/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h @@ -0,0 +1,60 @@ +/*===- __clang_openmp_device_functions.h - OpenMP device function declares -=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __CLANG_OPENMP_DEVICE_FUNCTIONS_H__ +#define __CLANG_OPENMP_DEVICE_FUNCTIONS_H__ + +#ifndef _OPENMP +#error "This file is for OpenMP compilation only." +#endif + +#pragma omp begin declare variant match(device={arch(nvptx64)}) +#define __CUDA__ + +#ifdef __cplusplus +extern "C" { +#endif + +/// Include declarations for libdevice functions. +#include <__clang_cuda_libdevice_declares.h> + +/// Provide definitions for these functions. +#include <__clang_cuda_device_functions.h> + +#ifdef __cplusplus +} // extern "C" +#endif + +#undef __CUDA__ +// TODO: Hack until we support an extension to the match clause that allows "or". +#undef __CLANG_CUDA_LIBDEVICE_DECLARES_H__ +#undef __CLANG_CUDA_DEVICE_FUNCTIONS_H__ +#pragma omp end declare variant + +#pragma omp begin declare variant match(device={arch(nvptx)}) +#define __CUDA__ + +#ifdef __cplusplus +extern "C" { +#endif + +/// Include declarations for libdevice functions. +#include <__clang_cuda_libdevice_declares.h> + +/// Provide definitions for these functions. +#include <__clang_cuda_device_functions.h> + +#ifdef __cplusplus +} // extern "C" +#endif + +#undef __CUDA__ +#pragma omp end declare variant + +#endif diff --git a/clang/lib/Headers/openmp_wrappers/__clang_openmp_math.h b/clang/lib/Headers/openmp_wrappers/__clang_openmp_math.h deleted file mode 100644 index 5d7ce9a965d3..000000000000 --- a/clang/lib/Headers/openmp_wrappers/__clang_openmp_math.h +++ /dev/null @@ -1,35 +0,0 @@ -/*===---- __clang_openmp_math.h - OpenMP target math support ---------------=== - * - * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. - * See https://llvm.org/LICENSE.txt for license information. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - * - *===-----------------------------------------------------------------------=== - */ - -#if defined(__NVPTX__) && defined(_OPENMP) -/// TODO: -/// We are currently reusing the functionality of the Clang-CUDA code path -/// as an alternative to the host declarations provided by math.h and cmath. -/// This is suboptimal. -/// -/// We should instead declare the device functions in a similar way, e.g., -/// through OpenMP 5.0 variants, and afterwards populate the module with the -/// host declarations by unconditionally including the host math.h or cmath, -/// respectively. This is actually what the Clang-CUDA code path does, using -/// __device__ instead of variants to avoid redeclarations and get the desired -/// overload resolution. - -#define __CUDA__ - -#if defined(__cplusplus) - #include <__clang_cuda_cmath.h> -#endif - -#undef __CUDA__ - -/// Magic macro for stopping the math.h/cmath host header from being included. -#define __CLANG_NO_HOST_MATH__ - -#endif - diff --git a/clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h b/clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h deleted file mode 100644 index dd97faca6932..000000000000 --- a/clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h +++ /dev/null @@ -1,34 +0,0 @@ -/*===---- __clang_openmp_math_declares.h - OpenMP math declares ------------=== - * - * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. - * See https://llvm.org/LICENSE.txt for license information. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - * - *===-----------------------------------------------------------------------=== - */ - -#ifndef __CLANG_OPENMP_MATH_DECLARES_H__ -#define __CLANG_OPENMP_MATH_DECLARES_H__ - -#ifndef _OPENMP -#error "This file is for OpenMP compilation only." -#endif - -#if defined(__NVPTX__) && defined(_OPENMP) - -#define __CUDA__ - -#if defined(__cplusplus) - #include <__clang_cuda_math_forward_declares.h> -#endif - -/// Include declarations for libdevice functions. -#include <__clang_cuda_libdevice_declares.h> -/// Provide definitions for these functions. -#include <__clang_cuda_device_functions.h> -#include <__clang_cuda_math.h> - -#undef __CUDA__ - -#endif -#endif diff --git a/clang/lib/Headers/openmp_wrappers/cmath b/clang/lib/Headers/openmp_wrappers/cmath index a5183a1d8d1b..57ea0cadf786 100644 --- a/clang/lib/Headers/openmp_wrappers/cmath +++ b/clang/lib/Headers/openmp_wrappers/cmath @@ -1,4 +1,4 @@ -/*===-------------- cmath - Alternative cmath header -----------------------=== +/*===-- __clang_openmp_device_functions.h - OpenMP math declares ------ c++ -=== * * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. * See https://llvm.org/LICENSE.txt for license information. @@ -7,10 +7,60 @@ *===-----------------------------------------------------------------------=== */ -#include <__clang_openmp_math.h> +#ifndef __CLANG_OPENMP_CMATH_H__ +#define __CLANG_OPENMP_CMATH_H__ + +#ifndef _OPENMP +#error "This file is for OpenMP compilation only." +#endif -#ifndef __CLANG_NO_HOST_MATH__ #include_next -#else -#undef __CLANG_NO_HOST_MATH__ + +// Make sure we include our math.h overlay, it probably happend already but we +// need to be sure. +#include + +#pragma omp begin declare variant match( \ + device = {arch(nvptx, nvptx64)}, implementation = {extension(match_any)}) + +#define __CUDA__ +#include <__clang_cuda_cmath.h> +#undef __CUDA__ + +// Overloads not provided by the CUDA wrappers but by the CUDA system headers. +// Since we do not include the latter we define them ourselves. +#define __DEVICE__ static constexpr __attribute__((always_inline, nothrow)) +__DEVICE__ float acosh(float __x) { return ::acoshf(__x); } +__DEVICE__ float asinh(float __x) { return ::asinhf(__x); } +__DEVICE__ float atanh(float __x) { return ::atanhf(__x); } +__DEVICE__ float cbrt(float __x) { return ::cbrtf(__x); } +__DEVICE__ float erf(float __x) { return ::erff(__x); } +__DEVICE__ float erfc(float __x) { return ::erfcf(__x); } +__DEVICE__ float exp2(float __x) { return ::exp2f(__x); } +__DEVICE__ float expm1(float __x) { return ::expm1f(__x); } +__DEVICE__ float fdim(float __x, float __y) { return ::fdimf(__x, __y); } +__DEVICE__ float hypot(float __x, float __y) { return ::hypotf(__x, __y); } +__DEVICE__ int ilogb(float __x) { return ::ilogbf(__x); } +__DEVICE__ float lgamma(float __x) { return ::lgammaf(__x); } +__DEVICE__ long long int llrint(float __x) { return ::llrintf(__x); } +__DEVICE__ long long int llround(float __x) { return ::llroundf(__x); } +__DEVICE__ float log1p(float __x) { return ::log1pf(__x); } +__DEVICE__ float log2(float __x) { return ::log2f(__x); } +__DEVICE__ float logb(float __x) { return ::logbf(__x); } +__DEVICE__ long int lrint(float __x) { return ::lrintf(__x); } +__DEVICE__ long int lround(float __x) { return ::lroundf(__x); } +__DEVICE__ float nextafter(float __x, float __y) { + return ::nextafterf(__x, __y); +} +__DEVICE__ float remainder(float __x, float __y) { + return ::remainderf(__x, __y); +} +__DEVICE__ float scalbln(float __x, long int __y) { + return ::scalblnf(__x, __y); +} +__DEVICE__ float scalbn(float __x, int __y) { return ::scalbnf(__x, __y); } +__DEVICE__ float tgamma(float __x) { return ::tgammaf(__x); } + +#pragma omp end declare variant + #endif diff --git a/clang/lib/Headers/openmp_wrappers/math.h b/clang/lib/Headers/openmp_wrappers/math.h index d2786ecb2424..cd6d3abf7768 100644 --- a/clang/lib/Headers/openmp_wrappers/math.h +++ b/clang/lib/Headers/openmp_wrappers/math.h @@ -1,4 +1,4 @@ -/*===------------- math.h - Alternative math.h header ----------------------=== +/*===---- openmp_wrapper/math.h -------- OpenMP math.h intercept ------ c++ -=== * * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. * See https://llvm.org/LICENSE.txt for license information. @@ -7,11 +7,26 @@ *===-----------------------------------------------------------------------=== */ -#include <__clang_openmp_math.h> +#ifndef __CLANG_OPENMP_MATH_H__ +#define __CLANG_OPENMP_MATH_H__ -#ifndef __CLANG_NO_HOST_MATH__ -#include_next -#else -#undef __CLANG_NO_HOST_MATH__ +#ifndef _OPENMP +#error "This file is for OpenMP compilation only." #endif +#include_next + +// We need limits.h for __clang_cuda_math.h below and because it should not hurt +// we include it eagerly here. +#include + +#pragma omp begin declare variant match( \ + device = {arch(nvptx, nvptx64)}, implementation = {extension(match_any)}) + +#define __CUDA__ +#include <__clang_cuda_math.h> +#undef __CUDA__ + +#pragma omp end declare variant + +#endif diff --git a/clang/lib/Headers/openmp_wrappers/time.h b/clang/lib/Headers/openmp_wrappers/time.h new file mode 100644 index 000000000000..4581e8c0c9ff --- /dev/null +++ b/clang/lib/Headers/openmp_wrappers/time.h @@ -0,0 +1,31 @@ +/*===---- time.h - OpenMP time header wrapper ------------------------ c ---=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __CLANG_OPENMP_TIME_H__ +#define __CLANG_OPENMP_TIME_H__ + +#ifndef _OPENMP +#error "This file is for OpenMP compilation only." +#endif + +#include_next + +#pragma omp begin declare variant match(device={arch(nvptx64)}) +static __attribute__((always_inline)) clock_t int clock() { + return __nvvm_read_ptx_sreg_clock(); +} +#pragma omp end declare variant + +#pragma omp begin declare variant match(device={arch(nvptx)}) +static __attribute__((always_inline)) clock_t int clock() { + return __nvvm_read_ptx_sreg_clock(); +} +#pragma omp end declare variant + +#endif diff --git a/clang/test/Headers/Inputs/include/climits b/clang/test/Headers/Inputs/include/climits new file mode 100644 index 000000000000..929762edc044 --- /dev/null +++ b/clang/test/Headers/Inputs/include/climits @@ -0,0 +1,4 @@ +#pragma once + +#define INT_MIN -2147483648 +#define INT_MAX 2147483647 diff --git a/clang/test/Headers/Inputs/include/cmath b/clang/test/Headers/Inputs/include/cmath index 4ba17951378f..0cadc131d211 100644 --- a/clang/test/Headers/Inputs/include/cmath +++ b/clang/test/Headers/Inputs/include/cmath @@ -1,5 +1,227 @@ #pragma once -double sqrt(double); +// __clang_cuda_(c)math(.h) also provide `abs` which actually belong in +// cstdlib. We could split them out but for now we just include cstdlib from +// cmath.h which is what the systems I've seen do as well. +#include + +#include + +double acos(double); +float acos(float); +double acosh(double); +float acosh(float); +double asin(double); +float asin(float); +double asinh(double); +float asinh(float); +double atan2(double, double); +float atan2(float, float); +double atan(double); +float atan(float); +double atanh(double); +float atanh(float); +double cbrt(double); +float cbrt(float); +double ceil(double); +float ceil(float); +double copysign(double, double); +float copysign(float, float); +double cos(double); +float cos(float); +double cosh(double); +float cosh(float); +double erfc(double); +float erfc(float); +double erf(double); +float erf(float); +double exp2(double); +float exp2(float); +double exp(double); +float exp(float); +double expm1(double); +float expm1(float); +double fdim(double, double); +float fdim(float, float); +double floor(double); +float floor(float); +double fma(double, double, double); +float fma(float, float, float); +double fmax(double, double); +float fmax(float, float); +double fmin(double, double); +float fmin(float, float); +double fmod(double, double); +float fmod(float, float); +int fpclassify(double); +int fpclassify(float); +double frexp(double, int *); +float frexp(float, int *); +double hypot(double, double); +float hypot(float, float); +int ilogb(double); +int ilogb(float); +bool isfinite(long double); +bool isfinite(double); +bool isfinite(float); +bool isgreater(double, double); +bool isgreaterequal(double, double); +bool isgreaterequal(float, float); +bool isgreater(float, float); +bool isinf(long double); +bool isinf(double); +bool isinf(float); +bool isless(double, double); +bool islessequal(double, double); +bool islessequal(float, float); +bool isless(float, float); +bool islessgreater(double, double); +bool islessgreater(float, float); +bool isnan(long double); +bool isnan(double); +bool isnan(float); +bool isnormal(double); +bool isnormal(float); +bool isunordered(double, double); +bool isunordered(float, float); +double ldexp(double, int); +float ldexp(float, int); +double lgamma(double); +float lgamma(float); +long long llrint(double); +long long llrint(float); +double log10(double); +float log10(float); +double log1p(double); +float log1p(float); +double log2(double); +float log2(float); +double logb(double); +float logb(float); +double log(double); +float log(float); +long lrint(double); +long lrint(float); +long lround(double); +long lround(float); +long long llround(float); // No llround(double). +double modf(double, double *); +float modf(float, float *); +double nan(const char *); +float nanf(const char *); +double nearbyint(double); +float nearbyint(float); +double nextafter(double, double); +float nextafter(float, float); double pow(double, double); -double modf(double, double*); +double pow(double, int); +float pow(float, float); +float pow(float, int); +double remainder(double, double); +float remainder(float, float); +double remquo(double, double, int *); +float remquo(float, float, int *); +double rint(double); +float rint(float); +double round(double); +float round(float); +double scalbln(double, long); +float scalbln(float, long); +double scalbn(double, int); +float scalbn(float, int); +bool signbit(double); +bool signbit(float); +long double sin(long double); +double sin(double); +float sin(float); +double sinh(double); +float sinh(float); +double sqrt(double); +float sqrt(float); +double tan(double); +float tan(float); +double tanh(double); +float tanh(float); +double tgamma(double); +float tgamma(float); +double trunc(double); +float trunc(float); + +namespace std { + +using ::acos; +using ::acosh; +using ::asin; +using ::asinh; +using ::atan; +using ::atan2; +using ::atanh; +using ::cbrt; +using ::ceil; +using ::copysign; +using ::cos; +using ::cosh; +using ::erf; +using ::erfc; +using ::exp; +using ::exp2; +using ::expm1; +using ::fdim; +using ::floor; +using ::fma; +using ::fmax; +using ::fmin; +using ::fmod; +using ::fpclassify; +using ::frexp; +using ::hypot; +using ::ilogb; +using ::isfinite; +using ::isgreater; +using ::isgreaterequal; +using ::isinf; +using ::isless; +using ::islessequal; +using ::islessgreater; +using ::isnan; +using ::isnormal; +using ::isunordered; +using ::ldexp; +using ::lgamma; +using ::llrint; +using ::log; +using ::log10; +using ::log1p; +using ::log2; +using ::logb; +using ::lrint; +using ::lround; +using ::llround; +using ::modf; +using ::nan; +using ::nanf; +using ::nearbyint; +using ::nextafter; +using ::pow; +using ::remainder; +using ::remquo; +using ::rint; +using ::round; +using ::scalbln; +using ::scalbn; +using ::signbit; +using ::sin; +using ::sinh; +using ::sqrt; +using ::tan; +using ::tanh; +using ::tgamma; +using ::trunc; + +} // namespace std + +#define FP_NAN 0 +#define FP_INFINITE 1 +#define FP_ZERO 2 +#define FP_SUBNORMAL 3 +#define FP_NORMAL 4 diff --git a/clang/test/Headers/Inputs/include/cstdlib b/clang/test/Headers/Inputs/include/cstdlib index f038a6d90cb0..00e81e8c4a15 100644 --- a/clang/test/Headers/Inputs/include/cstdlib +++ b/clang/test/Headers/Inputs/include/cstdlib @@ -1,5 +1,7 @@ #pragma once +#include + #if __cplusplus >= 201703L extern int abs (int __x) throw() __attribute__ ((__const__)) ; extern long int labs (long int __x) throw() __attribute__ ((__const__)) ; @@ -20,4 +22,6 @@ abs(long __i) { return __builtin_labs(__i); } inline long long abs(long long __x) { return __builtin_llabs (__x); } + +float fabs(float __x) { return __builtin_fabs(__x); } } diff --git a/clang/test/Headers/Inputs/include/math.h b/clang/test/Headers/Inputs/include/math.h index 4ba17951378f..a60ad45b4d71 100644 --- a/clang/test/Headers/Inputs/include/math.h +++ b/clang/test/Headers/Inputs/include/math.h @@ -1,5 +1,199 @@ #pragma once -double sqrt(double); -double pow(double, double); -double modf(double, double*); +// __clang_cuda_(c)math(.h) also provide `abs` which actually belong in +// cstdlib. We could split them out but for now we just include cstdlib from +// cmath.h which is what the systems I've seen do as well. +#include + +double fabs(double __a); +double acos(double __a); +float acosf(float __a); +double acosh(double __a); +float acoshf(float __a); +double asin(double __a); +float asinf(float __a); +double asinh(double __a); +float asinhf(float __a); +double atan(double __a); +double atan2(double __a, double __b); +float atan2f(float __a, float __b); +float atanf(float __a); +double atanh(double __a); +float atanhf(float __a); +double cbrt(double __a); +float cbrtf(float __a); +double ceil(double __a); +float ceilf(float __a); +double copysign(double __a, double __b); +float copysignf(float __a, float __b); +double cos(double __a); +float cosf(float __a); +double cosh(double __a); +float coshf(float __a); +double cospi(double __a); +float cospif(float __a); +double cyl_bessel_i0(double __a); +float cyl_bessel_i0f(float __a); +double cyl_bessel_i1(double __a); +float cyl_bessel_i1f(float __a); +double erf(double __a); +double erfc(double __a); +float erfcf(float __a); +double erfcinv(double __a); +float erfcinvf(float __a); +double erfcx(double __a); +float erfcxf(float __a); +float erff(float __a); +double erfinv(double __a); +float erfinvf(float __a); +double exp(double __a); +double exp10(double __a); +float exp10f(float __a); +double exp2(double __a); +float exp2f(float __a); +float expf(float __a); +double expm1(double __a); +float expm1f(float __a); +float fabsf(float __a); +double fdim(double __a, double __b); +float fdimf(float __a, float __b); +double fdivide(double __a, double __b); +float fdividef(float __a, float __b); +double floor(double __f); +float floorf(float __f); +double fma(double __a, double __b, double __c); +float fmaf(float __a, float __b, float __c); +double fmax(double __a, double __b); +float fmaxf(float __a, float __b); +double fmin(double __a, double __b); +float fminf(float __a, float __b); +double fmod(double __a, double __b); +float fmodf(float __a, float __b); +double frexp(double __a, int *__b); +float frexpf(float __a, int *__b); +double hypot(double __a, double __b); +float hypotf(float __a, float __b); +int ilogb(double __a); +int ilogbf(float __a); +double j0(double __a); +float j0f(float __a); +double j1(double __a); +float j1f(float __a); +double jn(int __n, double __a); +float jnf(int __n, float __a); +double ldexp(double __a, int __b); +float ldexpf(float __a, int __b); +double lgamma(double __a); +float lgammaf(float __a); +long long llmax(long long __a, long long __b); +long long llmin(long long __a, long long __b); +long long llrint(double __a); +long long llrintf(float __a); +long long llround(double __a); +long long llroundf(float __a); +double log(double __a); +double log10(double __a); +float log10f(float __a); +double log1p(double __a); +float log1pf(float __a); +double log2(double __a); +float log2f(float __a); +double logb(double __a); +float logbf(float __a); +float logf(float __a); +long lrint(double __a); +long lrintf(float __a); +long lround(double __a); +long lroundf(float __a); +int max(int __a, int __b); +int min(int __a, int __b); +double modf(double __a, double *__b); +float modff(float __a, float *__b); +double nearbyint(double __a); +float nearbyintf(float __a); +double nextafter(double __a, double __b); +float nextafterf(float __a, float __b); +double norm(int __dim, const double *__t); +double norm3d(double __a, double __b, double __c); +float norm3df(float __a, float __b, float __c); +double norm4d(double __a, double __b, double __c, double __d); +float norm4df(float __a, float __b, float __c, float __d); +double normcdf(double __a); +float normcdff(float __a); +double normcdfinv(double __a); +float normcdfinvf(float __a); +float normf(int __dim, const float *__t); +double pow(double __a, double __b); +float powf(float __a, float __b); +double powi(double __a, int __b); +float powif(float __a, int __b); +double rcbrt(double __a); +float rcbrtf(float __a); +double remainder(double __a, double __b); +float remainderf(float __a, float __b); +double remquo(double __a, double __b, int *__c); +float remquof(float __a, float __b, int *__c); +double rhypot(double __a, double __b); +float rhypotf(float __a, float __b); +double rint(double __a); +float rintf(float __a); +double rnorm(int __a, const double *__b); +double rnorm3d(double __a, double __b, double __c); +float rnorm3df(float __a, float __b, float __c); +double rnorm4d(double __a, double __b, double __c, double __d); +float rnorm4df(float __a, float __b, float __c, float __d); +float rnormf(int __dim, const float *__t); +double round(double __a); +float roundf(float __a); +double rsqrt(double __a); +float rsqrtf(float __a); +double scalbn(double __a, int __b); +float scalbnf(float __a, int __b); +double scalbln(double __a, long __b); +float scalblnf(float __a, long __b); +double sin(double __a); +void sincos(double __a, double *__s, double *__c); +void sincosf(float __a, float *__s, float *__c); +void sincospi(double __a, double *__s, double *__c); +void sincospif(float __a, float *__s, float *__c); +float sinf(float __a); +double sinh(double __a); +float sinhf(float __a); +double sinpi(double __a); +float sinpif(float __a); +double sqrt(double __a); +float sqrtf(float __a); +double tan(double __a); +float tanf(float __a); +double tanh(double __a); +float tanhf(float __a); +double tgamma(double __a); +float tgammaf(float __a); +double trunc(double __a); +float truncf(float __a); +unsigned long long ullmax(unsigned long long __a, + unsigned long long __b); +unsigned long long ullmin(unsigned long long __a, + unsigned long long __b); +unsigned int umax(unsigned int __a, unsigned int __b); +unsigned int umin(unsigned int __a, unsigned int __b); +double y0(double __a); +float y0f(float __a); +double y1(double __a); +float y1f(float __a); +double yn(int __a, double __b); +float ynf(int __a, float __b); + +/** + * A positive float constant expression. HUGE_VALF evaluates + * to +infinity. Used as an error value returned by the built-in + * math functions. + */ +#define HUGE_VALF (__builtin_huge_valf()) + +/** + * A positive double constant expression. HUGE_VAL evaluates + * to +infinity. Used as an error value returned by the built-in + * math functions. + */ +#define HUGE_VAL (__builtin_huge_val()) diff --git a/clang/test/Headers/Inputs/include/stdlib.h b/clang/test/Headers/Inputs/include/stdlib.h index 296b6239f677..516e521df7ec 100644 --- a/clang/test/Headers/Inputs/include/stdlib.h +++ b/clang/test/Headers/Inputs/include/stdlib.h @@ -1,2 +1,6 @@ #pragma once typedef __SIZE_TYPE__ size_t; + +#ifndef __cplusplus +extern int abs(int __x) __attribute__((__const__)); +#endif diff --git a/clang/test/Headers/nvptx_device_cmath_functions.c b/clang/test/Headers/nvptx_device_cmath_functions.c index 23265d00f13d..7ba28442d34a 100644 --- a/clang/test/Headers/nvptx_device_cmath_functions.c +++ b/clang/test/Headers/nvptx_device_cmath_functions.c @@ -3,10 +3,11 @@ // REQUIRES: nvptx-registered-target -// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include cmath -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_math_declares.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -include cmath -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s +// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s -#include +#include +#include void test_sqrt(double a1) { #pragma omp target diff --git a/clang/test/Headers/nvptx_device_cmath_functions.cpp b/clang/test/Headers/nvptx_device_cmath_functions.cpp index 0787b9406261..35e33f97a3ef 100644 --- a/clang/test/Headers/nvptx_device_cmath_functions.cpp +++ b/clang/test/Headers/nvptx_device_cmath_functions.cpp @@ -3,8 +3,8 @@ // REQUIRES: nvptx-registered-target -// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include cmath -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_math_declares.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -include cmath -internal-isystem %S/Inputs/include -include stdlib.h -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s +// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s #include #include diff --git a/clang/test/Headers/nvptx_device_cmath_functions_cxx17.cpp b/clang/test/Headers/nvptx_device_cmath_functions_cxx17.cpp index 0b715fea01f1..62ae1e20ffe2 100644 --- a/clang/test/Headers/nvptx_device_cmath_functions_cxx17.cpp +++ b/clang/test/Headers/nvptx_device_cmath_functions_cxx17.cpp @@ -3,8 +3,8 @@ // REQUIRES: nvptx-registered-target -// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include cmath -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -std=c++17 -// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_math_declares.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -include cmath -internal-isystem %S/Inputs/include -include stdlib.h -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -std=c++17 -o - | FileCheck -check-prefix CHECK-YES %s +// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -std=c++17 +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -std=c++17 -o - | FileCheck -check-prefix CHECK-YES %s #include #include diff --git a/clang/test/Headers/nvptx_device_math_complex.c b/clang/test/Headers/nvptx_device_math_complex.c new file mode 100644 index 000000000000..43f4ec6a6b59 --- /dev/null +++ b/clang/test/Headers/nvptx_device_math_complex.c @@ -0,0 +1,23 @@ +// REQUIRES: nvptx-registered-target +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s +// expected-no-diagnostics + +// CHECK-DAG: call { float, float } @__divsc3( +// CHECK-DAG: call { float, float } @__mulsc3( +void test_scmplx(float _Complex a) { +#pragma omp target + { + (void)(a * (a / a)); + } +} + + +// CHECK-DAG: call { double, double } @__divdc3( +// CHECK-DAG: call { double, double } @__muldc3( +void test_dcmplx(double _Complex a) { +#pragma omp target + { + (void)(a * (a / a)); + } +} diff --git a/clang/test/Headers/nvptx_device_math_functions.c b/clang/test/Headers/nvptx_device_math_functions.c index 3cc1be51ce88..7e37e3fc6641 100644 --- a/clang/test/Headers/nvptx_device_math_functions.c +++ b/clang/test/Headers/nvptx_device_math_functions.c @@ -3,23 +3,31 @@ // REQUIRES: nvptx-registered-target -// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include math.h -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_math_declares.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -include math.h -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s +// RUN: %clang_cc1 -x c -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -x c -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s +// RUN: %clang_cc1 -x c++ -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -x c++ -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s +#ifdef __cplusplus +#include +#include +#else +#include #include +#endif void test_sqrt(double a1) { #pragma omp target { - // CHECK-YES: call double @__nv_sqrt(double + // CHECK: call double @__nv_sqrt(double double l1 = sqrt(a1); - // CHECK-YES: call double @__nv_pow(double + // CHECK: call double @__nv_pow(double double l2 = pow(a1, a1); - // CHECK-YES: call double @__nv_modf(double + // CHECK: call double @__nv_modf(double double l3 = modf(a1 + 3.5, &a1); - // CHECK-YES: call double @__nv_fabs(double + // CHECK: call double @__nv_fabs(double double l4 = fabs(a1); - // CHECK-YES: call i32 @__nv_abs(i32 + // CHECK: call i32 @__nv_abs(i32 double l5 = abs((int)a1); } } diff --git a/clang/test/Headers/nvptx_device_math_functions.cpp b/clang/test/Headers/nvptx_device_math_functions.cpp index e0f18263f04e..6ace3c5fa84e 100644 --- a/clang/test/Headers/nvptx_device_math_functions.cpp +++ b/clang/test/Headers/nvptx_device_math_functions.cpp @@ -3,11 +3,11 @@ // REQUIRES: nvptx-registered-target -// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include math.h -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_math_declares.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -include math.h -internal-isystem %S/Inputs/include -include stdlib.h -include limits -include cstdlib -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s +// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s #include -#include +#include void test_sqrt(double a1) { #pragma omp target diff --git a/clang/test/Headers/nvptx_device_math_functions_cxx17.cpp b/clang/test/Headers/nvptx_device_math_functions_cxx17.cpp index e3c0b1241b8c..5220f44336f0 100644 --- a/clang/test/Headers/nvptx_device_math_functions_cxx17.cpp +++ b/clang/test/Headers/nvptx_device_math_functions_cxx17.cpp @@ -3,11 +3,11 @@ // REQUIRES: nvptx-registered-target -// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include math.h -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -std=c++17 -// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_math_declares.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -include math.h -internal-isystem %S/Inputs/include -include stdlib.h -include limits -include cstdlib -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -std=c++17 -o - | FileCheck -check-prefix CHECK-YES %s +// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -std=c++17 +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -std=c++17 -o - | FileCheck -check-prefix CHECK-YES %s #include -#include +#include void test_sqrt(double a1) { #pragma omp target diff --git a/clang/test/Headers/nvptx_device_math_macro.cpp b/clang/test/Headers/nvptx_device_math_macro.cpp new file mode 100644 index 000000000000..e21aa2b072b9 --- /dev/null +++ b/clang/test/Headers/nvptx_device_math_macro.cpp @@ -0,0 +1,17 @@ +// REQUIRES: nvptx-registered-target +// RUN: %clang_cc1 -x c++ -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -x c++ -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s +// expected-no-diagnostics + +#include + +#pragma omp declare target +int use_macro() { + double a(0); +// CHECK-NOT: call +// CHECK: call double @llvm.fabs.f64(double +// CHECK-NOT: call +// CHECK: ret i32 %conv + return (std::fpclassify(a) != FP_ZERO); +} +#pragma omp end declare target diff --git a/clang/test/Headers/nvptx_device_math_modf.cpp b/clang/test/Headers/nvptx_device_math_modf.cpp new file mode 100644 index 000000000000..fcfe20f4dfad --- /dev/null +++ b/clang/test/Headers/nvptx_device_math_modf.cpp @@ -0,0 +1,53 @@ +// REQUIRES: nvptx-registered-target +// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s + +#include + +// 4 calls to modf(f), all translated to __nv_modf calls: + +// CHECK-NOT: _Z.modf +// CHECK: call double @__nv_modf(double +// CHECK-NOT: _Z.modf +// CHECK: call float @__nv_modff(float +// CHECK-NOT: _Z.modf +// CHECK: call double @__nv_modf(double +// CHECK-NOT: _Z.modf +// CHECK: call float @__nv_modff(float +// CHECK-NOT: _Z.modf + +template +void test_modf(T x) +{ + T dx; + int intx; + + #pragma omp target map(from: intx, dx) + { + T ipart; + dx = std::modf(x, &ipart); + intx = static_cast(ipart); + } +} + +int main() +{ + +#if !defined(C_ONLY) + test_modf(1.0); + test_modf(1.0); +#endif + + #pragma omp target + { + double intpart, res; + res = modf(1.1, &intpart); + } + + #pragma omp target + { + float intpart, res; + res = modff(1.1f, &intpart); + } + +} diff --git a/clang/test/Headers/nvptx_device_math_sin.c b/clang/test/Headers/nvptx_device_math_sin.c new file mode 100644 index 000000000000..75b998d59006 --- /dev/null +++ b/clang/test/Headers/nvptx_device_math_sin.c @@ -0,0 +1,27 @@ +// REQUIRES: nvptx-registered-target +// RUN: %clang_cc1 -x c -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -x c -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=SLOW +// RUN: %clang_cc1 -x c -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -ffast-math +// RUN: %clang_cc1 -x c -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -ffast-math | FileCheck %s --check-prefix=FAST +// expected-no-diagnostics + +#include + +double math(float f, double d, long double ld) { + double r = 0; +// SLOW: call float @__nv_sinf(float +// FAST: call fast float @__nv_fast_sinf(float + r += sinf(f); +// SLOW: call double @__nv_sin(double +// FAST: call fast double @__nv_sin(double + r += sin(d); + return r; +} + +long double foo(float f, double d, long double ld) { + double r = ld; + r += math(f, d, ld); +#pragma omp target map(r) + { r += math(f, d, ld); } + return r; +} diff --git a/clang/test/Headers/nvptx_device_math_sin.cpp b/clang/test/Headers/nvptx_device_math_sin.cpp new file mode 100644 index 000000000000..e4d25b40b1b9 --- /dev/null +++ b/clang/test/Headers/nvptx_device_math_sin.cpp @@ -0,0 +1,27 @@ +// REQUIRES: nvptx-registered-target +// RUN: %clang_cc1 -x c++ -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -x c++ -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=SLOW +// RUN: %clang_cc1 -x c++ -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -ffast-math +// RUN: %clang_cc1 -x c++ -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -ffast-math | FileCheck %s --check-prefix=FAST +// expected-no-diagnostics + +#include + +double math(float f, double d, long double ld) { + double r = 0; +// SLOW: call float @__nv_sinf(float +// FAST: call fast float @__nv_fast_sinf(float + r += sin(f); +// SLOW: call double @__nv_sin(double +// FAST: call fast double @__nv_sin(double + r += sin(d); + return r; +} + +long double foo(float f, double d, long double ld) { + double r = ld; + r += math(f, d, ld); +#pragma omp target map(r) + { r += math(f, d, ld); } + return r; +} diff --git a/clang/test/Headers/nvptx_device_math_sin_cos.cpp b/clang/test/Headers/nvptx_device_math_sin_cos.cpp new file mode 100644 index 000000000000..dbb2e71ec352 --- /dev/null +++ b/clang/test/Headers/nvptx_device_math_sin_cos.cpp @@ -0,0 +1,63 @@ +// REQUIRES: nvptx-registered-target +// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s + +#include + +// 6 calls to sin/cos(f), all translated to __nv_sin/__nv_cos calls: + +// CHECK-NOT: _Z.sin +// CHECK-NOT: _Z.cos +// CHECK: call double @__nv_sin(double +// CHECK-NOT: _Z.sin +// CHECK-NOT: _Z.cos +// CHECK: call float @__nv_sinf(float +// CHECK-NOT: _Z.sin +// CHECK-NOT: _Z.cos +// CHECK: call double @__nv_sin(double +// CHECK-NOT: _Z.sin +// CHECK-NOT: _Z.cos +// CHECK: call double @__nv_cos(double +// CHECK-NOT: _Z.sin +// CHECK-NOT: _Z.cos +// CHECK: call float @__nv_sinf(float +// CHECK-NOT: _Z.sin +// CHECK-NOT: _Z.cos +// CHECK: call float @__nv_cosf(float +// CHECK-NOT: _Z.sin +// CHECK-NOT: _Z.cos + +template +void test_sin_cos(T x) +{ + T res_sin, res_cos; + + #pragma omp target map(from: res_sin, res_cos) + { + res_sin = std::sin(x); + res_cos = std::cos(x); + } +} + +int main() +{ + +#if !defined(C_ONLY) + test_sin_cos(0.0); + test_sin_cos(0.0); +#endif + + #pragma omp target + { + double res; + res = sin(1.0); + } + + #pragma omp target + { + float res; + res = sinf(1.0f); + } + + return 0; +} diff --git a/clang/test/Headers/nvptx_device_math_sincos.cpp b/clang/test/Headers/nvptx_device_math_sincos.cpp new file mode 100644 index 000000000000..5419ee2c3513 --- /dev/null +++ b/clang/test/Headers/nvptx_device_math_sincos.cpp @@ -0,0 +1,58 @@ +// REQUIRES: nvptx-registered-target +// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s + +#include + +// 4 calls to sincos(f), all translated to __nv_sincos calls: + +// CHECK-NOT: _Z.sincos +// CHECK: call void @__nv_sincos(double +// CHECK-NOT: _Z.sincos +// CHECK: call void @__nv_sincosf(float +// CHECK-NOT: _Z.sincos +// CHECK: call void @__nv_sincos(double +// CHECK-NOT: _Z.sincos +// CHECK: call void @__nv_sincosf(float +// CHECK-NOT: _Z.sincos + +// single precision wrapper +inline void sincos(float x, float* __restrict__ sin, float* __restrict__ cos) +{ + sincosf(x, sin, cos); +} + +template +void test_sincos(T x) +{ + T res_sin, res_cos; + + #pragma omp target map(from: res_sin, res_cos) + { + sincos(x, &res_sin, &res_cos); + } + +} + +int main(int argc, char **argv) +{ + +#if !defined(C_ONLY) + test_sincos(0.0); + test_sincos(0.0); +#endif + + #pragma omp target + { + double s, c; + sincos(0, &s, &c); + } + + #pragma omp target + { + float s, c; + sincosf(0.f, &s, &c); + } + + return 0; +} From llvm-branch-commits at lists.llvm.org Thu Apr 9 04:35:11 2020 From: llvm-branch-commits at lists.llvm.org (Anton Bikineev via llvm-branch-commits) Date: Thu, 09 Apr 2020 04:35:11 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 5b622d3 - tsan: don't instrument __attribute__((naked)) functions Message-ID: <5e8f086f.1c69fb81.63d7f.5649@mx.google.com> Author: Anton Bikineev Date: 2020-04-09T13:32:58+02:00 New Revision: 5b622d37c194eb8e0046b465ff78f4daa92139cc URL: https://github.com/llvm/llvm-project/commit/5b622d37c194eb8e0046b465ff78f4daa92139cc DIFF: https://github.com/llvm/llvm-project/commit/5b622d37c194eb8e0046b465ff78f4daa92139cc.diff LOG: tsan: don't instrument __attribute__((naked)) functions Naked functions are required to not have compiler generated prologues/epilogues, hence no instrumentation is needed for them. Bugzilla: https://bugs.llvm.org/show_bug.cgi?id=45400 Differential Revision: https://reviews.llvm.org/D77477 Added: Modified: llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 9b7edad3444b..e8882e4217aa 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -441,6 +441,11 @@ bool ThreadSanitizer::sanitizeFunction(Function &F, // the module constructor. if (F.getName() == kTsanModuleCtorName) return false; + // Naked functions can not have prologue/epilogue + // (__tsan_func_entry/__tsan_func_exit) generated, so don't instrument them at + // all. + if (F.hasFnAttribute(Attribute::Naked)) + return false; initialize(*F.getParent()); SmallVector AllLoadsAndStores; SmallVector LocalLoadsAndStores; diff --git a/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll b/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll index 953ab8ed8dc5..100717af13bf 100644 --- a/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll +++ b/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll @@ -78,5 +78,18 @@ define void @SwiftErrorCall(i8** swifterror) sanitize_thread { call void @SwiftError(i8** %0) ret void } + +; CHECK-LABEL: @NakedTest(i32* %a) +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 4 +; CHECK-NEXT: ret i32 %tmp1 +define i32 @NakedTest(i32* %a) naked sanitize_thread { + call void @foo() + %tmp1 = load i32, i32* %a, align 4 + ret i32 %tmp1 +} + +declare void @foo() nounwind + ; CHECK: define internal void @tsan.module_ctor() ; CHECK: call void @__tsan_init() From llvm-branch-commits at lists.llvm.org Fri Apr 10 17:17:48 2020 From: llvm-branch-commits at lists.llvm.org (Fangrui Song via llvm-branch-commits) Date: Fri, 10 Apr 2020 17:17:48 -0700 (PDT) Subject: [llvm-branch-commits] [lld] 489a735 - [ELF] Fix a null pointer dereference when --emit-relocs and --strip-debug are used together Message-ID: <5e910cac.1c69fb81.8fba4.8c1d@mx.google.com> Author: Fangrui Song Date: 2020-04-10T17:17:37-07:00 New Revision: 489a7356cca373de761ada4c06c5b43edc581b4b URL: https://github.com/llvm/llvm-project/commit/489a7356cca373de761ada4c06c5b43edc581b4b DIFF: https://github.com/llvm/llvm-project/commit/489a7356cca373de761ada4c06c5b43edc581b4b.diff LOG: [ELF] Fix a null pointer dereference when --emit-relocs and --strip-debug are used together Fixes https://bugs.llvm.org//show_bug.cgi?id=44878 When --strip-debug is specified, .debug* are removed from inputSections while .rel[a].debug* (incorrectly) remain. LinkerScript::addOrphanSections() requires the output section of a relocated InputSectionBase to be created first. .debug* are not in inputSections -> output sections .debug* are not created -> getOutputSectionName(.rel[a].debug*) dereferences a null pointer. Fix the null pointer dereference by deleting .rel[a].debug* from inputSections as well. Reviewed By: grimar, nickdesaulniers Differential Revision: https://reviews.llvm.org/D74510 (cherry picked from commit 6c73246179376442705b3a545f4e1f1478777a04) Added: lld/test/ELF/emit-relocs-debug.s Modified: lld/ELF/Driver.cpp lld/ELF/InputSection.cpp lld/ELF/InputSection.h Removed: ################################################################################ diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 25330832339c..6de9698bb2c8 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1906,8 +1906,17 @@ template void LinkerDriver::link(opt::InputArgList &args) { // We do not want to emit debug sections if --strip-all // or -strip-debug are given. - return config->strip != StripPolicy::None && - (s->name.startswith(".debug") || s->name.startswith(".zdebug")); + if (config->strip == StripPolicy::None) + return false; + + if (isDebugSection(*s)) + return true; + if (auto *isec = dyn_cast(s)) + if (InputSectionBase *rel = isec->getRelocatedSection()) + if (isDebugSection(*rel)) + return true; + + return false; }); // Now that the number of partitions is fixed, save a pointer to the main diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 147c51ab285e..d34abf641ed3 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -441,8 +441,7 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef rels) { // See the comment in maybeReportUndefined for PPC64 .toc . auto *d = dyn_cast(&sym); if (!d) { - if (!sec->name.startswith(".debug") && - !sec->name.startswith(".zdebug") && sec->name != ".eh_frame" && + if (!isDebugSection(*sec) && sec->name != ".eh_frame" && sec->name != ".gcc_except_table" && sec->name != ".toc") { uint32_t secIdx = cast(sym).discardedSecIdx; Elf_Shdr_Impl sec = diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 3c42af7db7b4..fe2c3c516a96 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -357,6 +357,10 @@ class InputSection : public InputSectionBase { template void copyShtGroup(uint8_t *buf); }; +inline bool isDebugSection(const InputSectionBase &sec) { + return sec.name.startswith(".debug") || sec.name.startswith(".zdebug"); +} + // The list of all input sections. extern std::vector inputSections; diff --git a/lld/test/ELF/emit-relocs-debug.s b/lld/test/ELF/emit-relocs-debug.s new file mode 100644 index 000000000000..04fa0f8d961b --- /dev/null +++ b/lld/test/ELF/emit-relocs-debug.s @@ -0,0 +1,20 @@ +# REQUIRES: x86 +## Test --emit-relocs handles .debug* + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: ld.lld --emit-relocs %t.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s +# RUN: ld.lld --emit-relocs --strip-debug %t.o -o %t.no +# RUN: llvm-readobj -r %t.no | FileCheck --check-prefix=NO %s + +# CHECK: Section {{.*}} .rela.debug_info { +# CHECK-NEXT: R_X86_64_64 .text 0x0 +# CHECK-NEXT: } + +# NO: Relocations [ +# NO-NEXT: ] + +foo: + +.section .debug_info +.quad foo From llvm-branch-commits at lists.llvm.org Sat Apr 11 22:21:35 2020 From: llvm-branch-commits at lists.llvm.org (Fangrui Song via llvm-branch-commits) Date: Sat, 11 Apr 2020 22:21:35 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 50d7e5d - [llvm-objcopy] Improve tool selection logic to recognize llvm-strip-$major as strip Message-ID: <5e92a55f.1c69fb81.3b2a5.0e64@mx.google.com> Author: Fangrui Song Date: 2020-04-11T22:20:59-07:00 New Revision: 50d7e5d5e7db05b53d8832b49761eb627fd2eb63 URL: https://github.com/llvm/llvm-project/commit/50d7e5d5e7db05b53d8832b49761eb627fd2eb63 DIFF: https://github.com/llvm/llvm-project/commit/50d7e5d5e7db05b53d8832b49761eb627fd2eb63.diff LOG: [llvm-objcopy] Improve tool selection logic to recognize llvm-strip-$major as strip Debian and some other distributions install llvm-strip as llvm-strip-$major (e.g. `/usr/bin/llvm-strip-9`) D54193 made it work with llvm-strip-$major but did not add a test. The behavior was regressed by D69146. Fixes https://github.com/ClangBuiltLinux/linux/issues/940 Reviewed By: alexshap Differential Revision: https://reviews.llvm.org/D76562 (cherry picked from commit f2f96eb605bc770e4da400dbcc7a6d2526ec1fd4) Added: llvm/test/tools/llvm-objcopy/tool-name.test Modified: llvm/tools/llvm-objcopy/llvm-objcopy.cpp Removed: ################################################################################ diff --git a/llvm/test/tools/llvm-objcopy/tool-name.test b/llvm/test/tools/llvm-objcopy/tool-name.test new file mode 100644 index 000000000000..a273375f109e --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/tool-name.test @@ -0,0 +1,33 @@ +## Don't make symlinks on Windows. +# UNSUPPORTED: system-windows + +# RUN: rm -rf %t +# RUN: mkdir %t + +# RUN: ln -s llvm-objcopy %t/llvm-objcopy-11.exe +# RUN: ln -s llvm-objcopy %t/powerpc64-unknown-freebsd13-objcopy + +# RUN: llvm-objcopy --help | FileCheck --check-prefix=OBJCOPY %s +# RUN: %t/llvm-objcopy-11.exe --help | FileCheck --check-prefix=OBJCOPY %s +# RUN: %t/powerpc64-unknown-freebsd13-objcopy --help | FileCheck --check-prefix=OBJCOPY %s + +# OBJCOPY: OVERVIEW: llvm-objcopy tool + +# RUN: ln -s llvm-strip %t/strip.exe +# RUN: ln -s llvm-strip %t/gnu-llvm-strip-10 + +# RUN: llvm-strip --help | FileCheck --check-prefix=STRIP %s +# RUN: %t/strip.exe --help | FileCheck --check-prefix=STRIP %s +# RUN: %t/gnu-llvm-strip-10 --help | FileCheck --check-prefix=STRIP %s + +# STRIP: OVERVIEW: llvm-strip tool + +## This driver emulates install_name_tool on macOS. +# RUN: ln -s llvm-install-name-tool %t/llvm-install-name-tool-10 +# RUN: ln -s llvm-install-name-tool %t/install_name_tool.exe + +# RUN: llvm-install-name-tool --help | FileCheck --check-prefix=INSTALL %s +# RUN: %t/llvm-install-name-tool-10 --help | FileCheck --check-prefix=INSTALL %s +# RUN: %t/install_name_tool.exe --help | FileCheck --check-prefix=INSTALL %s + +# INSTALL: OVERVIEW: llvm-install-name-tool tool diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index e662f35f4b08..4a44a7ab0875 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -322,11 +322,25 @@ enum class ToolType { Objcopy, Strip, InstallNameTool }; int main(int argc, char **argv) { InitLLVM X(argc, argv); ToolName = argv[0]; - ToolType Tool = StringSwitch(sys::path::stem(ToolName)) - .EndsWith("strip", ToolType::Strip) - .EndsWith("install-name-tool", ToolType::InstallNameTool) - .EndsWith("install_name_tool", ToolType::InstallNameTool) - .Default(ToolType::Objcopy); + + StringRef Stem = sys::path::stem(ToolName); + auto Is = [=](StringRef Tool) { + // We need to recognize the following filenames: + // + // llvm-objcopy -> objcopy + // strip-10.exe -> strip + // powerpc64-unknown-freebsd13-objcopy -> objcopy + // llvm-install-name-tool -> install-name-tool + auto I = Stem.rfind_lower(Tool); + return I != StringRef::npos && + (I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()])); + }; + ToolType Tool = ToolType::Objcopy; + if (Is("strip")) + Tool = ToolType::Strip; + else if (Is("install-name-tool") || Is("install_name_tool")) + Tool = ToolType::InstallNameTool; + // Expand response files. // TODO: Move these lines, which are copied from lib/Support/CommandLine.cpp, // into a separate function in the CommandLine library and call that function From llvm-branch-commits at lists.llvm.org Mon Apr 13 07:18:09 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Mon, 13 Apr 2020 07:18:09 -0700 (PDT) Subject: [llvm-branch-commits] [libcxx] 4822f2a - Bump version to 10.0.1 Message-ID: <5e9474a1.1c69fb81.277b9.8ce7@mx.google.com> Author: Tom Stellard Date: 2020-04-13T14:13:36Z New Revision: 4822f2a6154742ab24e0266d6c4b0c2937d22ab7 URL: https://github.com/llvm/llvm-project/commit/4822f2a6154742ab24e0266d6c4b0c2937d22ab7 DIFF: https://github.com/llvm/llvm-project/commit/4822f2a6154742ab24e0266d6c4b0c2937d22ab7.diff LOG: Bump version to 10.0.1 Added: Modified: libcxx/CMakeLists.txt libcxxabi/CMakeLists.txt libunwind/CMakeLists.txt llvm/CMakeLists.txt llvm/utils/gn/secondary/llvm/version.gni llvm/utils/lit/lit/__init__.py llvm/utils/release/build_llvm_package.bat Removed: ################################################################################ diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 1d6ab58166ef..60564dc96c7b 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -27,7 +27,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBCXX_STANDALONE_BUIL project(libcxx CXX C) set(PACKAGE_NAME libcxx) - set(PACKAGE_VERSION 10.0.0) + set(PACKAGE_VERSION 10.0.1) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs at lists.llvm.org") diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt index 59d99971a765..8f9572586b4a 100644 --- a/libcxxabi/CMakeLists.txt +++ b/libcxxabi/CMakeLists.txt @@ -21,7 +21,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBCXXABI_STANDALONE_B project(libcxxabi CXX C) set(PACKAGE_NAME libcxxabi) - set(PACKAGE_VERSION 10.0.0) + set(PACKAGE_VERSION 10.0.1) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs at lists.llvm.org") diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt index 7726511b6e1f..c033069ef1d0 100644 --- a/libunwind/CMakeLists.txt +++ b/libunwind/CMakeLists.txt @@ -83,7 +83,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBUNWIND_STANDALONE_B endif() set(PACKAGE_NAME libunwind) - set(PACKAGE_VERSION 10.0.0) + set(PACKAGE_VERSION 10.0.1) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs at lists.llvm.org") diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index a02c2a5a23f1..bc45df7a3acb 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -22,7 +22,7 @@ if(NOT DEFINED LLVM_VERSION_MINOR) set(LLVM_VERSION_MINOR 0) endif() if(NOT DEFINED LLVM_VERSION_PATCH) - set(LLVM_VERSION_PATCH 0) + set(LLVM_VERSION_PATCH 1) endif() if(NOT DEFINED LLVM_VERSION_SUFFIX) set(LLVM_VERSION_SUFFIX "") diff --git a/llvm/utils/gn/secondary/llvm/version.gni b/llvm/utils/gn/secondary/llvm/version.gni index 39961ef497e4..184e96bdd0b9 100644 --- a/llvm/utils/gn/secondary/llvm/version.gni +++ b/llvm/utils/gn/secondary/llvm/version.gni @@ -1,4 +1,4 @@ llvm_version_major = 10 llvm_version_minor = 0 -llvm_version_patch = 0 +llvm_version_patch = 1 llvm_version = "$llvm_version_major.$llvm_version_minor.$llvm_version_patch" diff --git a/llvm/utils/lit/lit/__init__.py b/llvm/utils/lit/lit/__init__.py index 09e366e1c5cf..2dc89fa0adc6 100644 --- a/llvm/utils/lit/lit/__init__.py +++ b/llvm/utils/lit/lit/__init__.py @@ -2,7 +2,7 @@ __author__ = 'Daniel Dunbar' __email__ = 'daniel at minormatter.com' -__versioninfo__ = (0, 10, 0) +__versioninfo__ = (0, 10, 1) __version__ = '.'.join(str(v) for v in __versioninfo__) + 'dev' __all__ = [] diff --git a/llvm/utils/release/build_llvm_package.bat b/llvm/utils/release/build_llvm_package.bat index a54fd1f0e622..e44941d1eb1f 100755 --- a/llvm/utils/release/build_llvm_package.bat +++ b/llvm/utils/release/build_llvm_package.bat @@ -27,8 +27,8 @@ set python64_dir=C:\Users\%USERNAME%\AppData\Local\Programs\Python\Python36 for /f "usebackq" %%i in (`PowerShell ^(Get-Date^).ToString^('yyyyMMdd'^)`) do set datestamp=%%i set revision=%1 -set package_version=10.0.0-%revision% -set clang_format_vs_version=10.0.0.%datestamp% +set package_version=10.0.1-%revision% +set clang_format_vs_version=10.0.1.%datestamp% set build_dir=llvm_package_%revision% echo Revision: %revision% From llvm-branch-commits at lists.llvm.org Mon Apr 13 12:24:22 2020 From: llvm-branch-commits at lists.llvm.org (via llvm-branch-commits) Date: Mon, 13 Apr 2020 12:24:22 -0700 (PDT) Subject: [llvm-branch-commits] [clang] 68cd4f7 - Use FinishThunk to finish musttail thunks Message-ID: <5e94bc66.1c69fb81.9e34d.f3a8@mx.google.com> Author: Reid Kleckner Date: 2020-04-13T10:34:45-07:00 New Revision: 68cd4f72beae67a9bdbc11c85fd745dec8fc0999 URL: https://github.com/llvm/llvm-project/commit/68cd4f72beae67a9bdbc11c85fd745dec8fc0999 DIFF: https://github.com/llvm/llvm-project/commit/68cd4f72beae67a9bdbc11c85fd745dec8fc0999.diff LOG: Use FinishThunk to finish musttail thunks FinishThunk, and the invariant of setting and then unsetting CurCodeDecl, was added in 7f416cc42638 (2015). The invariant didn't exist when I added this musttail codepath in ab2090d10765 (2014). Recently in 28328c3771, I started using this codepath on non-Windows platforms, and users reported problems during release testing (PR44987). The issue was already present for users of EH on i686-windows-msvc, so I added a test for that case as well. Reviewed By: hans Differential Revision: https://reviews.llvm.org/D76444 (cherry picked from commit ce5173c0e174870934d1b3a026f631d996136191) Added: clang/test/CodeGenCXX/ms-thunks-ehspec.cpp clang/test/CodeGenCXX/thunks-ehspec.cpp Modified: clang/lib/CodeGen/CGVTables.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 59631e802373..e97f7e41499d 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -437,7 +437,8 @@ void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD, // Finish the function to maintain CodeGenFunction invariants. // FIXME: Don't emit unreachable code. EmitBlock(createBasicBlock()); - FinishFunction(); + + FinishThunk(); } void CodeGenFunction::generateThunk(llvm::Function *Fn, @@ -564,7 +565,7 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD, CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn); // Thunks for variadic methods are special because in general variadic - // arguments cannot be perferctly forwarded. In the general case, clang + // arguments cannot be perfectly forwarded. In the general case, clang // implements such thunks by cloning the original function body. However, for // thunks with no return adjustment on targets that support musttail, we can // use musttail to perfectly forward the variadic arguments. diff --git a/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp b/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp new file mode 100644 index 000000000000..f72100d5078b --- /dev/null +++ b/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions %s -triple=i686-windows-msvc -emit-llvm -o - | FileCheck %s + +// When generating thunks using musttail due to inalloca parameters, don't push +// and pop terminate scopes. PR44987 + +struct NonTrivial { + NonTrivial(); + NonTrivial(const NonTrivial &o); + ~NonTrivial(); + int x; +}; +struct A { + virtual void f(NonTrivial o) noexcept; +}; +struct B { + virtual void f(NonTrivial o) noexcept; +}; +class C : A, B { + virtual void f(NonTrivial o) noexcept; +}; +C c; + +// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f at C@@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>* inalloca %0) +// CHECK-NOT: invoke +// CHECK: musttail call x86_thiscallcc void @"?f at C@@EAEXUNonTrivial@@@Z"(%class.C* %{{.*}}, <{ %struct.NonTrivial }>* inalloca %0) +// CHECK-NEXT ret void + diff --git a/clang/test/CodeGenCXX/thunks-ehspec.cpp b/clang/test/CodeGenCXX/thunks-ehspec.cpp new file mode 100644 index 000000000000..30276948d3fc --- /dev/null +++ b/clang/test/CodeGenCXX/thunks-ehspec.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck %s + +// When generating the thunk for secondary, do not push terminate scopes for +// either the varargs or non-varargs case. Related to PR44987. + +struct A { + virtual void primary_key(); +}; +struct B { + virtual void secondary(); + virtual void secondary_vararg(int, ...); +}; +class C : A, B { + virtual void primary_key(); + void secondary() noexcept; + void secondary_vararg(int, ...) noexcept; +}; +void C::primary_key() {} + +// CHECK-LABEL: define available_externally void @_ZThn8_N1C9secondaryEv(%class.C* %this) +// CHECK-NOT: invoke +// CHECK: tail call void @_ZN1C9secondaryEv(%class.C* %{{.*}}) +// CHECK-NOT: invoke +// CHECK: ret void + +// CHECK-LABEL: define available_externally void @_ZThn8_N1C16secondary_varargEiz(%class.C* %this, i32 %0, ...) +// CHECK-NOT: invoke +// CHECK: musttail call void (%class.C*, i32, ...) @_ZN1C16secondary_varargEiz(%class.C* %{{.*}}, i32 %{{.*}}, ...) #2 +// CHECK-NEXT: ret void From llvm-branch-commits at lists.llvm.org Mon Apr 13 13:39:09 2020 From: llvm-branch-commits at lists.llvm.org (via llvm-branch-commits) Date: Mon, 13 Apr 2020 13:39:09 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 47e68d8 - [CodeGen] Fix sinking local values in lpads with phis Message-ID: <5e94cded.1c69fb81.494b1.ed4b@mx.google.com> Author: Reid Kleckner Date: 2020-04-13T13:37:15-07:00 New Revision: 47e68d864420afd42d34fd25e97522e5c149de46 URL: https://github.com/llvm/llvm-project/commit/47e68d864420afd42d34fd25e97522e5c149de46 DIFF: https://github.com/llvm/llvm-project/commit/47e68d864420afd42d34fd25e97522e5c149de46.diff LOG: [CodeGen] Fix sinking local values in lpads with phis There was already a test case for landingpads to handle this case, but I had forgotten to consider PHI instructions preceding the EH_LABEL in the landingpad. PR45261 (cherry picked from commit e5bf5037d869c74bc2faf81fa1f58dfd827e8356) Added: Modified: llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/test/CodeGen/X86/sink-local-value.ll Removed: ################################################################################ diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 8294591b7326..6ecde9b43c07 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -225,6 +225,21 @@ static bool isRegUsedByPhiNodes(unsigned DefReg, return false; } +static bool isTerminatingEHLabel(MachineBasicBlock *MBB, MachineInstr &MI) { + // Ignore non-EH labels. + if (!MI.isEHLabel()) + return false; + + // Any EH label outside a landing pad must be for an invoke. Consider it a + // terminator. + if (!MBB->isEHPad()) + return true; + + // If this is a landingpad, the first non-phi instruction will be an EH_LABEL. + // Don't consider that label to be a terminator. + return MI.getIterator() != MBB->getFirstNonPHI(); +} + /// Build a map of instruction orders. Return the first terminator and its /// order. Consider EH_LABEL instructions to be terminators as well, since local /// values for phis after invokes must be materialized before the call. @@ -233,7 +248,7 @@ void FastISel::InstOrderMap::initialize( unsigned Order = 0; for (MachineInstr &I : *MBB) { if (!FirstTerminator && - (I.isTerminator() || (I.isEHLabel() && &I != &MBB->front()))) { + (I.isTerminator() || isTerminatingEHLabel(MBB, I))) { FirstTerminator = &I; FirstTerminatorOrder = Order; } diff --git a/llvm/test/CodeGen/X86/sink-local-value.ll b/llvm/test/CodeGen/X86/sink-local-value.ll index b0e511ac1189..f7d861ac9b6c 100644 --- a/llvm/test/CodeGen/X86/sink-local-value.ll +++ b/llvm/test/CodeGen/X86/sink-local-value.ll @@ -145,6 +145,42 @@ try.cont: ; preds = %entry, %lpad ; CHECK: retl +define i32 @lpad_phi() personality i32 (...)* @__gxx_personality_v0 { +entry: + store i32 42, i32* @sink_across + invoke void @may_throw() + to label %try.cont unwind label %lpad + +lpad: ; preds = %entry + %p = phi i32 [ 11, %entry ] ; Trivial, but -O0 keeps it + %0 = landingpad { i8*, i32 } + catch i8* null + store i32 %p, i32* @sink_across + br label %try.cont + +try.cont: ; preds = %entry, %lpad + %r.0 = phi i32 [ 13, %entry ], [ 55, %lpad ] + ret i32 %r.0 +} + +; The constant materialization should be *after* the stores to sink_across, but +; before any EH_LABEL. + +; CHECK-LABEL: lpad_phi: +; CHECK: movl $42, sink_across +; CHECK: movl $13, %{{[a-z]*}} +; CHECK: .Ltmp{{.*}}: +; CHECK: calll may_throw +; CHECK: .Ltmp{{.*}}: +; CHECK: jmp .LBB{{.*}} +; CHECK: .LBB{{.*}}: # %lpad +; CHECK-NEXT: .Ltmp{{.*}}: +; CHECK: movl {{.*}}, sink_across +; CHECK: movl $55, %{{[a-z]*}} +; CHECK: .LBB{{.*}}: # %try.cont +; CHECK: retl + + ; Function Attrs: nounwind readnone speculatable declare void @llvm.dbg.value(metadata, metadata, metadata) #0 From llvm-branch-commits at lists.llvm.org Mon Apr 13 13:54:31 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Mon, 13 Apr 2020 13:54:31 -0700 (PDT) Subject: [llvm-branch-commits] [lld] edbe962 - [COFF] Don't treat DWARF sections as GC roots Message-ID: <5e94d187.1c69fb81.93980.d6f0@mx.google.com> Author: Reid Kleckner Date: 2020-04-13T13:48:04-07:00 New Revision: edbe962459da6e3b7b4168118f93a77847b54e02 URL: https://github.com/llvm/llvm-project/commit/edbe962459da6e3b7b4168118f93a77847b54e02 DIFF: https://github.com/llvm/llvm-project/commit/edbe962459da6e3b7b4168118f93a77847b54e02.diff LOG: [COFF] Don't treat DWARF sections as GC roots DWARF sections are typically live and not COMDAT, so they would be treated as GC roots. Enabling DWARF would essentially keep all code with debug info alive, preventing any section GC. Fixes PR45273 Reviewed By: mstorsjo, MaskRay Differential Revision: https://reviews.llvm.org/D76935 (cherry picked from commit c579a5b1d92a9bc2046d00ee2d427832e0f5ddec) Added: lld/test/COFF/gc-dwarf.s Modified: lld/COFF/MarkLive.cpp Removed: ################################################################################ diff --git a/lld/COFF/MarkLive.cpp b/lld/COFF/MarkLive.cpp index 6d34cb864e3c..0afa615a1933 100644 --- a/lld/COFF/MarkLive.cpp +++ b/lld/COFF/MarkLive.cpp @@ -28,10 +28,12 @@ void markLive(ArrayRef chunks) { // as we push, so sections never appear twice in the list. SmallVector worklist; - // COMDAT section chunks are dead by default. Add non-COMDAT chunks. + // COMDAT section chunks are dead by default. Add non-COMDAT chunks. Do not + // traverse DWARF sections. They are live, but they should not keep other + // sections alive. for (Chunk *c : chunks) if (auto *sc = dyn_cast(c)) - if (sc->live) + if (sc->live && !sc->isDWARF()) worklist.push_back(sc); auto enqueue = [&](SectionChunk *c) { diff --git a/lld/test/COFF/gc-dwarf.s b/lld/test/COFF/gc-dwarf.s new file mode 100644 index 000000000000..56b866f4a4ac --- /dev/null +++ b/lld/test/COFF/gc-dwarf.s @@ -0,0 +1,60 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.obj +# RUN: lld-link -lldmap:%t.map -out:%t.exe -opt:ref -entry:main %t.obj -verbose 2>&1 | FileCheck %s +# RUN: FileCheck %s --check-prefix=MAP --input-file=%t.map + +# CHECK: Discarded unused1 +# CHECK-NEXT: Discarded unused2 +# CHECK-NOT: Discarded + +# MAP: In Symbol +# MAP: gc-dwarf.s.tmp.obj:(.text) +# MAP: {{ main$}} +# MAP: gc-dwarf.s.tmp.obj:(.text) +# MAP: {{ used$}} + + .def @feat.00; .scl 3; .type 0; .endef + .globl @feat.00 +.set @feat.00, 0 + + .def main; .scl 2; .type 32; .endef + .section .text,"xr",one_only,main + .globl main +main: + callq used + xorl %eax, %eax + retq + + .def used; .scl 2; .type 32; .endef + .section .text,"xr",one_only,used + .globl used +used: + retq + + + .def unused1; .scl 2; .type 32; .endef + .section .text,"xr",one_only,unused1 + .globl unused1 +unused1: + retq + + .def unused2; .scl 2; .type 32; .endef + .section .text,"xr",one_only,unused2 + .globl unused2 +unused2: + retq + +# This isn't valid DWARF, but LLD doesn't care. Make up some data that +# references the functions above. +.section .debug_info,"r" +.long main at IMGREL +.long unused1 at IMGREL +.long unused2 at IMGREL + +# Similarly, .eh_frame unwind info should not keep functions alive. Again, this +# is not valid unwind info, but it doesn't matter for testing purposes. +.section .eh_frame,"r" +.long main at IMGREL +.long unused1 at IMGREL +.long unused2 at IMGREL From llvm-branch-commits at lists.llvm.org Tue Apr 14 20:09:18 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Tue, 14 Apr 2020 20:09:18 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 321d929 - [DAGCombine] Fix splitting indexed loads in ForwardStoreValueToDirectLoad() Message-ID: <5e967ade.1c69fb81.646ec.b9fc@mx.google.com> Author: Nemanja Ivanovic Date: 2020-04-14T20:05:13-07:00 New Revision: 321d929774c6fa0767e4ae5eb0881ad15e7a4664 URL: https://github.com/llvm/llvm-project/commit/321d929774c6fa0767e4ae5eb0881ad15e7a4664 DIFF: https://github.com/llvm/llvm-project/commit/321d929774c6fa0767e4ae5eb0881ad15e7a4664.diff LOG: [DAGCombine] Fix splitting indexed loads in ForwardStoreValueToDirectLoad() In DAGCombiner::visitLOAD() we perform some checks before breaking up an indexed load. However, we don't do the same checking in ForwardStoreValueToDirectLoad() which can lead to failures later during combining (see: https://bugs.llvm.org/show_bug.cgi?id=45301). This patch just adds the same checks to this function as well. Fixes: https://bugs.llvm.org/show_bug.cgi?id=45301 Differential revision: https://reviews.llvm.org/D76778 (cherry picked from commit 482141134729237072cb94248381dab96ce34374) Added: llvm/test/CodeGen/PowerPC/pr45301.ll Modified: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Removed: ################################################################################ diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 8ff04797c8d8..2476fd26f250 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -886,6 +886,13 @@ static bool isAnyConstantBuildVector(SDValue V, bool NoOpaques = false) { ISD::isBuildVectorOfConstantFPSDNodes(V.getNode()); } +// Determine if this an indexed load with an opaque target constant index. +static bool canSplitIdx(LoadSDNode *LD) { + return MaySplitLoadIndex && + (LD->getOperand(2).getOpcode() != ISD::TargetConstant || + !cast(LD->getOperand(2))->isOpaque()); +} + bool DAGCombiner::reassociationCanBreakAddressingModePattern(unsigned Opc, const SDLoc &DL, SDValue N0, @@ -14222,11 +14229,11 @@ SDValue DAGCombiner::ForwardStoreValueToDirectLoad(LoadSDNode *LD) { auto ReplaceLd = [&](LoadSDNode *LD, SDValue Val, SDValue Chain) -> SDValue { if (LD->isIndexed()) { - bool IsSub = (LD->getAddressingMode() == ISD::PRE_DEC || - LD->getAddressingMode() == ISD::POST_DEC); - unsigned Opc = IsSub ? ISD::SUB : ISD::ADD; - SDValue Idx = DAG.getNode(Opc, SDLoc(LD), LD->getOperand(1).getValueType(), - LD->getOperand(1), LD->getOperand(2)); + // Cannot handle opaque target constants and we must respect the user's + // request not to split indexes from loads. + if (!canSplitIdx(LD)) + return SDValue(); + SDValue Idx = SplitIndexingFromLoad(LD); SDValue Ops[] = {Val, Idx, Chain}; return CombineTo(LD, Ops, 3); } @@ -14322,14 +14329,12 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { // the indexing into an add/sub directly (that TargetConstant may not be // valid for a diff erent type of node, and we cannot convert an opaque // target constant into a regular constant). - bool HasOTCInc = LD->getOperand(2).getOpcode() == ISD::TargetConstant && - cast(LD->getOperand(2))->isOpaque(); + bool CanSplitIdx = canSplitIdx(LD); - if (!N->hasAnyUseOfValue(0) && - ((MaySplitLoadIndex && !HasOTCInc) || !N->hasAnyUseOfValue(1))) { + if (!N->hasAnyUseOfValue(0) && (CanSplitIdx || !N->hasAnyUseOfValue(1))) { SDValue Undef = DAG.getUNDEF(N->getValueType(0)); SDValue Index; - if (N->hasAnyUseOfValue(1) && MaySplitLoadIndex && !HasOTCInc) { + if (N->hasAnyUseOfValue(1) && CanSplitIdx) { Index = SplitIndexingFromLoad(LD); // Try to fold the base pointer arithmetic into subsequent loads and // stores. diff --git a/llvm/test/CodeGen/PowerPC/pr45301.ll b/llvm/test/CodeGen/PowerPC/pr45301.ll new file mode 100644 index 000000000000..ee0c6c341cc0 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/pr45301.ll @@ -0,0 +1,58 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=powerpc64-- -verify-machineinstrs \ +; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s +%struct.e.0.1.2.3.12.29 = type { [10 x i32] } + +define dso_local void @g(%struct.e.0.1.2.3.12.29* %agg.result) local_unnamed_addr #0 { +; CHECK-LABEL: g: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mflr r0 +; CHECK-NEXT: std r0, 16(r1) +; CHECK-NEXT: stdu r1, -112(r1) +; CHECK-NEXT: bl i +; CHECK-NEXT: nop +; CHECK-NEXT: addis r4, r2, g at toc@ha +; CHECK-NEXT: addi r4, r4, g at toc@l +; CHECK-NEXT: ld r5, 0(r4) +; CHECK-NEXT: std r5, 0(r3) +; CHECK-NEXT: ld r5, 16(r4) +; CHECK-NEXT: std r5, 16(r3) +; CHECK-NEXT: ld r6, 8(r4) +; CHECK-NEXT: std r6, 8(r3) +; CHECK-NEXT: ld r6, 24(r4) +; CHECK-NEXT: std r6, 24(r3) +; CHECK-NEXT: lwz r6, 0(r3) +; CHECK-NEXT: ld r4, 32(r4) +; CHECK-NEXT: std r4, 32(r3) +; CHECK-NEXT: li r4, 20 +; CHECK-NEXT: stwbrx r6, 0, r3 +; CHECK-NEXT: stwbrx r5, r3, r4 +; CHECK-NEXT: addi r1, r1, 112 +; CHECK-NEXT: ld r0, 16(r1) +; CHECK-NEXT: mtlr r0 +; CHECK-NEXT: blr +entry: + %call = tail call signext i32 bitcast (i32 (...)* @i to i32 ()*)() + %conv = sext i32 %call to i64 + %0 = inttoptr i64 %conv to i8* + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(40) %0, i8* nonnull align 4 dereferenceable(40) bitcast (void (%struct.e.0.1.2.3.12.29*)* @g to i8*), i64 40, i1 false) + %1 = inttoptr i64 %conv to i32* + %2 = load i32, i32* %1, align 4 + %rev.i = tail call i32 @llvm.bswap.i32(i32 %2) + store i32 %rev.i, i32* %1, align 4 + %incdec.ptr.i.4 = getelementptr inbounds i32, i32* %1, i64 5 + %3 = load i32, i32* %incdec.ptr.i.4, align 4 + %rev.i.5 = tail call i32 @llvm.bswap.i32(i32 %3) + store i32 %rev.i.5, i32* %incdec.ptr.i.4, align 4 + ret void +} + +declare i32 @i(...) local_unnamed_addr + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1 + +; Function Attrs: nounwind readnone speculatable willreturn +declare i32 @llvm.bswap.i32(i32) + +attributes #0 = { nounwind } From llvm-branch-commits at lists.llvm.org Tue Apr 14 20:33:41 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Tue, 14 Apr 2020 20:33:41 -0700 (PDT) Subject: [llvm-branch-commits] [clang] e3ac79a - Teach TreeTransform to substitute into resolved TemplateArguments. Message-ID: <5e968095.1c69fb81.cefdf.a885@mx.google.com> Author: Richard Smith Date: 2020-04-14T20:32:00-07:00 New Revision: e3ac79a649056865d47815446a95503bd4bd8908 URL: https://github.com/llvm/llvm-project/commit/e3ac79a649056865d47815446a95503bd4bd8908 DIFF: https://github.com/llvm/llvm-project/commit/e3ac79a649056865d47815446a95503bd4bd8908.diff LOG: Teach TreeTransform to substitute into resolved TemplateArguments. This comes up when substituting into an already-substituted template argument during constraint satisfaction checking. (cherry picked from commit b20ab412bf838a8a87e5cc1c8c6399c3c9255354) Added: clang/test/SemaTemplate/subst-into-subst.cpp Modified: clang/lib/Sema/TreeTransform.h Removed: ################################################################################ diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 0305954a278e..30fb089742ee 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4022,50 +4022,8 @@ template void TreeTransform::InventTemplateArgumentLoc( const TemplateArgument &Arg, TemplateArgumentLoc &Output) { - SourceLocation Loc = getDerived().getBaseLocation(); - switch (Arg.getKind()) { - case TemplateArgument::Null: - llvm_unreachable("null template argument in TreeTransform"); - break; - - case TemplateArgument::Type: - Output = TemplateArgumentLoc(Arg, - SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc)); - - break; - - case TemplateArgument::Template: - case TemplateArgument::TemplateExpansion: { - NestedNameSpecifierLocBuilder Builder; - TemplateName Template = Arg.getAsTemplateOrTemplatePattern(); - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) - Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc); - else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc); - - if (Arg.getKind() == TemplateArgument::Template) - Output = TemplateArgumentLoc(Arg, - Builder.getWithLocInContext(SemaRef.Context), - Loc); - else - Output = TemplateArgumentLoc(Arg, - Builder.getWithLocInContext(SemaRef.Context), - Loc, Loc); - - break; - } - - case TemplateArgument::Expression: - Output = TemplateArgumentLoc(Arg, Arg.getAsExpr()); - break; - - case TemplateArgument::Declaration: - case TemplateArgument::Integral: - case TemplateArgument::Pack: - case TemplateArgument::NullPtr: - Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo()); - break; - } + Output = getSema().getTrivialTemplateArgumentLoc( + Arg, QualType(), getDerived().getBaseLocation()); } template @@ -4075,12 +4033,45 @@ bool TreeTransform::TransformTemplateArgument( const TemplateArgument &Arg = Input.getArgument(); switch (Arg.getKind()) { case TemplateArgument::Null: - case TemplateArgument::Integral: case TemplateArgument::Pack: - case TemplateArgument::Declaration: - case TemplateArgument::NullPtr: llvm_unreachable("Unexpected TemplateArgument"); + case TemplateArgument::Integral: + case TemplateArgument::NullPtr: + case TemplateArgument::Declaration: { + // Transform a resolved template argument straight to a resolved template + // argument. We get here when substituting into an already-substituted + // template type argument during concept satisfaction checking. + QualType T = Arg.getNonTypeTemplateArgumentType(); + QualType NewT = getDerived().TransformType(T); + if (NewT.isNull()) + return true; + + ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration + ? Arg.getAsDecl() + : nullptr; + ValueDecl *NewD = D ? cast_or_null(getDerived().TransformDecl( + getDerived().getBaseLocation(), D)) + : nullptr; + if (D && !NewD) + return true; + + if (NewT == T && D == NewD) + Output = Input; + else if (Arg.getKind() == TemplateArgument::Integral) + Output = TemplateArgumentLoc( + TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT), + TemplateArgumentLocInfo()); + else if (Arg.getKind() == TemplateArgument::NullPtr) + Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true), + TemplateArgumentLocInfo()); + else + Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT), + TemplateArgumentLocInfo()); + + return false; + } + case TemplateArgument::Type: { TypeSourceInfo *DI = Input.getTypeSourceInfo(); if (!DI) diff --git a/clang/test/SemaTemplate/subst-into-subst.cpp b/clang/test/SemaTemplate/subst-into-subst.cpp new file mode 100644 index 000000000000..69c4a837864d --- /dev/null +++ b/clang/test/SemaTemplate/subst-into-subst.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s + +// When forming and checking satisfaction of atomic constraints, we will +// substitute still-dependent template arguments into an expression, and later +// substitute into the result. This creates some unique situations; check that +// they work. + +namespace SubstIntoResolvedTypeTemplateArg { + template struct X {}; + + template concept A = true; + template concept B = sizeof(T) != 0; + template concept C = B>; + + int f(A auto); // expected-note {{candidate}} + int f(C auto); // expected-note {{candidate}} + int k1 = f(0); // expected-error {{ambiguous}} + + template concept D = A && B>; + int f(D auto); + int k2 = f(0); // ok + + // The atomic constraint formed from B> is identical to the + // one formed from C, even though the template arguments are written as + // diff erent expressions; the "equivalent" rules are used rather than the + // "identical" rules when matching template arguments in concept-ids. + template concept E = A && B>; + int g(C auto); + int g(E auto); // expected-note {{candidate}} + int k3 = g(0); + + int g(D auto); // expected-note {{candidate}} + int k4 = g(0); // expected-error {{ambiguous}} +} From llvm-branch-commits at lists.llvm.org Tue Apr 14 22:36:17 2020 From: llvm-branch-commits at lists.llvm.org (Fangrui Song via llvm-branch-commits) Date: Tue, 14 Apr 2020 22:36:17 -0700 (PDT) Subject: [llvm-branch-commits] [lld] b6ccc88 - [ELF][test] Rename SHF_LINK_ORDER related "metadata" to "linkorder" Message-ID: <5e969d51.1c69fb81.51093.b930@mx.google.com> Author: Fangrui Song Date: 2020-04-14T22:31:55-07:00 New Revision: b6ccc88d575c78cb6cfebf545ef2c8d159cbdf3c URL: https://github.com/llvm/llvm-project/commit/b6ccc88d575c78cb6cfebf545ef2c8d159cbdf3c DIFF: https://github.com/llvm/llvm-project/commit/b6ccc88d575c78cb6cfebf545ef2c8d159cbdf3c.diff LOG: [ELF][test] Rename SHF_LINK_ORDER related "metadata" to "linkorder" Test cleanups. (cherry picked from commit b305b8a256eade076bb13f52668a6015631ac0e5) Added: lld/test/ELF/gc-sections-linkorder-err.s lld/test/ELF/gc-sections-linkorder.s lld/test/ELF/gc-sections-linkorder2.s lld/test/ELF/linkerscript/discard-linkorder.s lld/test/ELF/linkerscript/linkorder.s lld/test/ELF/linkerscript/linkorder2.s lld/test/ELF/linkorder-err.s lld/test/ELF/linkorder-err2.s lld/test/ELF/linkorder-err3.s Modified: Removed: lld/test/ELF/gc-sections-metadata-err.s lld/test/ELF/gc-sections-metadata.s lld/test/ELF/gc-sections-metadata2.s lld/test/ELF/linkerscript/discard-section-metadata.s lld/test/ELF/linkerscript/section-metadata.s lld/test/ELF/linkerscript/section-metadata2.s lld/test/ELF/section-metadata-err.s lld/test/ELF/section-metadata-err2.s lld/test/ELF/section-metadata-err3.s ################################################################################ diff --git a/lld/test/ELF/gc-sections-metadata-err.s b/lld/test/ELF/gc-sections-linkorder-err.s similarity index 100% rename from lld/test/ELF/gc-sections-metadata-err.s rename to lld/test/ELF/gc-sections-linkorder-err.s diff --git a/lld/test/ELF/gc-sections-linkorder.s b/lld/test/ELF/gc-sections-linkorder.s new file mode 100644 index 000000000000..54a29abde8e1 --- /dev/null +++ b/lld/test/ELF/gc-sections-linkorder.s @@ -0,0 +1,32 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: ld.lld --gc-sections --print-gc-sections %t.o -o /dev/null | FileCheck %s --implicit-check-not=removing + +# CHECK: removing unused section {{.*}}.o:(.foo2) +# CHECK: removing unused section {{.*}}.o:(bar2) +# CHECK: removing unused section {{.*}}.o:(.zed2) + +.global _start +_start: +.quad .foo1 + +.section .foo1,"a" +.quad 0 + +.section .foo2,"a" +.quad 0 + +.section bar1,"ao", at progbits,.foo1 +.quad .zed1 +.quad .foo1 + +.section bar2,"ao", at progbits,.foo2 +.quad .zed2 +.quad .foo2 + +.section .zed1,"a" +.quad 0 + +.section .zed2,"a" +.quad 0 diff --git a/lld/test/ELF/gc-sections-metadata2.s b/lld/test/ELF/gc-sections-linkorder2.s similarity index 60% rename from lld/test/ELF/gc-sections-metadata2.s rename to lld/test/ELF/gc-sections-linkorder2.s index 3a3b640b280a..b22bc589f56e 100644 --- a/lld/test/ELF/gc-sections-metadata2.s +++ b/lld/test/ELF/gc-sections-linkorder2.s @@ -1,16 +1,13 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: ld.lld --gc-sections %t.o -o %t -# RUN: llvm-objdump -section-headers %t | FileCheck %s -# CHECK: .foo -# CHECK: .bar -# CHECK: .zed +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld --gc-sections --print-gc-sections %t.o -o /dev/null | count 0 .globl _start _start: .quad .foo +## .foo is retained, so sections linking to it are retained as well. .section .foo,"a" .quad 0 .section .bar,"ao", at progbits,.foo diff --git a/lld/test/ELF/gc-sections-metadata.s b/lld/test/ELF/gc-sections-metadata.s deleted file mode 100644 index 2e696f8752bd..000000000000 --- a/lld/test/ELF/gc-sections-metadata.s +++ /dev/null @@ -1,38 +0,0 @@ -# REQUIRES: x86 - -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: ld.lld --gc-sections %t.o -o %t -# RUN: llvm-objdump -section-headers %t | FileCheck %s - -# CHECK: 1 .foo1 -# CHECK-NEXT: bar1 -# CHECK-NEXT: .zed1 -# CHECK-NEXT: .text -# CHECK-NEXT: .comment -# CHECK-NEXT: .symtab -# CHECK-NEXT: .shstrtab -# CHECK-NEXT: .strtab - -.global _start -_start: -.quad .foo1 - -.section .foo1,"a" -.quad 0 - -.section .foo2,"a" -.quad 0 - -.section bar1,"ao", at progbits,.foo1 -.quad .zed1 -.quad .foo1 - -.section bar2,"ao", at progbits,.foo2 -.quad .zed2 -.quad .foo2 - -.section .zed1,"a" -.quad 0 - -.section .zed2,"a" -.quad 0 diff --git a/lld/test/ELF/linkerscript/discard-section-metadata.s b/lld/test/ELF/linkerscript/discard-linkorder.s similarity index 100% rename from lld/test/ELF/linkerscript/discard-section-metadata.s rename to lld/test/ELF/linkerscript/discard-linkorder.s diff --git a/lld/test/ELF/linkerscript/section-metadata.s b/lld/test/ELF/linkerscript/linkorder.s similarity index 100% rename from lld/test/ELF/linkerscript/section-metadata.s rename to lld/test/ELF/linkerscript/linkorder.s diff --git a/lld/test/ELF/linkerscript/section-metadata2.s b/lld/test/ELF/linkerscript/linkorder2.s similarity index 100% rename from lld/test/ELF/linkerscript/section-metadata2.s rename to lld/test/ELF/linkerscript/linkorder2.s diff --git a/lld/test/ELF/linkorder-err.s b/lld/test/ELF/linkorder-err.s new file mode 100644 index 000000000000..85409ecfc9ef --- /dev/null +++ b/lld/test/ELF/linkorder-err.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s + +# CHECK: error: a section .foo with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}.o:(.merge) + +.section .merge,"aM", at progbits,8 +.quad 0 +.section .foo,"ao", at progbits,.merge +.quad 0 diff --git a/lld/test/ELF/section-metadata-err2.s b/lld/test/ELF/linkorder-err2.s similarity index 55% rename from lld/test/ELF/section-metadata-err2.s rename to lld/test/ELF/linkorder-err2.s index 3191c1f4d3b6..ccacd00768b2 100644 --- a/lld/test/ELF/section-metadata-err2.s +++ b/lld/test/ELF/linkorder-err2.s @@ -4,8 +4,8 @@ # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s ## Check we do not crash and report proper errors. -# CHECK: error: a section .bar with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}section-metadata-err2.s.tmp.o:(.foo) -# CHECK: error: a section .bar with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}section-metadata-err2.s.tmp.o:(.foo) +# CHECK: error: a section .bar with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}.o:(.foo) +# CHECK-NEXT: error: a section .bar with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}.o:(.foo) .section .foo,"aM", at progbits,8 .quad 0 diff --git a/lld/test/ELF/section-metadata-err3.s b/lld/test/ELF/linkorder-err3.s similarity index 85% rename from lld/test/ELF/section-metadata-err3.s rename to lld/test/ELF/linkorder-err3.s index 5c4875b9da5e..2e36ab457677 100644 --- a/lld/test/ELF/section-metadata-err3.s +++ b/lld/test/ELF/linkorder-err3.s @@ -4,7 +4,7 @@ # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s # CHECK: error: incompatible section flags for .bar -# CHECK-NEXT: >>> {{.*}}section-metadata-err3.s.tmp.o:(.bar): 0x2 +# CHECK-NEXT: >>> {{.*}}.o:(.bar): 0x2 # CHECK-NEXT: >>> output section .bar: 0x82 .section .foo,"a", at progbits diff --git a/lld/test/ELF/section-metadata-err.s b/lld/test/ELF/section-metadata-err.s deleted file mode 100644 index c9104303e434..000000000000 --- a/lld/test/ELF/section-metadata-err.s +++ /dev/null @@ -1,15 +0,0 @@ -# REQUIRES: x86 - -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s - -# CHECK: error: a section .bar with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}section-metadata-err.s.tmp.o:(.foo) - -.global _start -_start: -.quad .foo - -.section .foo,"aM", at progbits,8 -.quad 0 - -.section .bar,"ao", at progbits,.foo From llvm-branch-commits at lists.llvm.org Tue Apr 14 22:36:19 2020 From: llvm-branch-commits at lists.llvm.org (Fangrui Song via llvm-branch-commits) Date: Tue, 14 Apr 2020 22:36:19 -0700 (PDT) Subject: [llvm-branch-commits] [lld] b2881de - [ELF][test] Improve linkerscript/linkorder.s Message-ID: <5e969d53.1c69fb81.f0b8d.024a@mx.google.com> Author: Fangrui Song Date: 2020-04-14T22:35:18-07:00 New Revision: b2881de649ca27bd00942a4dc6b0e3a0f7e7f32f URL: https://github.com/llvm/llvm-project/commit/b2881de649ca27bd00942a4dc6b0e3a0f7e7f32f DIFF: https://github.com/llvm/llvm-project/commit/b2881de649ca27bd00942a4dc6b0e3a0f7e7f32f.diff LOG: [ELF][test] Improve linkerscript/linkorder.s (cherry picked from commit 2d19270efcf01672c8eaab1ccb0e5b89ea953cc9) Added: Modified: lld/test/ELF/linkerscript/linkorder.s Removed: ################################################################################ diff --git a/lld/test/ELF/linkerscript/linkorder.s b/lld/test/ELF/linkerscript/linkorder.s index 44547b8ab002..118c2e6b073d 100644 --- a/lld/test/ELF/linkerscript/linkorder.s +++ b/lld/test/ELF/linkerscript/linkorder.s @@ -1,33 +1,63 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { .text : { *(.text.bar) *(.text.foo) } }" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-objdump -s %t | FileCheck %s +## Contiguous SHF_LINK_ORDER sections. +# RUN: echo 'SECTIONS { .rodata : {BYTE(0) *(.rodata*) BYTE(3)} \ +# RUN: .text : {*(.text.bar) *(.text.foo)} }' > %t.lds +# RUN: ld.lld -T %t.lds %t.o -o %t +# RUN: llvm-readelf -S -x .rodata -x .text %t | FileCheck %s -# RUN: echo "SECTIONS { .text : { *(.text.foo) *(.text.bar) } }" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-objdump -s %t | FileCheck --check-prefix=INV %s +# CHECK: Hex dump of section '.rodata': +# CHECK-NEXT: 00020103 +# CHECK: Hex dump of section '.text': +# CHECK-NEXT: 0201 +# RUN: echo 'SECTIONS { .rodata : {BYTE(0) *(.rodata*) BYTE(3)} \ +# RUN: .text : {*(.text.foo) *(.text.bar)} }' > %t1.lds +# RUN: ld.lld -T %t1.lds %t.o -o %t1 +# RUN: llvm-readelf -S -x .rodata -x .text %t1 | FileCheck --check-prefix=CHECK1 %s -# CHECK: Contents of section .rodata: -# CHECK-NEXT: 02000000 00000000 01000000 00000000 -# CHECK: Contents of section .text: -# CHECK-NEXT: 02000000 00000000 01000000 00000000 +# CHECK1: Hex dump of section '.rodata': +# CHECK1-NEXT: 00010203 +# CHECK1: Hex dump of section '.text': +# CHECK1-NEXT: 0102 -# INV: Contents of section .rodata: -# INV-NEXT: 01000000 00000000 02000000 00000000 -# INV: Contents of section .text: -# INV-NEXT: 01000000 00000000 02000000 00000000 +## Adjacent input sections descriptions are contiguous. +## Orphan section .text.bar precedes .text.foo, so swap the order of .rodata.* +# RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) *(.rodata.bar)} }' > %t2.lds +# RUN: ld.lld -T %t2.lds %t.o -o %t2 +# RUN: llvm-readelf -S -x .rodata %t2 | FileCheck --check-prefix=CHECK2 %s + +# CHECK2: [ 1] .rodata {{.*}} AL 3 +# CHECK2: [ 3] .text {{.*}} AX 0 +# CHECK2: Hex dump of section '.rodata': +# CHECK2-NEXT: 0201 + +## Non-contiguous SHF_LINK_ORDER sections, separated by a BYTE. +# RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) BYTE(0) *(.rodata.bar)} }' > %terr1.lds +# RUN: ld.lld -T %terr1.lds %t.o -o /dev/null + +## Non-contiguous SHF_LINK_ORDER sections, separated by a non-SHF_LINK_ORDER section. +# RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) *(.text) *(.rodata.bar)} }' > %terr2.lds +# RUN: not ld.lld -T %terr2.lds %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s + +## Non-contiguous SHF_LINK_ORDER sections, separated by a symbol assignment. +# RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) a = .; *(.rodata.bar)} }' > %terr3.lds +# RUN: ld.lld -T %terr3.lds %t.o -o /dev/null + +# ERR: error: incompatible section flags for .rodata .global _start _start: +.section .ro,"a" +.byte 0 + .section .text.bar,"a", at progbits -.quad 2 +.byte 2 .section .text.foo,"a", at progbits -.quad 1 +.byte 1 .section .rodata.foo,"ao", at progbits,.text.foo -.quad 1 +.byte 1 .section .rodata.bar,"ao", at progbits,.text.bar -.quad 2 +.byte 2 From llvm-branch-commits at lists.llvm.org Tue Apr 14 22:36:21 2020 From: llvm-branch-commits at lists.llvm.org (Fangrui Song via llvm-branch-commits) Date: Tue, 14 Apr 2020 22:36:21 -0700 (PDT) Subject: [llvm-branch-commits] [lld] 71c3f57 - [ELF] Allow SHF_LINK_ORDER and non-SHF_LINK_ORDER to be mixed Message-ID: <5e969d55.1c69fb81.d543c.6f74@mx.google.com> Author: Fangrui Song Date: 2020-04-14T22:35:46-07:00 New Revision: 71c3f57326cf956330f47f9061104e0f299cb7cf URL: https://github.com/llvm/llvm-project/commit/71c3f57326cf956330f47f9061104e0f299cb7cf DIFF: https://github.com/llvm/llvm-project/commit/71c3f57326cf956330f47f9061104e0f299cb7cf.diff LOG: [ELF] Allow SHF_LINK_ORDER and non-SHF_LINK_ORDER to be mixed Currently, `error: incompatible section flags for .rodata` is reported when we mix SHF_LINK_ORDER and non-SHF_LINK_ORDER sections in an output section. This is overconstrained. This patch allows mixed flags with the requirement that SHF_LINK_ORDER sections must be contiguous. Mixing flags is used by Linux aarch64 (https://github.com/ClangBuiltLinux/linux/issues/953) .init.data : { ... KEEP(*(__patchable_function_entries)) ... } When the integrated assembler is enabled, clang's -fpatchable-function-entry=N[,M] implementation sets the SHF_LINK_ORDER flag (D72215) to fix a number of garbage collection issues. Strictly speaking, the ELF specification does not require contiguous SHF_LINK_ORDER sections but for many current uses of SHF_LINK_ORDER like .ARM.exidx/__patchable_function_entries there has been a requirement for the sections to be contiguous on top of the requirements of the ELF specification. This patch also imposes one restriction: SHF_LINK_ORDER sections cannot be separated by a symbol assignment or a BYTE command. Not allowing BYTE is a natural extension that a non-SHF_LINK_ORDER cannot be a separator. Symbol assignments can delimiter the contents of SHF_LINK_ORDER sections. Allowing SHF_LINK_ORDER sections across symbol assignments (especially __start_/__stop_) can make things hard to explain. The restriction should not be a problem for practical use cases. Reviewed By: psmith Differential Revision: https://reviews.llvm.org/D77007 (cherry picked from commit 673e81eee4fa3ffa38736f1063e6c4fa2d9278b0) Added: Modified: lld/ELF/OutputSections.cpp lld/ELF/Writer.cpp lld/test/ELF/linkerscript/linkorder.s Removed: lld/test/ELF/linkorder-err3.s ################################################################################ diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 6142cb0783ce..b609878be319 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -114,8 +114,7 @@ void OutputSection::commitSection(InputSection *isec) { flags = isec->flags; } else { // Otherwise, check if new type or flags are compatible with existing ones. - unsigned mask = SHF_TLS | SHF_LINK_ORDER; - if ((flags & mask) != (isec->flags & mask)) + if ((flags ^ isec->flags) & SHF_TLS) error("incompatible section flags for " + name + "\n>>> " + toString(isec) + ": 0x" + utohexstr(isec->flags) + "\n>>> output section " + name + ": 0x" + utohexstr(flags)); @@ -367,8 +366,9 @@ void OutputSection::finalize() { // all InputSections in the OutputSection have the same dependency. if (auto *ex = dyn_cast(first)) link = ex->getLinkOrderDep()->getParent()->sectionIndex; - else if (auto *d = first->getLinkOrderDep()) - link = d->getParent()->sectionIndex; + else if (first->flags & SHF_LINK_ORDER) + if (auto *d = first->getLinkOrderDep()) + link = d->getParent()->sectionIndex; } if (type == SHT_GROUP) { diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index ac332de2a057..713c54dee509 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1523,17 +1523,30 @@ template void Writer::resolveShfLinkOrder() { // but sort must consider them all at once. std::vector scriptSections; std::vector sections; + bool started = false, stopped = false; for (BaseCommand *base : sec->sectionCommands) { if (auto *isd = dyn_cast(base)) { for (InputSection *&isec : isd->sections) { - scriptSections.push_back(&isec); - sections.push_back(isec); - - InputSection *link = isec->getLinkOrderDep(); - if (!link->getParent()) - error(toString(isec) + ": sh_link points to discarded section " + - toString(link)); + if (!(isec->flags & SHF_LINK_ORDER)) { + if (started) + stopped = true; + } else if (stopped) { + error(toString(isec) + ": SHF_LINK_ORDER sections in " + sec->name + + " are not contiguous"); + } else { + started = true; + + scriptSections.push_back(&isec); + sections.push_back(isec); + + InputSection *link = isec->getLinkOrderDep(); + if (!link->getParent()) + error(toString(isec) + ": sh_link points to discarded section " + + toString(link)); + } } + } else if (started) { + stopped = true; } } diff --git a/lld/test/ELF/linkerscript/linkorder.s b/lld/test/ELF/linkerscript/linkorder.s index 118c2e6b073d..eab4819af8c1 100644 --- a/lld/test/ELF/linkerscript/linkorder.s +++ b/lld/test/ELF/linkerscript/linkorder.s @@ -7,6 +7,8 @@ # RUN: ld.lld -T %t.lds %t.o -o %t # RUN: llvm-readelf -S -x .rodata -x .text %t | FileCheck %s +# CHECK: [ 1] .rodata {{.*}} AL 3 +# CHECK: [ 3] .text {{.*}} AX 0 # CHECK: Hex dump of section '.rodata': # CHECK-NEXT: 00020103 # CHECK: Hex dump of section '.text': @@ -17,6 +19,8 @@ # RUN: ld.lld -T %t1.lds %t.o -o %t1 # RUN: llvm-readelf -S -x .rodata -x .text %t1 | FileCheck --check-prefix=CHECK1 %s +# CHECK1: [ 1] .rodata {{.*}} AL 3 +# CHECK1: [ 3] .text {{.*}} AX 0 # CHECK1: Hex dump of section '.rodata': # CHECK1-NEXT: 00010203 # CHECK1: Hex dump of section '.text': @@ -35,7 +39,7 @@ ## Non-contiguous SHF_LINK_ORDER sections, separated by a BYTE. # RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) BYTE(0) *(.rodata.bar)} }' > %terr1.lds -# RUN: ld.lld -T %terr1.lds %t.o -o /dev/null +# RUN: not ld.lld -T %terr1.lds %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s ## Non-contiguous SHF_LINK_ORDER sections, separated by a non-SHF_LINK_ORDER section. # RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) *(.text) *(.rodata.bar)} }' > %terr2.lds @@ -43,9 +47,9 @@ ## Non-contiguous SHF_LINK_ORDER sections, separated by a symbol assignment. # RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) a = .; *(.rodata.bar)} }' > %terr3.lds -# RUN: ld.lld -T %terr3.lds %t.o -o /dev/null +# RUN: not ld.lld -T %terr3.lds %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s -# ERR: error: incompatible section flags for .rodata +# ERR: error: {{.*}}.o:(.rodata.bar): SHF_LINK_ORDER sections in .rodata are not contiguous .global _start _start: diff --git a/lld/test/ELF/linkorder-err3.s b/lld/test/ELF/linkorder-err3.s deleted file mode 100644 index 2e36ab457677..000000000000 --- a/lld/test/ELF/linkorder-err3.s +++ /dev/null @@ -1,17 +0,0 @@ -# REQUIRES: x86 - -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s - -# CHECK: error: incompatible section flags for .bar -# CHECK-NEXT: >>> {{.*}}.o:(.bar): 0x2 -# CHECK-NEXT: >>> output section .bar: 0x82 - -.section .foo,"a", at progbits -.quad 0 - -.section .bar,"ao", at progbits,.foo,unique,1 -.quad 0 - -.section .bar,"a", at progbits,unique,2 -.quad 1 From llvm-branch-commits at lists.llvm.org Wed Apr 15 15:08:55 2020 From: llvm-branch-commits at lists.llvm.org (Matthias Gehre via llvm-branch-commits) Date: Wed, 15 Apr 2020 15:08:55 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 79060d2 - [LifetimeAnalysis] Add [[gsl::Pointer]] to llvm::StringRef Message-ID: <5e9785f7.1c69fb81.fd610.22ad@mx.google.com> Author: Matthias Gehre Date: 2020-04-16T00:08:41+02:00 New Revision: 79060d2ea122a28f595e719432fbafa18f3b9eb9 URL: https://github.com/llvm/llvm-project/commit/79060d2ea122a28f595e719432fbafa18f3b9eb9 DIFF: https://github.com/llvm/llvm-project/commit/79060d2ea122a28f595e719432fbafa18f3b9eb9.diff LOG: [LifetimeAnalysis] Add [[gsl::Pointer]] to llvm::StringRef Summary: This detected the bugs fixed in https://reviews.llvm.org/D66442 and https://reviews.llvm.org/D66440 The warning itself was implemented in https://reviews.llvm.org/D63954 https://reviews.llvm.org/D64256 https://reviews.llvm.org/D65120 https://reviews.llvm.org/D65127 https://reviews.llvm.org/D66152 Reviewers: zturner, mehdi_amini, gribozavr Subscribers: dexonsmith, Szelethus, xazax.hun, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66443 Added: Modified: llvm/include/llvm/ADT/StringRef.h Removed: ################################################################################ diff --git a/llvm/include/llvm/ADT/StringRef.h b/llvm/include/llvm/ADT/StringRef.h index ad31517a1ea7..337efd641135 100644 --- a/llvm/include/llvm/ADT/StringRef.h +++ b/llvm/include/llvm/ADT/StringRef.h @@ -54,7 +54,7 @@ namespace llvm { /// situations where the character data resides in some other buffer, whose /// lifetime extends past that of the StringRef. For this reason, it is not in /// general safe to store a StringRef. - class StringRef { + class [[gsl::Pointer]] StringRef { public: static const size_t npos = ~size_t(0); From llvm-branch-commits at lists.llvm.org Thu Apr 16 11:12:29 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Thu, 16 Apr 2020 11:12:29 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 5fbba36 - [SimplifyCFG] Skip merging return blocks if it would break a CallBr. Message-ID: <5e98a00d.1c69fb81.22f73.ca35@mx.google.com> Author: Jonas Paulsson Date: 2020-04-16T11:12:13-07:00 New Revision: 5fbba36cbe93f12da5c4d6063db21cf35ecc9bfc URL: https://github.com/llvm/llvm-project/commit/5fbba36cbe93f12da5c4d6063db21cf35ecc9bfc DIFF: https://github.com/llvm/llvm-project/commit/5fbba36cbe93f12da5c4d6063db21cf35ecc9bfc.diff LOG: [SimplifyCFG] Skip merging return blocks if it would break a CallBr. SimplifyCFG should not merge empty return blocks and leave a CallBr behind with a duplicated destination since the verifier will then trigger an assert. This patch checks for this case and avoids the transformation. CodeGenPrepare has a similar check which also has a FIXME comment about why this is needed. It seems perhaps better if these two passes would eventually instead update the CallBr instruction instead of just checking and avoiding. This fixes https://bugs.llvm.org/show_bug.cgi?id=45062. Review: Craig Topper Differential Revision: https://reviews.llvm.org/D75620 (cherry picked from commit c2dafe12dc24f7f1326f5c4c6a3b23f1485f1bd6) Added: llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll Modified: llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp index 623a8b711ed8..ac53ff33e836 100644 --- a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -104,6 +104,21 @@ static bool mergeEmptyReturnBlocks(Function &F) { continue; } + // Skip merging if this would result in a CallBr instruction with a + // duplicate destination. FIXME: See note in CodeGenPrepare.cpp. + bool SkipCallBr = false; + for (pred_iterator PI = pred_begin(&BB), E = pred_end(&BB); + PI != E && !SkipCallBr; ++PI) { + if (auto *CBI = dyn_cast((*PI)->getTerminator())) + for (unsigned i = 0, e = CBI->getNumSuccessors(); i != e; ++i) + if (RetBlock == CBI->getSuccessor(i)) { + SkipCallBr = true; + break; + } + } + if (SkipCallBr) + continue; + // Otherwise, we found a duplicate return block. Merge the two. Changed = true; diff --git a/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll b/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll new file mode 100644 index 000000000000..18210e5e0b06 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll @@ -0,0 +1,28 @@ +; RUN: opt < %s -simplifycfg -disable-output +; +; Test that SimplifyCFG does not cause CallBr instructions to have duplicate +; destinations, which will cause the verifier to assert. + +define void @fun0() { +entry: + callbr void asm sideeffect "", "X"(i8* blockaddress(@fun0, %bb1)) + to label %bb2 [label %bb1] + +bb1: ; preds = %bb + ret void + +bb2: ; preds = %bb + ret void +} + +define void @fun1() { +entry: + callbr void asm sideeffect "", "X"(i8* blockaddress(@fun1, %bb1)) + to label %bb2 [label %bb1] + +bb2: ; preds = %bb + ret void + +bb1: ; preds = %bb + ret void +} From llvm-branch-commits at lists.llvm.org Thu Apr 16 11:17:40 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Thu, 16 Apr 2020 11:17:40 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] ef7dbe6 - [X86][SSE] combineX86ShufflesConstants - early out for zeroable vectors (PR45443) Message-ID: <5e98a144.1c69fb81.d40ec.b1a4@mx.google.com> Author: Simon Pilgrim Date: 2020-04-16T11:17:07-07:00 New Revision: ef7dbe6de65b7ad1cc4e9ab921cdade7a12c13db URL: https://github.com/llvm/llvm-project/commit/ef7dbe6de65b7ad1cc4e9ab921cdade7a12c13db DIFF: https://github.com/llvm/llvm-project/commit/ef7dbe6de65b7ad1cc4e9ab921cdade7a12c13db.diff LOG: [X86][SSE] combineX86ShufflesConstants - early out for zeroable vectors (PR45443) Shuffle combining can insert zero byte sized elements into the shuffle mask, which combineX86ShufflesConstants will attempt to fold without taking into account whether the byte-sized type is legal (e.g. AVX512F only targets). If we have a full-zeroable vector then we should just return a zero version of the root type, otherwise if the type isn't valid we should bail. Fixes PR45443 (cherry picked from commit e3b60597769f79a8abc19fb8ef1f321d9adc1358) Added: llvm/test/CodeGen/X86/pr45443.ll Modified: llvm/lib/Target/X86/X86ISelLowering.cpp Removed: ################################################################################ diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index cbdd7135de43..60eefbc677da 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -33998,6 +33998,7 @@ static SDValue combineX86ShufflesConstants(ArrayRef Ops, return SDValue(); // Shuffle the constant bits according to the mask. + SDLoc DL(Root); APInt UndefElts(NumMaskElts, 0); APInt ZeroElts(NumMaskElts, 0); APInt ConstantElts(NumMaskElts, 0); @@ -34035,6 +34036,10 @@ static SDValue combineX86ShufflesConstants(ArrayRef Ops, } assert((UndefElts | ZeroElts | ConstantElts).isAllOnesValue()); + // Attempt to create a zero vector. + if ((UndefElts | ZeroElts).isAllOnesValue()) + return getZeroVector(Root.getSimpleValueType(), Subtarget, DAG, DL); + // Create the constant data. MVT MaskSVT; if (VT.isFloatingPoint() && (MaskSizeInBits == 32 || MaskSizeInBits == 64)) @@ -34043,8 +34048,9 @@ static SDValue combineX86ShufflesConstants(ArrayRef Ops, MaskSVT = MVT::getIntegerVT(MaskSizeInBits); MVT MaskVT = MVT::getVectorVT(MaskSVT, NumMaskElts); + if (!DAG.getTargetLoweringInfo().isTypeLegal(MaskVT)) + return SDValue(); - SDLoc DL(Root); SDValue CstOp = getConstVector(ConstantBitData, UndefElts, MaskVT, DAG, DL); return DAG.getBitcast(VT, CstOp); } diff --git a/llvm/test/CodeGen/X86/pr45443.ll b/llvm/test/CodeGen/X86/pr45443.ll new file mode 100644 index 000000000000..1e40ab94e9ca --- /dev/null +++ b/llvm/test/CodeGen/X86/pr45443.ll @@ -0,0 +1,21 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i686-- -mattr=+avx512f | FileCheck %s --check-prefixes=CHECK,X86 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512f | FileCheck %s --check-prefixes=CHECK,X64 + +define <16 x float> @PR45443() { +; CHECK-LABEL: PR45443: +; CHECK: # %bb.0: # %bb +; CHECK-NEXT: vfmadd231ps {{.*#+}} zmm0 = (zmm0 * mem) + zmm0 +; CHECK-NEXT: ret{{[l|q]}} +bb: + %tmp = tail call <16 x i32> @llvm.x86.avx512.psll.d.512(<16 x i32> , <4 x i32> ) + %tmp4 = tail call fast <16 x float> @llvm.fma.v16f32(<16 x float> undef, <16 x float> , <16 x float> undef) + %tmp5 = icmp ult <16 x i32> %tmp, + %tmp6 = and <16 x i32> %tmp, + %tmp7 = icmp ne <16 x i32> %tmp6, zeroinitializer + %tmp8 = and <16 x i1> %tmp7, %tmp5 + %tmp9 = select fast <16 x i1> %tmp8, <16 x float> , <16 x float> %tmp4 + ret <16 x float> %tmp9 +} +declare <16 x float> @llvm.fma.v16f32(<16 x float>, <16 x float>, <16 x float>) +declare <16 x i32> @llvm.x86.avx512.psll.d.512(<16 x i32>, <4 x i32>) From llvm-branch-commits at lists.llvm.org Thu Apr 16 12:05:38 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Thu, 16 Apr 2020 12:05:38 -0700 (PDT) Subject: [llvm-branch-commits] [clang] cc6e51a - add release notes for ffp-model and ffp-exception-behavior Message-ID: <5e98ac82.1c69fb81.2846c.6783@mx.google.com> Author: Melanie Blower Date: 2020-04-16T12:05:10-07:00 New Revision: cc6e51a1414989ff1c2dcab30c00ac10ea19afa1 URL: https://github.com/llvm/llvm-project/commit/cc6e51a1414989ff1c2dcab30c00ac10ea19afa1 DIFF: https://github.com/llvm/llvm-project/commit/cc6e51a1414989ff1c2dcab30c00ac10ea19afa1.diff LOG: add release notes for ffp-model and ffp-exception-behavior (cherry picked from commit c8dadac228b7dd3a71d5fc25489d1b884a2b0f5e) Added: Modified: clang/docs/ReleaseNotes.rst Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a100d0a76b49..4939230a0643 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -184,6 +184,13 @@ New Compiler Flags - ``-mbranches-within-32B-boundaries`` is added as an x86 assembler mitigation for Intel's Jump Condition Code Erratum. +- -ffp-exception-behavior={ignore,maytrap,strict} allows the user to specify + the floating-point exception behavior. The default setting is ``ignore``. + +- -ffp-model={precise,strict,fast} provides the user an umbrella option to + simplify access to the many single purpose floating point options. The default + setting is ``precise``. + Deprecated Compiler Flags ------------------------- From llvm-branch-commits at lists.llvm.org Thu Apr 16 12:05:40 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Thu, 16 Apr 2020 12:05:40 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 6196695 - [CodeView] Align type records on 4-bytes when emitting PDBs Message-ID: <5e98ac84.1c69fb81.e8e89.c41b@mx.google.com> Author: Alexandre Ganea Date: 2020-04-16T12:05:11-07:00 New Revision: 6196695ec5819c0df7efe3fecca5c4ef9ea80b1c URL: https://github.com/llvm/llvm-project/commit/6196695ec5819c0df7efe3fecca5c4ef9ea80b1c DIFF: https://github.com/llvm/llvm-project/commit/6196695ec5819c0df7efe3fecca5c4ef9ea80b1c.diff LOG: [CodeView] Align type records on 4-bytes when emitting PDBs When emitting PDBs, the TypeStreamMerger class is used to merge .debug$T records from the input .OBJ files into the output .PDB stream. Records in .OBJs are not required to be aligned on 4-bytes, and "The Netwide Assembler 2.14" generates non-aligned records. When compiling with -DLLVM_ENABLE_ASSERTIONS=ON, an assert was triggered in MergingTypeTableBuilder when non-ghash merging was used. With ghash merging there was no assert. As a result, LLD could potentially generate a non-aligned TPI stream. We now align records on 4-bytes when record indices are remapped, in TypeStreamMerger::remapIndices(). Differential Revision: https://reviews.llvm.org/D75081 (cherry picked from commit a7325298e1f311b383b8ce5ba8e2d3698fef472a) Added: lld/test/COFF/pdb-tpi-aligned-records.test Modified: llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp Removed: ################################################################################ diff --git a/lld/test/COFF/pdb-tpi-aligned-records.test b/lld/test/COFF/pdb-tpi-aligned-records.test new file mode 100644 index 000000000000..cb3e412a8c20 --- /dev/null +++ b/lld/test/COFF/pdb-tpi-aligned-records.test @@ -0,0 +1,46 @@ +# RUN: yaml2obj < %s > %t.obj +# RUN: yaml2obj %p/Inputs/generic.yaml > %t2.obj + +# RUN: lld-link /out:%t.exe /debug /entry:main %t.obj %t2.obj /nodefaultlib +# RUN: llvm-pdbutil dump --types --type-data %t.pdb | FileCheck %s +# RUN: lld-link /out:%t.exe /debug:ghash /entry:main %t.obj %t2.obj /nodefaultlib +# RUN: llvm-pdbutil dump --types --type-data %t.pdb | FileCheck %s + +# CHECK: 0000: 12000810 03000000 00000000 00000000 0000F2F1 + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [] +sections: + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + # It is important to keep the 'SectionData' since the .OBJ is reconstructed from it, + # and that triggers an alignement bug in the output .PDB. + SectionData: '040000001000081003000000000000000000000000000600011200000000' + Types: + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 3 + CallConv: NearC + Options: [ None ] + ParameterCount: 0 + ArgumentList: 0 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ ] +symbols: + - Name: '.debug$T' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 30 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 +... diff --git a/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h b/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h index 3b103c227708..bb8cc032e28d 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h +++ b/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h @@ -71,6 +71,11 @@ class GlobalTypeTableBuilder : public TypeCollection { template TypeIndex insertRecordAs(GloballyHashedType Hash, size_t RecordSize, CreateFunc Create) { + assert(RecordSize < UINT32_MAX && "Record too big"); + assert(RecordSize % 4 == 0 && + "RecordSize is not a multiple of 4 bytes which will cause " + "misalignment in the output TPI stream!"); + auto Result = HashedRecords.try_emplace(Hash, nextTypeIndex()); if (LLVM_UNLIKELY(Result.second /*inserted*/ || diff --git a/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp index 4d7cd468f3ee..6924b0e0ca02 100644 --- a/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp +++ b/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp @@ -90,7 +90,9 @@ static inline ArrayRef stabilize(BumpPtrAllocator &Alloc, TypeIndex MergingTypeTableBuilder::insertRecordAs(hash_code Hash, ArrayRef &Record) { assert(Record.size() < UINT32_MAX && "Record too big"); - assert(Record.size() % 4 == 0 && "Record is not aligned to 4 bytes!"); + assert(Record.size() % 4 == 0 && + "The type record size is not a multiple of 4 bytes which will cause " + "misalignment in the output TPI stream!"); LocallyHashedType WeakHash{Hash, Record}; auto Result = HashedRecords.try_emplace(WeakHash, nextTypeIndex()); diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp index f9fca74a2199..c233db5c1d06 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -360,16 +360,18 @@ Error TypeStreamMerger::remapType(const CVType &Type) { [this, Type](MutableArrayRef Storage) -> ArrayRef { return remapIndices(Type, Storage); }; + unsigned AlignedSize = alignTo(Type.RecordData.size(), 4); + if (LLVM_LIKELY(UseGlobalHashes)) { GlobalTypeTableBuilder &Dest = isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream; GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()]; - DestIdx = Dest.insertRecordAs(H, Type.RecordData.size(), DoSerialize); + DestIdx = Dest.insertRecordAs(H, AlignedSize, DoSerialize); } else { MergingTypeTableBuilder &Dest = isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; - RemapStorage.resize(Type.RecordData.size()); + RemapStorage.resize(AlignedSize); ArrayRef Result = DoSerialize(RemapStorage); if (!Result.empty()) DestIdx = Dest.insertRecordBytes(Result); @@ -386,9 +388,15 @@ Error TypeStreamMerger::remapType(const CVType &Type) { ArrayRef TypeStreamMerger::remapIndices(const CVType &OriginalType, MutableArrayRef Storage) { + unsigned Align = OriginalType.RecordData.size() & 3; + unsigned AlignedSize = alignTo(OriginalType.RecordData.size(), 4); + assert(Storage.size() == AlignedSize && + "The storage buffer size is not a multiple of 4 bytes which will " + "cause misalignment in the output TPI stream!"); + SmallVector Refs; discoverTypeIndices(OriginalType.RecordData, Refs); - if (Refs.empty()) + if (Refs.empty() && Align == 0) return OriginalType.RecordData; ::memcpy(Storage.data(), OriginalType.RecordData.data(), @@ -408,6 +416,16 @@ TypeStreamMerger::remapIndices(const CVType &OriginalType, return {}; } } + + if (Align > 0) { + RecordPrefix *StorageHeader = + reinterpret_cast(Storage.data()); + StorageHeader->RecordLen += 4 - Align; + + DestContent = Storage.data() + OriginalType.RecordData.size(); + for (; Align < 4; ++Align) + *DestContent++ = LF_PAD4 - Align; + } return Storage; } diff --git a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp index 4f10f8524a9b..51a1f0a544e3 100644 --- a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp @@ -44,6 +44,9 @@ void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) { void TpiStreamBuilder::addTypeRecord(ArrayRef Record, Optional Hash) { // If we just crossed an 8KB threshold, add a type index offset. + assert(((Record.size() & 3) == 0) && + "The type record's size is not a multiple of 4 bytes which will " + "cause misalignment in the output TPI stream!"); size_t NewSize = TypeRecordBytes + Record.size(); constexpr size_t EightKB = 8 * 1024; if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecords.empty()) { @@ -153,8 +156,11 @@ Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout, return EC; for (auto Rec : TypeRecords) { - assert(!Rec.empty()); // An empty record will not write anything, but it - // would shift all offsets from here on. + assert(!Rec.empty() && "Attempting to write an empty type record shifts " + "all offsets in the TPI stream!"); + assert(((Rec.size() & 3) == 0) && + "The type record's size is not a multiple of 4 bytes which will " + "cause misalignment in the output TPI stream!"); if (auto EC = Writer.writeBytes(Rec)) return EC; } From llvm-branch-commits at lists.llvm.org Thu Apr 16 21:30:06 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Thu, 16 Apr 2020 21:30:06 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 92d5c1b - [PowerPC] Update alignment for ReuseLoadInfo in LowerFP_TO_INTForReuse Message-ID: <5e9930ce.1c69fb81.21c8.41d3@mx.google.com> Author: Kai Luo Date: 2020-04-16T18:30:44-07:00 New Revision: 92d5c1be9ee93850c0a8903f05f36a23ee835dc2 URL: https://github.com/llvm/llvm-project/commit/92d5c1be9ee93850c0a8903f05f36a23ee835dc2 DIFF: https://github.com/llvm/llvm-project/commit/92d5c1be9ee93850c0a8903f05f36a23ee835dc2.diff LOG: [PowerPC] Update alignment for ReuseLoadInfo in LowerFP_TO_INTForReuse In LowerFP_TO_INTForReuse, when emitting `stfiwx`, alignment of 4 is set for the `MachineMemOperand`, but RLI(ReuseLoadInfo)'s alignment is not updated for following loads. It's related to failed alignment check reported in https://bugs.llvm.org/show_bug.cgi?id=45297 Differential Revision: https://reviews.llvm.org/D77624 Backport b7d5229d789b7cb2747226d528ed016624b11cea. Added: llvm/test/CodeGen/PowerPC/kernel-fp-round.ll Modified: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Removed: ################################################################################ diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 60ed72e1018b..764563c17c24 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -7720,15 +7720,17 @@ void PPCTargetLowering::LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI, // Emit a store to the stack slot. SDValue Chain; + unsigned Alignment = DAG.getEVTAlignment(Tmp.getValueType()); if (i32Stack) { MachineFunction &MF = DAG.getMachineFunction(); + Alignment = 4; MachineMemOperand *MMO = - MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 4, 4); + MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 4, Alignment); SDValue Ops[] = { DAG.getEntryNode(), Tmp, FIPtr }; Chain = DAG.getMemIntrinsicNode(PPCISD::STFIWX, dl, DAG.getVTList(MVT::Other), Ops, MVT::i32, MMO); } else - Chain = DAG.getStore(DAG.getEntryNode(), dl, Tmp, FIPtr, MPI); + Chain = DAG.getStore(DAG.getEntryNode(), dl, Tmp, FIPtr, MPI, Alignment); // Result is a load from the stack slot. If loading 4 bytes, make sure to // add in a bias on big endian. @@ -7741,6 +7743,7 @@ void PPCTargetLowering::LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI, RLI.Chain = Chain; RLI.Ptr = FIPtr; RLI.MPI = MPI; + RLI.Alignment = Alignment; } /// Custom lowers floating point to integer conversions to use diff --git a/llvm/test/CodeGen/PowerPC/kernel-fp-round.ll b/llvm/test/CodeGen/PowerPC/kernel-fp-round.ll new file mode 100644 index 000000000000..b672712ca48d --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/kernel-fp-round.ll @@ -0,0 +1,44 @@ +; RUN: llc -simplify-mir -verify-machineinstrs -stop-after=finalize-isel \ +; RUN: -mtriple=powerpc64le-unknown-unknown -mattr=-vsx < %s | FileCheck %s +; RUN: llc -simplify-mir -verify-machineinstrs -stop-after=finalize-isel \ +; RUN: -mtriple=powerpc-unknown-unknown -mcpu=pwr6 -mattr=-vsx < %s | \ +; RUN: FileCheck --check-prefix=CHECK-P6 %s +; RUN: llc -simplify-mir -verify-machineinstrs -stop-after=finalize-isel \ +; RUN: -mtriple=powerpc64-unknown-unknown -mcpu=pwr6 -mattr=-vsx < %s | \ +; RUN: FileCheck --check-prefix=CHECK-P6-64 %s + +define float @test(float %a) { +; CHECK: stack: +; CHECK-NEXT: - { id: 0, size: 4, alignment: 4 } +; CHECK: %2:f8rc = FCTIWZ killed %1, implicit $rm +; CHECK: STFIWX killed %2, $zero8, %3 +; CHECK-NEXT: %4:f8rc = LFIWAX $zero8, %3 :: (load 4 from %stack.0) +; CHECK-NEXT: %5:f4rc = FCFIDS killed %4, implicit $rm +; CHECK-NEXT: $f1 = COPY %5 +; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $f1 + +; CHECK-P6: stack: +; CHECK-P6-NEXT: - { id: 0, size: 4, alignment: 4 } +; CHECK-P6: %2:f8rc = FCTIWZ killed %1, implicit $rm +; CHECK-P6: STFIWX killed %2, $zero, %3 +; CHECK-P6-NEXT: %4:f8rc = LFIWAX $zero, %3 :: (load 4 from %stack.0) +; CHECK-P6-NEXT: %5:f8rc = FCFID killed %4, implicit $rm +; CHECK-P6-NEXT: %6:f4rc = FRSP killed %5, implicit $rm +; CHECK-P6-NEXT: $f1 = COPY %6 +; CHECK-P6-NEXT: BLR implicit $lr, implicit $rm, implicit $f1 + +; CHECK-P6-64: stack: +; CHECK-P6-64-NEXT: - { id: 0, size: 4, alignment: 4 } +; CHECK-P6-64: %2:f8rc = FCTIWZ killed %1, implicit $rm +; CHECK-P6-64: STFIWX killed %2, $zero8, %3 +; CHECK-P6-64-NEXT: %4:f8rc = LFIWAX $zero8, %3 :: (load 4 from %stack.0) +; CHECK-P6-64-NEXT: %5:f8rc = FCFID killed %4, implicit $rm +; CHECK-P6-64-NEXT: %6:f4rc = FRSP killed %5, implicit $rm +; CHECK-P6-64-NEXT: $f1 = COPY %6 +; CHECK-P6-64-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $f1 + +entry: + %b = fptosi float %a to i32 + %c = sitofp i32 %b to float + ret float %c +} From llvm-branch-commits at lists.llvm.org Fri Apr 17 18:02:34 2020 From: llvm-branch-commits at lists.llvm.org (Lucy Fox via llvm-branch-commits) Date: Fri, 17 Apr 2020 18:02:34 -0700 (PDT) Subject: [llvm-branch-commits] [mlir] 01d7814 - [MLIR] Update tutorial to add missing tests and bring directory paths and code snippets up to date. Message-ID: <5e9a51aa.1c69fb81.dbd30.1f86@mx.google.com> Author: Lucy Fox Date: 2020-04-17T17:53:48-07:00 New Revision: 01d781489e71bee1ac37c6b89089df7e72fd0423 URL: https://github.com/llvm/llvm-project/commit/01d781489e71bee1ac37c6b89089df7e72fd0423 DIFF: https://github.com/llvm/llvm-project/commit/01d781489e71bee1ac37c6b89089df7e72fd0423.diff LOG: [MLIR] Update tutorial to add missing tests and bring directory paths and code snippets up to date. Summary: The tests referred to in Chapter 3 of the tutorial were missing from the tutorial test directory; this adds those missing tests. This also cleans up some stale directory paths and code snippets used throughout the tutorial. Subscribers: mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, aartbik, liufengdb, Joonsoo, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D76809 Added: mlir/test/Examples/Toy/Ch3/transpose_transpose.toy mlir/test/Examples/Toy/Ch3/trivial_reshape.toy mlir/test/Examples/Toy/Ch4/transpose_transpose.toy mlir/test/Examples/Toy/Ch4/trivial_reshape.toy mlir/test/Examples/Toy/Ch5/transpose_transpose.toy mlir/test/Examples/Toy/Ch5/trivial_reshape.toy mlir/test/Examples/Toy/Ch6/transpose_transpose.toy mlir/test/Examples/Toy/Ch6/trivial_reshape.toy mlir/test/Examples/Toy/Ch7/transpose_transpose.toy mlir/test/Examples/Toy/Ch7/trivial_reshape.toy Modified: mlir/docs/Tutorials/Toy/Ch-1.md mlir/docs/Tutorials/Toy/Ch-2.md mlir/docs/Tutorials/Toy/Ch-3.md mlir/docs/Tutorials/Toy/Ch-5.md mlir/docs/Tutorials/Toy/Ch-6.md Removed: ################################################################################ diff --git a/mlir/docs/Tutorials/Toy/Ch-1.md b/mlir/docs/Tutorials/Toy/Ch-1.md index 347eb3b03b04..7c2f49918049 100644 --- a/mlir/docs/Tutorials/Toy/Ch-1.md +++ b/mlir/docs/Tutorials/Toy/Ch-1.md @@ -109,48 +109,48 @@ The AST from the above code is fairly straightforward; here is a dump of it: ``` Module: - Function - Proto 'multiply_transpose' @test/ast.toy:5:1' - Args: [a, b] + Function + Proto 'multiply_transpose' @test/Examples/Toy/Ch1/ast.toy:4:1' + Params: [a, b] Block { Return - BinOp: * @test/ast.toy:6:25 - Call 'transpose' [ @test/ast.toy:6:10 - var: a @test/ast.toy:6:20 + BinOp: * @test/Examples/Toy/Ch1/ast.toy:5:25 + Call 'transpose' [ @test/Examples/Toy/Ch1/ast.toy:5:10 + var: a @test/Examples/Toy/Ch1/ast.toy:5:20 ] - Call 'transpose' [ @test/ast.toy:6:25 - var: b @test/ast.toy:6:35 + Call 'transpose' [ @test/Examples/Toy/Ch1/ast.toy:5:25 + var: b @test/Examples/Toy/Ch1/ast.toy:5:35 ] } // Block - Function - Proto 'main' @test/ast.toy:9:1' - Args: [] + Function + Proto 'main' @test/Examples/Toy/Ch1/ast.toy:8:1' + Params: [] Block { - VarDecl a<> @test/ast.toy:11:3 - Literal: <2, 3>[<3>[1.000000e+00, 2.000000e+00, 3.000000e+00], <3>[4.000000e+00, 5.000000e+00, 6.000000e+00]] @test/ast.toy:11:17 - VarDecl b<2, 3> @test/ast.toy:12:3 - Literal: <6>[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00] @test/ast.toy:12:17 - VarDecl c<> @test/ast.toy:15:3 - Call 'multiply_transpose' [ @test/ast.toy:15:11 - var: a @test/ast.toy:15:30 - var: b @test/ast.toy:15:33 + VarDecl a<> @test/Examples/Toy/Ch1/ast.toy:11:3 + Literal: <2, 3>[ <3>[ 1.000000e+00, 2.000000e+00, 3.000000e+00], <3>[ 4.000000e+00, 5.000000e+00, 6.000000e+00]] @test/Examples/Toy/Ch1/ast.toy:11:11 + VarDecl b<2, 3> @test/Examples/Toy/Ch1/ast.toy:15:3 + Literal: <6>[ 1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00] @test/Examples/Toy/Ch1/ast.toy:15:17 + VarDecl c<> @test/Examples/Toy/Ch1/ast.toy:19:3 + Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:19:11 + var: a @test/Examples/Toy/Ch1/ast.toy:19:30 + var: b @test/Examples/Toy/Ch1/ast.toy:19:33 ] - VarDecl d<> @test/ast.toy:18:3 - Call 'multiply_transpose' [ @test/ast.toy:18:11 - var: b @test/ast.toy:18:30 - var: a @test/ast.toy:18:33 + VarDecl d<> @test/Examples/Toy/Ch1/ast.toy:22:3 + Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:22:11 + var: b @test/Examples/Toy/Ch1/ast.toy:22:30 + var: a @test/Examples/Toy/Ch1/ast.toy:22:33 ] - VarDecl e<> @test/ast.toy:21:3 - Call 'multiply_transpose' [ @test/ast.toy:21:11 - var: b @test/ast.toy:21:30 - var: c @test/ast.toy:21:33 + VarDecl e<> @test/Examples/Toy/Ch1/ast.toy:25:3 + Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:25:11 + var: b @test/Examples/Toy/Ch1/ast.toy:25:30 + var: c @test/Examples/Toy/Ch1/ast.toy:25:33 ] - VarDecl f<> @test/ast.toy:24:3 - Call 'multiply_transpose' [ @test/ast.toy:24:11 - Call 'transpose' [ @test/ast.toy:24:30 - var: a @test/ast.toy:24:40 + VarDecl f<> @test/Examples/Toy/Ch1/ast.toy:28:3 + Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:28:11 + Call 'transpose' [ @test/Examples/Toy/Ch1/ast.toy:28:30 + var: a @test/Examples/Toy/Ch1/ast.toy:28:40 ] - var: c @test/ast.toy:24:44 + var: c @test/Examples/Toy/Ch1/ast.toy:28:44 ] } // Block ``` diff --git a/mlir/docs/Tutorials/Toy/Ch-2.md b/mlir/docs/Tutorials/Toy/Ch-2.md index c8be4819a277..e57bd7da4b22 100755 --- a/mlir/docs/Tutorials/Toy/Ch-2.md +++ b/mlir/docs/Tutorials/Toy/Ch-2.md @@ -491,8 +491,7 @@ def ConstantOp : Toy_Op<"constant"> { #### Specifying a Custom Assembly Format -At this point we can generate our "Toy IR". A simplified version of the previous -example: +At this point we can generate our "Toy IR". For example, the following: ```toy # User defined generic function that operates on unknown shaped arguments. @@ -514,22 +513,22 @@ Results in the following IR: ```mlir module { func @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64> { - %0 = "toy.transpose"(%arg0) : (tensor<*xf64>) -> tensor<*xf64> loc("test/codegen.toy":5:10) - %1 = "toy.transpose"(%arg1) : (tensor<*xf64>) -> tensor<*xf64> loc("test/codegen.toy":5:25) - %2 = "toy.mul"(%0, %1) : (tensor<*xf64>, tensor<*xf64>) -> tensor<*xf64> loc("test/codegen.toy":5:25) - "toy.return"(%2) : (tensor<*xf64>) -> () loc("test/codegen.toy":5:3) - } loc("test/codegen.toy":4:1) + %0 = "toy.transpose"(%arg0) : (tensor<*xf64>) -> tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":5:10) + %1 = "toy.transpose"(%arg1) : (tensor<*xf64>) -> tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":5:25) + %2 = "toy.mul"(%0, %1) : (tensor<*xf64>, tensor<*xf64>) -> tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":5:25) + "toy.return"(%2) : (tensor<*xf64>) -> () loc("test/Examples/Toy/Ch2/codegen.toy":5:3) + } loc("test/Examples/Toy/Ch2/codegen.toy":4:1) func @main() { - %0 = "toy.constant"() {value = dense<[[1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64>} : () -> tensor<2x3xf64> loc("test/codegen.toy":9:17) - %1 = "toy.reshape"(%0) : (tensor<2x3xf64>) -> tensor<2x3xf64> loc("test/codegen.toy":9:3) - %2 = "toy.constant"() {value = dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]> : tensor<6xf64>} : () -> tensor<6xf64> loc("test/codegen.toy":10:17) - %3 = "toy.reshape"(%2) : (tensor<6xf64>) -> tensor<2x3xf64> loc("test/codegen.toy":10:3) - %4 = "toy.generic_call"(%1, %3) {callee = @multiply_transpose} : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/codegen.toy":11:11) - %5 = "toy.generic_call"(%3, %1) {callee = @multiply_transpose} : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/codegen.toy":12:11) - "toy.print"(%5) : (tensor<*xf64>) -> () loc("test/codegen.toy":13:3) - "toy.return"() : () -> () loc("test/codegen.toy":8:1) - } loc("test/codegen.toy":8:1) -} loc("test/codegen.toy":0:0) + %0 = "toy.constant"() {value = dense<[[1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64>} : () -> tensor<2x3xf64> loc("test/Examples/Toy/Ch2/codegen.toy":9:17) + %1 = "toy.reshape"(%0) : (tensor<2x3xf64>) -> tensor<2x3xf64> loc("test/Examples/Toy/Ch2/codegen.toy":9:3) + %2 = "toy.constant"() {value = dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]> : tensor<6xf64>} : () -> tensor<6xf64> loc("test/Examples/Toy/Ch2/codegen.toy":10:17) + %3 = "toy.reshape"(%2) : (tensor<6xf64>) -> tensor<2x3xf64> loc("test/Examples/Toy/Ch2/codegen.toy":10:3) + %4 = "toy.generic_call"(%1, %3) {callee = @multiply_transpose} : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":11:11) + %5 = "toy.generic_call"(%3, %1) {callee = @multiply_transpose} : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":12:11) + "toy.print"(%5) : (tensor<*xf64>) -> () loc("test/Examples/Toy/Ch2/codegen.toy":13:3) + "toy.return"() : () -> () loc("test/Examples/Toy/Ch2/codegen.toy":8:1) + } loc("test/Examples/Toy/Ch2/codegen.toy":8:1) +} loc(unknown) ``` One thing to notice here is that all of our Toy operations are printed using the @@ -645,22 +644,22 @@ now get a much more readable: ```mlir module { func @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64> { - %0 = toy.transpose(%arg0 : tensor<*xf64>) to tensor<*xf64> loc("test/codegen.toy":5:10) - %1 = toy.transpose(%arg1 : tensor<*xf64>) to tensor<*xf64> loc("test/codegen.toy":5:25) - %2 = toy.mul %0, %1 : tensor<*xf64> loc("test/codegen.toy":5:25) - toy.return %2 : tensor<*xf64> loc("test/codegen.toy":5:3) - } loc("test/codegen.toy":4:1) + %0 = toy.transpose(%arg0 : tensor<*xf64>) to tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":5:10) + %1 = toy.transpose(%arg1 : tensor<*xf64>) to tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":5:25) + %2 = toy.mul %0, %1 : tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":5:25) + toy.return %2 : tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":5:3) + } loc("test/Examples/Toy/Ch2/codegen.toy":4:1) func @main() { - %0 = toy.constant dense<[[1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> loc("test/codegen.toy":9:17) - %1 = toy.reshape(%0 : tensor<2x3xf64>) to tensor<2x3xf64> loc("test/codegen.toy":9:3) - %2 = toy.constant dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]> : tensor<6xf64> loc("test/codegen.toy":10:17) - %3 = toy.reshape(%2 : tensor<6xf64>) to tensor<2x3xf64> loc("test/codegen.toy":10:3) - %4 = toy.generic_call @multiply_transpose(%1, %3) : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/codegen.toy":11:11) - %5 = toy.generic_call @multiply_transpose(%3, %1) : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/codegen.toy":12:11) - toy.print %5 : tensor<*xf64> loc("test/codegen.toy":13:3) - toy.return loc("test/codegen.toy":8:1) - } loc("test/codegen.toy":8:1) -} loc("test/codegen.toy":0:0) + %0 = toy.constant dense<[[1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> loc("test/Examples/Toy/Ch2/codegen.toy":9:17) + %1 = toy.reshape(%0 : tensor<2x3xf64>) to tensor<2x3xf64> loc("test/Examples/Toy/Ch2/codegen.toy":9:3) + %2 = toy.constant dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]> : tensor<6xf64> loc("test/Examples/Toy/Ch2/codegen.toy":10:17) + %3 = toy.reshape(%2 : tensor<6xf64>) to tensor<2x3xf64> loc("test/Examples/Toy/Ch2/codegen.toy":10:3) + %4 = toy.generic_call @multiply_transpose(%1, %3) : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":11:11) + %5 = toy.generic_call @multiply_transpose(%3, %1) : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":12:11) + toy.print %5 : tensor<*xf64> loc("test/Examples/Toy/Ch2/codegen.toy":13:3) + toy.return loc("test/Examples/Toy/Ch2/codegen.toy":8:1) + } loc("test/Examples/Toy/Ch2/codegen.toy":8:1) +} loc(unknown) ``` Above we introduce several of the concepts for defining operations in the ODS @@ -670,53 +669,12 @@ variadic operands, etc. Check out the ## Complete Toy Example -At this point we can generate our "Toy IR". A simplified version of the previous -example: - -```toy -# User defined generic function that operates on unknown shaped arguments. -def multiply_transpose(a, b) { - return transpose(a) * transpose(b); -} - -def main() { - var a<2, 3> = [[1, 2, 3], [4, 5, 6]]; - var b<2, 3> = [1, 2, 3, 4, 5, 6]; - var c = multiply_transpose(a, b); - var d = multiply_transpose(b, a); - print(d); -} -``` - -Results in the following IR: - -```mlir -module { - func @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64> { - %0 = toy.transpose(%arg0 : tensor<*xf64>) to tensor<*xf64> loc("test/codegen.toy":5:10) - %1 = toy.transpose(%arg1 : tensor<*xf64>) to tensor<*xf64> loc("test/codegen.toy":5:25) - %2 = toy.mul %0, %1 : tensor<*xf64> loc("test/codegen.toy":5:25) - toy.return %2 : tensor<*xf64> loc("test/codegen.toy":5:3) - } loc("test/codegen.toy":4:1) - func @main() { - %0 = toy.constant dense<[[1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> loc("test/codegen.toy":9:17) - %1 = toy.reshape(%0 : tensor<2x3xf64>) to tensor<2x3xf64> loc("test/codegen.toy":9:3) - %2 = toy.constant dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]> : tensor<6xf64> loc("test/codegen.toy":10:17) - %3 = toy.reshape(%2 : tensor<6xf64>) to tensor<2x3xf64> loc("test/codegen.toy":10:3) - %4 = toy.generic_call @multiply_transpose(%1, %3) : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/codegen.toy":11:11) - %5 = toy.generic_call @multiply_transpose(%3, %1) : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> loc("test/codegen.toy":12:11) - toy.print %5 : tensor<*xf64> loc("test/codegen.toy":13:3) - toy.return loc("test/codegen.toy":8:1) - } loc("test/codegen.toy":8:1) -} loc("test/codegen.toy":0:0) -``` - -You can build `toyc-ch2` and try yourself: `toyc-ch2 -test/Examples/Toy/Ch2/codegen.toy -emit=mlir -mlir-print-debuginfo`. We can also -check our RoundTrip: `toyc-ch2 test/Examples/Toy/Ch2/codegen.toy -emit=mlir --mlir-print-debuginfo 2> codegen.mlir` followed by `toyc-ch2 codegen.mlir --emit=mlir`. You should also use `mlir-tblgen` on the final definition file and -study the generated C++ code. +We can now generate our "Toy IR". You can build `toyc-ch2` and try yourself on +the above example: `toyc-ch2 test/Examples/Toy/Ch2/codegen.toy -emit=mlir +-mlir-print-debuginfo`. We can also check our RoundTrip: `toyc-ch2 +test/Examples/Toy/Ch2/codegen.toy -emit=mlir -mlir-print-debuginfo 2> +codegen.mlir` followed by `toyc-ch2 codegen.mlir -emit=mlir`. You should also +use `mlir-tblgen` on the final definition file and study the generated C++ code. At this point, MLIR knows about our Toy dialect and operations. In the [next chapter](Ch-3.md), we will leverage our new dialect to implement some diff --git a/mlir/docs/Tutorials/Toy/Ch-3.md b/mlir/docs/Tutorials/Toy/Ch-3.md index 0f741e7a5410..cc31454fe533 100644 --- a/mlir/docs/Tutorials/Toy/Ch-3.md +++ b/mlir/docs/Tutorials/Toy/Ch-3.md @@ -129,8 +129,8 @@ similar way to LLVM: pm.addNestedPass(mlir::createCanonicalizerPass()); ``` -Finally, we can run `toyc-ch3 test/transpose_transpose.toy -emit=mlir -opt` and -observe our pattern in action: +Finally, we can run `toyc-ch3 test/Examples/Toy/Ch3/transpose_transpose.toy +-emit=mlir -opt` and observe our pattern in action: ```mlir func @transpose_transpose(%arg0: tensor<*xf64>) -> tensor<*xf64> { @@ -216,7 +216,7 @@ def FoldConstantReshapeOptPattern : Pat< ``` We demonstrate these reshape optimizations using the following -trivialReshape.toy program: +trivial_reshape.toy program: ```c++ def main() { @@ -240,8 +240,8 @@ module { } ``` -We can try to run `toyc-ch3 test/trivialReshape.toy -emit=mlir -opt` and observe -our pattern in action: +We can try to run `toyc-ch3 test/Examples/Toy/Ch3/trivial_reshape.toy -emit=mlir +-opt` and observe our pattern in action: ```mlir module { diff --git a/mlir/docs/Tutorials/Toy/Ch-5.md b/mlir/docs/Tutorials/Toy/Ch-5.md index fd0341a26ea5..28e799d7d6bb 100644 --- a/mlir/docs/Tutorials/Toy/Ch-5.md +++ b/mlir/docs/Tutorials/Toy/Ch-5.md @@ -222,7 +222,7 @@ def PrintOp : Toy_Op<"print"> { ## Complete Toy Example -Looking back at our current working example: +Let's take a concrete example: ```mlir func @main() { @@ -336,8 +336,8 @@ func @main() { Here, we can see that a redundant allocation was removed, the two loop nests were fused, and some unnecessary `load`s were removed. You can build `toyc-ch5` -and try yourself: `toyc-ch5 test/lowering.toy -emit=mlir-affine`. We can also -check our optimizations by adding `-opt`. +and try yourself: `toyc-ch5 test/Examples/Toy/Ch5/affine-lowering.mlir +-emit=mlir-affine`. We can also check our optimizations by adding `-opt`. In this chapter we explored some aspects of partial lowering, with the intent to optimize. In the [next chapter](Ch-6.md) we will continue the discussion about diff --git a/mlir/docs/Tutorials/Toy/Ch-6.md b/mlir/docs/Tutorials/Toy/Ch-6.md index feaf42c39ba4..2808961f378f 100644 --- a/mlir/docs/Tutorials/Toy/Ch-6.md +++ b/mlir/docs/Tutorials/Toy/Ch-6.md @@ -239,8 +239,8 @@ define void @main() } ``` -The full code listing for dumping LLVM IR can be found in `Ch6/toy.cpp` in the -`dumpLLVMIR()` function: +The full code listing for dumping LLVM IR can be found in +`examples/toy/Ch6/toy.cpp` in the `dumpLLVMIR()` function: ```c++ @@ -318,5 +318,8 @@ You can also play with `-emit=mlir`, `-emit=mlir-affine`, `-emit=mlir-llvm`, and [`--print-ir-after-all`](../../WritingAPass.md#ir-printing) to track the evolution of the IR throughout the pipeline. +The example code used throughout this section can be found in +test/Examples/Toy/Ch6/llvm-lowering.mlir. + So far, we have worked with primitive data types. In the [next chapter](Ch-7.md), we will add a composite `struct` type. diff --git a/mlir/test/Examples/Toy/Ch3/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch3/transpose_transpose.toy new file mode 100644 index 000000000000..9945e7cf8397 --- /dev/null +++ b/mlir/test/Examples/Toy/Ch3/transpose_transpose.toy @@ -0,0 +1,25 @@ +# RUN: toyc-ch3 %s -emit=mlir 2>&1 | FileCheck %s + +# User defined generic function that operates on unknown shaped arguments +def transpose_transpose(x) { + return transpose(transpose(x)); +} + +def main() { + var a<2, 3> = [[1, 2, 3], [4, 5, 6]]; + var b = transpose_transpose(a); + print(b); +} + +# CHECK-LABEL: func @transpose_transpose( +# CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> +# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> +# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> +# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch3/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch3/trivial_reshape.toy new file mode 100644 index 000000000000..aa2c38714cf8 --- /dev/null +++ b/mlir/test/Examples/Toy/Ch3/trivial_reshape.toy @@ -0,0 +1,16 @@ +# RUN: toyc-ch3 %s -emit=mlir 2>&1 | FileCheck %s + +def main() { + var a<2,1> = [1, 2]; + var b<2,1> = a; + var c<2,1> = b; + print(c); +} + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy new file mode 100644 index 000000000000..77bacec0ae80 --- /dev/null +++ b/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy @@ -0,0 +1,25 @@ +# RUN: toyc-ch4 %s -emit=mlir 2>&1 | FileCheck %s + +# User defined generic function that operates on unknown shaped arguments +def transpose_transpose(x) { + return transpose(transpose(x)); +} + +def main() { + var a<2, 3> = [[1, 2, 3], [4, 5, 6]]; + var b = transpose_transpose(a); + print(b); +} + +# CHECK-LABEL: func @transpose_transpose( +# CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> +# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> +# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> +# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch4/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch4/trivial_reshape.toy new file mode 100644 index 000000000000..318bd07b36d3 --- /dev/null +++ b/mlir/test/Examples/Toy/Ch4/trivial_reshape.toy @@ -0,0 +1,16 @@ +# RUN: toyc-ch4 %s -emit=mlir 2>&1 | FileCheck %s + +def main() { + var a<2,1> = [1, 2]; + var b<2,1> = a; + var c<2,1> = b; + print(c); +} + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch5/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch5/transpose_transpose.toy new file mode 100644 index 000000000000..b038352a3dc0 --- /dev/null +++ b/mlir/test/Examples/Toy/Ch5/transpose_transpose.toy @@ -0,0 +1,25 @@ +# RUN: toyc-ch5 %s -emit=mlir 2>&1 | FileCheck %s + +# User defined generic function that operates on unknown shaped arguments +def transpose_transpose(x) { + return transpose(transpose(x)); +} + +def main() { + var a<2, 3> = [[1, 2, 3], [4, 5, 6]]; + var b = transpose_transpose(a); + print(b); +} + +# CHECK-LABEL: func @transpose_transpose( +# CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> +# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> +# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> +# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy new file mode 100644 index 000000000000..48828c4c10f7 --- /dev/null +++ b/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy @@ -0,0 +1,16 @@ +# RUN: toyc-ch5 %s -emit=mlir 2>&1 | FileCheck %s + +def main() { + var a<2,1> = [1, 2]; + var b<2,1> = a; + var c<2,1> = b; + print(c); +} + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch6/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch6/transpose_transpose.toy new file mode 100644 index 000000000000..5ddfbc23a851 --- /dev/null +++ b/mlir/test/Examples/Toy/Ch6/transpose_transpose.toy @@ -0,0 +1,25 @@ +# RUN: toyc-ch6 %s -emit=mlir 2>&1 | FileCheck %s + +# User defined generic function that operates on unknown shaped arguments +def transpose_transpose(x) { + return transpose(transpose(x)); +} + +def main() { + var a<2, 3> = [[1, 2, 3], [4, 5, 6]]; + var b = transpose_transpose(a); + print(b); +} + +# CHECK-LABEL: func @transpose_transpose( +# CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> +# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> +# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> +# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy new file mode 100644 index 000000000000..6fa9f68b68ca --- /dev/null +++ b/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy @@ -0,0 +1,16 @@ +# RUN: toyc-ch6 %s -emit=mlir 2>&1 | FileCheck %s + +def main() { + var a<2,1> = [1, 2]; + var b<2,1> = a; + var c<2,1> = b; + print(c); +} + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch7/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch7/transpose_transpose.toy new file mode 100644 index 000000000000..804cdb879884 --- /dev/null +++ b/mlir/test/Examples/Toy/Ch7/transpose_transpose.toy @@ -0,0 +1,25 @@ +# RUN: toyc-ch7 %s -emit=mlir 2>&1 | FileCheck %s + +# User defined generic function that operates on unknown shaped arguments +def transpose_transpose(x) { + return transpose(transpose(x)); +} + +def main() { + var a<2, 3> = [[1, 2, 3], [4, 5, 6]]; + var b = transpose_transpose(a); + print(b); +} + +# CHECK-LABEL: func @transpose_transpose( +# CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> +# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> +# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> +# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> +# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy new file mode 100644 index 000000000000..73209d8f5ffe --- /dev/null +++ b/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy @@ -0,0 +1,16 @@ +# RUN: toyc-ch7 %s -emit=mlir 2>&1 | FileCheck %s + +def main() { + var a<2,1> = [1, 2]; + var b<2,1> = a; + var c<2,1> = b; + print(c); +} + +# CHECK-LABEL: func @main() +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: toy.return \ No newline at end of file From llvm-branch-commits at lists.llvm.org Fri Apr 17 18:02:36 2020 From: llvm-branch-commits at lists.llvm.org (Lucy Fox via llvm-branch-commits) Date: Fri, 17 Apr 2020 18:02:36 -0700 (PDT) Subject: [llvm-branch-commits] [mlir] 9cad0d0 - [MLIR] Update tutorial to add missing tests and bring directory paths and code snippets up to date. Message-ID: <5e9a51ac.1c69fb81.3afe6.25af@mx.google.com> Author: Lucy Fox Date: 2020-04-17T17:53:48-07:00 New Revision: 9cad0d090d33bd1012439818b87c63ec25d84f60 URL: https://github.com/llvm/llvm-project/commit/9cad0d090d33bd1012439818b87c63ec25d84f60 DIFF: https://github.com/llvm/llvm-project/commit/9cad0d090d33bd1012439818b87c63ec25d84f60.diff LOG: [MLIR] Update tutorial to add missing tests and bring directory paths and code snippets up to date. Summary: The tests referred to in Chapter 3 of the tutorial were missing from the tutorial test directory; this adds those missing tests. This also cleans up some stale directory paths and code snippets used throughout the tutorial. Differential Revision: https://reviews.llvm.org/D76809 Added: Modified: mlir/test/Examples/Toy/Ch3/transpose_transpose.toy mlir/test/Examples/Toy/Ch3/trivial_reshape.toy mlir/test/Examples/Toy/Ch4/transpose_transpose.toy mlir/test/Examples/Toy/Ch4/trivial_reshape.toy mlir/test/Examples/Toy/Ch5/transpose_transpose.toy mlir/test/Examples/Toy/Ch5/trivial_reshape.toy mlir/test/Examples/Toy/Ch6/transpose_transpose.toy mlir/test/Examples/Toy/Ch6/trivial_reshape.toy mlir/test/Examples/Toy/Ch7/transpose_transpose.toy mlir/test/Examples/Toy/Ch7/trivial_reshape.toy Removed: ################################################################################ diff --git a/mlir/test/Examples/Toy/Ch3/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch3/transpose_transpose.toy index 9945e7cf8397..c686f6ab1c31 100644 --- a/mlir/test/Examples/Toy/Ch3/transpose_transpose.toy +++ b/mlir/test/Examples/Toy/Ch3/transpose_transpose.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch3 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch3 %s -emit=mlir -opt 2>&1 | FileCheck %s # User defined generic function that operates on unknown shaped arguments def transpose_transpose(x) { @@ -13,13 +13,10 @@ def main() { # CHECK-LABEL: func @transpose_transpose( # CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> -# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> +# CHECK-NEXT: toy.return [[VAL_0]] : tensor<*xf64> # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> -# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> -# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> -# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: [[VAL_2:%.*]] = toy.generic_call @transpose_transpose([[VAL_1]]) : (tensor<2x3xf64>) -> tensor<*xf64> +# CHECK-NEXT: toy.print [[VAL_2]] : tensor<*xf64> # CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch3/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch3/trivial_reshape.toy index aa2c38714cf8..0f0b1af1f50e 100644 --- a/mlir/test/Examples/Toy/Ch3/trivial_reshape.toy +++ b/mlir/test/Examples/Toy/Ch3/trivial_reshape.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch3 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch3 %s -emit=mlir -opt 2>&1 | FileCheck %s def main() { var a<2,1> = [1, 2]; @@ -8,9 +8,9 @@ def main() { } # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> -# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant +# CHECK-SAME: dense<[ +# CHECK-SAME: [1.000000e+00], [2.000000e+00] +# CHECK-SAME: ]> : tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_0]] : tensor<2x1xf64> # CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy index 77bacec0ae80..2177c35fa93d 100644 --- a/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy +++ b/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch4 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s # User defined generic function that operates on unknown shaped arguments def transpose_transpose(x) { @@ -11,15 +11,7 @@ def main() { print(b); } -# CHECK-LABEL: func @transpose_transpose( -# CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> -# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> - # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> -# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> -# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> -# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: toy.print [[VAL_1]] : tensor<2x3xf64> # CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch4/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch4/trivial_reshape.toy index 318bd07b36d3..453efa3ef312 100644 --- a/mlir/test/Examples/Toy/Ch4/trivial_reshape.toy +++ b/mlir/test/Examples/Toy/Ch4/trivial_reshape.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch4 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s def main() { var a<2,1> = [1, 2]; @@ -8,9 +8,9 @@ def main() { } # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> -# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant +# CHECK-SAME: dense<[ +# CHECK-SAME: [1.000000e+00], [2.000000e+00] +# CHECK-SAME: ]> : tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_0]] : tensor<2x1xf64> # CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch5/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch5/transpose_transpose.toy index b038352a3dc0..c0659c86af02 100644 --- a/mlir/test/Examples/Toy/Ch5/transpose_transpose.toy +++ b/mlir/test/Examples/Toy/Ch5/transpose_transpose.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch5 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch5 %s -emit=mlir -opt 2>&1 | FileCheck %s # User defined generic function that operates on unknown shaped arguments def transpose_transpose(x) { @@ -11,15 +11,7 @@ def main() { print(b); } -# CHECK-LABEL: func @transpose_transpose( -# CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> -# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> - # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> -# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> -# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> -# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: toy.print [[VAL_1]] : tensor<2x3xf64> # CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy index 48828c4c10f7..453efa3ef312 100644 --- a/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy +++ b/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch5 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s def main() { var a<2,1> = [1, 2]; @@ -8,9 +8,9 @@ def main() { } # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> -# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant +# CHECK-SAME: dense<[ +# CHECK-SAME: [1.000000e+00], [2.000000e+00] +# CHECK-SAME: ]> : tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_0]] : tensor<2x1xf64> # CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch6/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch6/transpose_transpose.toy index 5ddfbc23a851..ac710fe08d1a 100644 --- a/mlir/test/Examples/Toy/Ch6/transpose_transpose.toy +++ b/mlir/test/Examples/Toy/Ch6/transpose_transpose.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch6 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch6 %s -emit=mlir -opt 2>&1 | FileCheck %s # User defined generic function that operates on unknown shaped arguments def transpose_transpose(x) { @@ -11,15 +11,7 @@ def main() { print(b); } -# CHECK-LABEL: func @transpose_transpose( -# CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> -# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> - # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> -# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> -# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> -# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: toy.print [[VAL_1]] : tensor<2x3xf64> # CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy index 6fa9f68b68ca..453efa3ef312 100644 --- a/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy +++ b/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch6 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s def main() { var a<2,1> = [1, 2]; @@ -8,9 +8,9 @@ def main() { } # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> -# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant +# CHECK-SAME: dense<[ +# CHECK-SAME: [1.000000e+00], [2.000000e+00] +# CHECK-SAME: ]> : tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_0]] : tensor<2x1xf64> # CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch7/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch7/transpose_transpose.toy index 804cdb879884..f268425341c9 100644 --- a/mlir/test/Examples/Toy/Ch7/transpose_transpose.toy +++ b/mlir/test/Examples/Toy/Ch7/transpose_transpose.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch7 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch7 %s -emit=mlir -opt 2>&1 | FileCheck %s # User defined generic function that operates on unknown shaped arguments def transpose_transpose(x) { @@ -11,15 +11,7 @@ def main() { print(b); } -# CHECK-LABEL: func @transpose_transpose( -# CHECK-SAME: [[VAL_0:%.*]]: tensor<*xf64>) -> tensor<*xf64> -# CHECK: [[VAL_1:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64> -# CHECK-NEXT: toy.return [[VAL_2]] : tensor<*xf64> - # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_3:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> -# CHECK-NEXT: [[VAL_4:%.*]] = toy.reshape([[VAL_3]] : tensor<2x3xf64>) to tensor<2x3xf64> -# CHECK-NEXT: [[VAL_5:%.*]] = toy.generic_call @transpose_transpose([[VAL_4]]) : (tensor<2x3xf64>) -> tensor<*xf64> -# CHECK-NEXT: toy.print [[VAL_5]] : tensor<*xf64> +# CHECK-NEXT: [[VAL_1:%.*]] = toy.constant dense<{{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]> : tensor<2x3xf64> +# CHECK-NEXT: toy.print [[VAL_1]] : tensor<2x3xf64> # CHECK-NEXT: toy.return \ No newline at end of file diff --git a/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy index 73209d8f5ffe..453efa3ef312 100644 --- a/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy +++ b/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch7 %s -emit=mlir 2>&1 | FileCheck %s +# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s def main() { var a<2,1> = [1, 2]; @@ -8,9 +8,9 @@ def main() { } # CHECK-LABEL: func @main() -# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf64> -# CHECK-NEXT: [[VAL_1:%.*]] = toy.reshape([[VAL_0]] : tensor<2xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_2:%.*]] = toy.reshape([[VAL_1]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: [[VAL_3:%.*]] = toy.reshape([[VAL_2]] : tensor<2x1xf64>) to tensor<2x1xf64> -# CHECK-NEXT: toy.print [[VAL_3]] : tensor<2x1xf64> +# CHECK-NEXT: [[VAL_0:%.*]] = toy.constant +# CHECK-SAME: dense<[ +# CHECK-SAME: [1.000000e+00], [2.000000e+00] +# CHECK-SAME: ]> : tensor<2x1xf64> +# CHECK-NEXT: toy.print [[VAL_0]] : tensor<2x1xf64> # CHECK-NEXT: toy.return \ No newline at end of file From llvm-branch-commits at lists.llvm.org Fri Apr 17 18:02:39 2020 From: llvm-branch-commits at lists.llvm.org (Lucy Fox via llvm-branch-commits) Date: Fri, 17 Apr 2020 18:02:39 -0700 (PDT) Subject: [llvm-branch-commits] [mlir] 46294ff - [MLIR] Update tutorial to add missing tests and bring directory paths and code snippets up to date. Message-ID: <5e9a51af.1c69fb81.b7816.99b9@mx.google.com> Author: Lucy Fox Date: 2020-04-17T17:58:16-07:00 New Revision: 46294ffd1c083151f04a94668aa4bbf1fd415e9d URL: https://github.com/llvm/llvm-project/commit/46294ffd1c083151f04a94668aa4bbf1fd415e9d DIFF: https://github.com/llvm/llvm-project/commit/46294ffd1c083151f04a94668aa4bbf1fd415e9d.diff LOG: [MLIR] Update tutorial to add missing tests and bring directory paths and code snippets up to date. Summary: The tests referred to in Chapter 3 of the tutorial were missing from the tutorial test directory; this adds those missing tests. This also cleans up some stale directory paths and code snippets used throughout the tutorial. Differential Revision: https://reviews.llvm.org/D76809 Added: Modified: mlir/test/Examples/Toy/Ch5/trivial_reshape.toy mlir/test/Examples/Toy/Ch6/trivial_reshape.toy mlir/test/Examples/Toy/Ch7/trivial_reshape.toy Removed: ################################################################################ diff --git a/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy index 453efa3ef312..1addb06022e0 100644 --- a/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy +++ b/mlir/test/Examples/Toy/Ch5/trivial_reshape.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s +# RUN: toyc-ch5 %s -emit=mlir -opt 2>&1 | FileCheck %s def main() { var a<2,1> = [1, 2]; @@ -13,4 +13,4 @@ def main() { # CHECK-SAME: [1.000000e+00], [2.000000e+00] # CHECK-SAME: ]> : tensor<2x1xf64> # CHECK-NEXT: toy.print [[VAL_0]] : tensor<2x1xf64> -# CHECK-NEXT: toy.return \ No newline at end of file +# CHECK-NEXT: toy.return diff --git a/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy index 453efa3ef312..17832ace3782 100644 --- a/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy +++ b/mlir/test/Examples/Toy/Ch6/trivial_reshape.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s +# RUN: toyc-ch6 %s -emit=mlir -opt 2>&1 | FileCheck %s def main() { var a<2,1> = [1, 2]; @@ -13,4 +13,4 @@ def main() { # CHECK-SAME: [1.000000e+00], [2.000000e+00] # CHECK-SAME: ]> : tensor<2x1xf64> # CHECK-NEXT: toy.print [[VAL_0]] : tensor<2x1xf64> -# CHECK-NEXT: toy.return \ No newline at end of file +# CHECK-NEXT: toy.return diff --git a/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy b/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy index 453efa3ef312..5ca8c4b6e41a 100644 --- a/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy +++ b/mlir/test/Examples/Toy/Ch7/trivial_reshape.toy @@ -1,4 +1,4 @@ -# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s +# RUN: toyc-ch7 %s -emit=mlir -opt 2>&1 | FileCheck %s def main() { var a<2,1> = [1, 2]; @@ -13,4 +13,4 @@ def main() { # CHECK-SAME: [1.000000e+00], [2.000000e+00] # CHECK-SAME: ]> : tensor<2x1xf64> # CHECK-NEXT: toy.print [[VAL_0]] : tensor<2x1xf64> -# CHECK-NEXT: toy.return \ No newline at end of file +# CHECK-NEXT: toy.return From llvm-branch-commits at lists.llvm.org Wed Apr 22 15:00:19 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Wed, 22 Apr 2020 15:00:19 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 5086fa0 - [PowerPC] Pre-commit reduced test case for PR45297. NFC. Message-ID: <5ea0be73.1c69fb81.9c69f.208f@mx.google.com> Author: Kai Luo Date: 2020-04-22T14:54:22-07:00 New Revision: 5086fa033344b5b16db92c9aa75be1e061921842 URL: https://github.com/llvm/llvm-project/commit/5086fa033344b5b16db92c9aa75be1e061921842 DIFF: https://github.com/llvm/llvm-project/commit/5086fa033344b5b16db92c9aa75be1e061921842.diff LOG: [PowerPC] Pre-commit reduced test case for PR45297. NFC. (cherry picked from commit 70f9f4dd9d19ed2cec0d9adf60fede9401898b85) Added: llvm/test/CodeGen/PowerPC/pr45297.ll Modified: Removed: ################################################################################ diff --git a/llvm/test/CodeGen/PowerPC/pr45297.ll b/llvm/test/CodeGen/PowerPC/pr45297.ll new file mode 100644 index 000000000000..71c19744fb70 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/pr45297.ll @@ -0,0 +1,10 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mattr=+altivec -mattr=-power8-vector -mattr=-vsx < %s | FileCheck %s +; XFAIL: * + +define dso_local void @test(float %0) local_unnamed_addr { +entry: + %1 = fptosi float %0 to i32 + store i32 %1, i32* undef, align 4 + ret void +} From llvm-branch-commits at lists.llvm.org Wed Apr 22 15:00:21 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Wed, 22 Apr 2020 15:00:21 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 40633cc - [PowerPC] Enhance test for PR45297. NFC. Message-ID: <5ea0be75.1c69fb81.2a720.0d82@mx.google.com> Author: Kai Luo Date: 2020-04-22T14:54:22-07:00 New Revision: 40633cc752a4ffecac22c6134761464bdbc8e10a URL: https://github.com/llvm/llvm-project/commit/40633cc752a4ffecac22c6134761464bdbc8e10a DIFF: https://github.com/llvm/llvm-project/commit/40633cc752a4ffecac22c6134761464bdbc8e10a.diff LOG: [PowerPC] Enhance test for PR45297. NFC. (cherry picked from commit 351b19231554d4dba29c42c798176f1ff3286a32) Added: Modified: llvm/test/CodeGen/PowerPC/pr45297.ll Removed: ################################################################################ diff --git a/llvm/test/CodeGen/PowerPC/pr45297.ll b/llvm/test/CodeGen/PowerPC/pr45297.ll index 71c19744fb70..97d05efe0498 100644 --- a/llvm/test/CodeGen/PowerPC/pr45297.ll +++ b/llvm/test/CodeGen/PowerPC/pr45297.ll @@ -1,10 +1,13 @@ -; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ -; RUN: -mattr=+altivec -mattr=-power8-vector -mattr=-vsx < %s | FileCheck %s -; XFAIL: * +; RUN: not --crash llc -verify-machineinstrs \ +; RUN: -mtriple=powerpc64le-unknown-linux-gnu -mattr=+altivec \ +; RUN: -mattr=-power8-vector -mattr=-vsx < %s 2>&1 | FileCheck %s +; CHECK: LLVM ERROR: Cannot select: t{{[0-9]+}}: ch = PPCISD::ST_VSR_SCAL_INT<(store 4 into @Global)> + + at Global = dso_local global i32 55, align 4 define dso_local void @test(float %0) local_unnamed_addr { entry: %1 = fptosi float %0 to i32 - store i32 %1, i32* undef, align 4 + store i32 %1, i32* @Global, align 4 ret void } From llvm-branch-commits at lists.llvm.org Wed Apr 22 15:00:23 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Wed, 22 Apr 2020 15:00:23 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 66cfbf1 - [PowerPC] Fix test for PR45297 to adapt build without asserts. NFC. Message-ID: <5ea0be77.1c69fb81.8ad73.210b@mx.google.com> Author: Kai Luo Date: 2020-04-22T14:54:22-07:00 New Revision: 66cfbf17a18513de5551d6cdda563a2864d13400 URL: https://github.com/llvm/llvm-project/commit/66cfbf17a18513de5551d6cdda563a2864d13400 DIFF: https://github.com/llvm/llvm-project/commit/66cfbf17a18513de5551d6cdda563a2864d13400.diff LOG: [PowerPC] Fix test for PR45297 to adapt build without asserts. NFC. (cherry picked from commit 26b46b67d806a5299a93b1b3bca1548cb47487ff) Added: Modified: llvm/test/CodeGen/PowerPC/pr45297.ll Removed: ################################################################################ diff --git a/llvm/test/CodeGen/PowerPC/pr45297.ll b/llvm/test/CodeGen/PowerPC/pr45297.ll index 97d05efe0498..5bd5df543950 100644 --- a/llvm/test/CodeGen/PowerPC/pr45297.ll +++ b/llvm/test/CodeGen/PowerPC/pr45297.ll @@ -1,7 +1,7 @@ ; RUN: not --crash llc -verify-machineinstrs \ ; RUN: -mtriple=powerpc64le-unknown-linux-gnu -mattr=+altivec \ ; RUN: -mattr=-power8-vector -mattr=-vsx < %s 2>&1 | FileCheck %s -; CHECK: LLVM ERROR: Cannot select: t{{[0-9]+}}: ch = PPCISD::ST_VSR_SCAL_INT<(store 4 into @Global)> +; CHECK: LLVM ERROR: Cannot select: {{.*}}: ch = PPCISD::ST_VSR_SCAL_INT<(store 4 into @Global)> @Global = dso_local global i32 55, align 4 From llvm-branch-commits at lists.llvm.org Wed Apr 22 15:00:24 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Wed, 22 Apr 2020 15:00:24 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] b11ecd1 - [PowerPC] Don't generate ST_VSR_SCAL_INT if power8-vector is disabled Message-ID: <5ea0be78.1c69fb81.72b2c.21dd@mx.google.com> Author: Kai Luo Date: 2020-04-22T14:54:22-07:00 New Revision: b11ecd196540d87cb7db190d405056984740d2ce URL: https://github.com/llvm/llvm-project/commit/b11ecd196540d87cb7db190d405056984740d2ce DIFF: https://github.com/llvm/llvm-project/commit/b11ecd196540d87cb7db190d405056984740d2ce.diff LOG: [PowerPC] Don't generate ST_VSR_SCAL_INT if power8-vector is disabled Summary: In https://bugs.llvm.org/show_bug.cgi?id=45297, it fails selecting instructions for `PPCISD::ST_VSR_SCAL_INT`. The reason it generate the `PPCISD::ST_VSR_SCAL_INT` with `-power8-vector` in IR is PPC's combiner checks `hasP8Altivec` rather than `hasP8Vector`. This patch should resolve PR45297. Differential Revision: https://reviews.llvm.org/D76773 (cherry picked from commit 8eb40e41f6ec99985a292e342ec303a0bd6f5f41) Added: Modified: llvm/lib/Target/PowerPC/PPCISelLowering.cpp llvm/test/CodeGen/PowerPC/pr45297.ll Removed: ################################################################################ diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 764563c17c24..352a05529bc9 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -13591,7 +13591,7 @@ SDValue PPCTargetLowering::combineStoreFPToInt(SDNode *N, (Op1VT == MVT::i32 || Op1VT == MVT::i64 || (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8))); - if (ResVT == MVT::ppcf128 || !Subtarget.hasP8Altivec() || + if (ResVT == MVT::ppcf128 || !Subtarget.hasP8Vector() || cast(N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt) return SDValue(); diff --git a/llvm/test/CodeGen/PowerPC/pr45297.ll b/llvm/test/CodeGen/PowerPC/pr45297.ll index 5bd5df543950..39583d5a04cc 100644 --- a/llvm/test/CodeGen/PowerPC/pr45297.ll +++ b/llvm/test/CodeGen/PowerPC/pr45297.ll @@ -1,11 +1,20 @@ -; RUN: not --crash llc -verify-machineinstrs \ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names \ ; RUN: -mtriple=powerpc64le-unknown-linux-gnu -mattr=+altivec \ ; RUN: -mattr=-power8-vector -mattr=-vsx < %s 2>&1 | FileCheck %s -; CHECK: LLVM ERROR: Cannot select: {{.*}}: ch = PPCISD::ST_VSR_SCAL_INT<(store 4 into @Global)> @Global = dso_local global i32 55, align 4 define dso_local void @test(float %0) local_unnamed_addr { +; CHECK-LABEL: test: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fctiwz f0, f1 +; CHECK-NEXT: addi r3, r1, -4 +; CHECK-NEXT: addis r4, r2, Global at toc@ha +; CHECK-NEXT: stfiwx f0, 0, r3 +; CHECK-NEXT: lwz r3, -4(r1) +; CHECK-NEXT: stw r3, Global at toc@l(r4) +; CHECK-NEXT: blr entry: %1 = fptosi float %0 to i32 store i32 %1, i32* @Global, align 4 From llvm-branch-commits at lists.llvm.org Fri Apr 24 08:52:26 2020 From: llvm-branch-commits at lists.llvm.org (Pablo Barrio via llvm-branch-commits) Date: Fri, 24 Apr 2020 08:52:26 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 981b225 - [AArch64] Allow PAC mnemonics in the HINT space with PAC disabled Message-ID: <5ea30b3a.1c69fb81.c061a.8c42@mx.google.com> Author: Pablo Barrio Date: 2020-04-24T16:50:42+01:00 New Revision: 981b2258ebdc27001405d333015e12297dd536f5 URL: https://github.com/llvm/llvm-project/commit/981b2258ebdc27001405d333015e12297dd536f5 DIFF: https://github.com/llvm/llvm-project/commit/981b2258ebdc27001405d333015e12297dd536f5.diff LOG: [AArch64] Allow PAC mnemonics in the HINT space with PAC disabled Summary: It is important to emit HINT instructions instead of PAC ones when PAC is disabled. This allows compatibility with other assemblers (e.g. GAS). This was implemented in commit da33762de853. Still, developers of assembly code will want to write code that is compatible with both pre- and post-PAC CPUs. They could use HINT mnemonics, but the new mnemonics are a lot more readable (e.g. paciaz instead of hint #24), and they will result in the same encodings. So, while LLVM should not *emit* the new mnemonics when PAC is disabled, this patch will at least make LLVM *accept* assembly code that uses them. Reviewers: danielkiss, chill, olista01, LukeCheeseman, simon_tatham Subscribers: kristof.beyls, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D78372 Added: Modified: llvm/lib/Target/AArch64/AArch64InstrInfo.td llvm/test/MC/AArch64/armv8.3a-signed-pointer.s Removed: ################################################################################ diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 91af6c79a427..913e23c861da 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -915,10 +915,28 @@ let Uses = [LR], Defs = [LR], CRm = 0b0000 in { def XPACLRI : SystemNoOperands<0b111, "hint\t#7">; } +// In order to be able to write readable assembly, LLVM should accept assembly +// inputs that use pointer authentication mnemonics, even with PA disabled. +// However, in order to be compatible with other assemblers (e.g. GAS), LLVM +// should not emit these mnemonics unless PA is enabled. +def : InstAlias<"paciaz", (PACIAZ), 0>; +def : InstAlias<"pacibz", (PACIBZ), 0>; +def : InstAlias<"autiaz", (AUTIAZ), 0>; +def : InstAlias<"autibz", (AUTIBZ), 0>; +def : InstAlias<"paciasp", (PACIASP), 0>; +def : InstAlias<"pacibsp", (PACIBSP), 0>; +def : InstAlias<"autiasp", (AUTIASP), 0>; +def : InstAlias<"autibsp", (AUTIBSP), 0>; +def : InstAlias<"pacia1716", (PACIA1716), 0>; +def : InstAlias<"pacib1716", (PACIB1716), 0>; +def : InstAlias<"autia1716", (AUTIA1716), 0>; +def : InstAlias<"autib1716", (AUTIB1716), 0>; +def : InstAlias<"xpaclri", (XPACLRI), 0>; + // These pointer authentication instructions require armv8.3a let Predicates = [HasPA] in { - // When compiling with PA, there is a better mnemonic for these instructions. + // When PA is enabled, a better mnemonic should be emitted. def : InstAlias<"paciaz", (PACIAZ), 1>; def : InstAlias<"pacibz", (PACIBZ), 1>; def : InstAlias<"autiaz", (AUTIAZ), 1>; diff --git a/llvm/test/MC/AArch64/armv8.3a-signed-pointer.s b/llvm/test/MC/AArch64/armv8.3a-signed-pointer.s index b804889726e7..dad4bc667853 100644 --- a/llvm/test/MC/AArch64/armv8.3a-signed-pointer.s +++ b/llvm/test/MC/AArch64/armv8.3a-signed-pointer.s @@ -2,7 +2,7 @@ // RUN: FileCheck --check-prefixes=CHECK,ALL %s // RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding %s -o - > %t.1 2>%t.2 -// RUN: FileCheck --check-prefixes=ALL %s < %t.1 +// RUN: FileCheck --check-prefixes=NO83,ALL %s < %t.1 // RUN: FileCheck --check-prefix=CHECK-REQ %s < %t.2 // ALL: .text @@ -98,56 +98,43 @@ // ALL-EMPTY: paciasp // CHECK-NEXT: paciasp // encoding: [0x3f,0x23,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: paciasp +// NO83-NEXT: hint #25 // encoding: [0x3f,0x23,0x03,0xd5] autiasp // CHECK-NEXT: autiasp // encoding: [0xbf,0x23,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: autiasp +// NO83-NEXT: hint #29 // encoding: [0xbf,0x23,0x03,0xd5] paciaz // CHECK-NEXT: paciaz // encoding: [0x1f,0x23,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: paciaz +// NO83-NEXT: hint #24 // encoding: [0x1f,0x23,0x03,0xd5] autiaz // CHECK-NEXT: autiaz // encoding: [0x9f,0x23,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: autiaz +// NO83-NEXT: hint #28 // encoding: [0x9f,0x23,0x03,0xd5] pacia1716 // CHECK-NEXT: pacia1716 // encoding: [0x1f,0x21,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: pacia1716 +// NO83-NEXT: hint #8 // encoding: [0x1f,0x21,0x03,0xd5] autia1716 // CHECK-NEXT: autia1716 // encoding: [0x9f,0x21,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: autia1716 +// NO83-NEXT: hint #12 // encoding: [0x9f,0x21,0x03,0xd5] pacibsp // CHECK-NEXT: pacibsp // encoding: [0x7f,0x23,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: pacibsp +// NO83-NEXT: hint #27 // encoding: [0x7f,0x23,0x03,0xd5] autibsp // CHECK-NEXT: autibsp // encoding: [0xff,0x23,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: autibsp +// NO83-NEXT: hint #31 // encoding: [0xff,0x23,0x03,0xd5] pacibz // CHECK-NEXT: pacibz // encoding: [0x5f,0x23,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: pacibz +// NO83-NEXT: hint #26 // encoding: [0x5f,0x23,0x03,0xd5] autibz // CHECK-NEXT: autibz // encoding: [0xdf,0x23,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: autibz +// NO83-NEXT: hint #30 // encoding: [0xdf,0x23,0x03,0xd5] pacib1716 // CHECK-NEXT: pacib1716 // encoding: [0x5f,0x21,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: pacib1716 +// NO83-NEXT: hint #10 // encoding: [0x5f,0x21,0x03,0xd5] autib1716 // CHECK-NEXT: autib1716 // encoding: [0xdf,0x21,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: autib1716 +// NO83-NEXT: hint #14 // encoding: [0xdf,0x21,0x03,0xd5] xpaclri // CHECK-NEXT: xpaclri // encoding: [0xff,0x20,0x03,0xd5] -// CHECK-REQ: error: instruction requires: pa -// CHECK-REQ-NEXT: xpaclri +// NO83-NEXT: hint #7 // encoding: [0xff,0x20,0x03,0xd5] // ALL-EMPTY: pacia x0, x1 From llvm-branch-commits at lists.llvm.org Mon Apr 27 17:34:10 2020 From: llvm-branch-commits at lists.llvm.org (Fangrui Song via llvm-branch-commits) Date: Mon, 27 Apr 2020 17:34:10 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] aa97472 - Re-land [MC] Fix quadratic behavior in addPendingLabel Message-ID: <5ea77a02.1c69fb81.39dd1.70f5@mx.google.com> Author: Alexandre Ganea Date: 2020-04-27T17:30:36-07:00 New Revision: aa97472d211df67e91e8c1dd3188a0fb2ff942c8 URL: https://github.com/llvm/llvm-project/commit/aa97472d211df67e91e8c1dd3188a0fb2ff942c8 DIFF: https://github.com/llvm/llvm-project/commit/aa97472d211df67e91e8c1dd3188a0fb2ff942c8.diff LOG: Re-land [MC] Fix quadratic behavior in addPendingLabel This was discovered when compiling large unity/blob/jumbo files. Differential Revision: https://reviews.llvm.org/D78775 (cherry picked from commit fd773e8a51b82775f411061117173a21b500642a) Added: Modified: llvm/include/llvm/MC/MCObjectStreamer.h llvm/lib/MC/MCObjectStreamer.cpp Removed: ################################################################################ diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 9e3f87565e26..701cdf30b479 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -9,6 +9,7 @@ #ifndef LLVM_MC_MCOBJECTSTREAMER_H #define LLVM_MC_MCOBJECTSTREAMER_H +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCSection.h" @@ -38,7 +39,7 @@ class MCObjectStreamer : public MCStreamer { bool EmitEHFrame; bool EmitDebugFrame; SmallVector PendingLabels; - SmallVector PendingLabelSections; + SmallSetVector PendingLabelSections; unsigned CurSubsectionIdx; struct PendingMCFixup { const MCSymbol *Sym; diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 3d1358df475f..e05a0ec11f56 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -59,12 +59,8 @@ void MCObjectStreamer::addPendingLabel(MCSymbol* S) { CurSection->addPendingLabel(S, CurSubsectionIdx); // Add this Section to the list of PendingLabelSections. - auto SecIt = std::find(PendingLabelSections.begin(), - PendingLabelSections.end(), CurSection); - if (SecIt == PendingLabelSections.end()) - PendingLabelSections.push_back(CurSection); - } - else + PendingLabelSections.insert(CurSection); + } else // There is no Section / Subsection for this label yet. PendingLabels.push_back(S); } From llvm-branch-commits at lists.llvm.org Tue Apr 28 09:20:45 2020 From: llvm-branch-commits at lists.llvm.org (Jean-Michel Gorius via llvm-branch-commits) Date: Tue, 28 Apr 2020 09:20:45 -0700 (PDT) Subject: [llvm-branch-commits] [mlir] 7f8ae54 - [mlir][assemblyFormat] Fix bug when using AttrSizedOperandSegments trait with non-buildable operand types only Message-ID: <5ea857dd.1c69fb81.8372a.921e@mx.google.com> Author: Martin Erhart Date: 2020-04-28T18:20:15+02:00 New Revision: 7f8ae5405a93a6041bd0969da7ccb288a4f7ec22 URL: https://github.com/llvm/llvm-project/commit/7f8ae5405a93a6041bd0969da7ccb288a4f7ec22 DIFF: https://github.com/llvm/llvm-project/commit/7f8ae5405a93a6041bd0969da7ccb288a4f7ec22.diff LOG: [mlir][assemblyFormat] Fix bug when using AttrSizedOperandSegments trait with non-buildable operand types only Summary: When creating an operation with * the `AttrSizedOperandSegments` trait * variadic operands of only non-buildable types * assemblyFormat to automatically generate the parser a local `builder` variable is used, but never declared. This adds a fix as well as a test for this case, as existing ones use buildable types only. Reviewers: rriddle, Kayjukh, grosser Reviewed By: Kayjukh Subscribers: mehdi_amini, jpienaar, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, liufengdb, Joonsoo, grosul1, frgossen, llvm-commits Tags: #mlir, #llvm Differential Revision: https://reviews.llvm.org/D79004 Added: Modified: mlir/test/lib/Dialect/Test/TestOps.td mlir/tools/mlir-tblgen/OpFormatGen.cpp Removed: ################################################################################ diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td index 57b0c36505ca..1da2e71fbbd4 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -1258,6 +1258,16 @@ def FormatOptionalOperandResultBOp : FormatOptionalOperandResultOpBase<"b", [{ (`[` $variadic^ `]`)? attr-dict }]>; +def FormatTwoVariadicOperandsNoBuildableTypeOp + : TEST_Op<"format_two_variadic_operands_no_buildable_type_op", + [AttrSizedOperandSegments]> { + let arguments = (ins Variadic:$a, + Variadic:$b); + let assemblyFormat = [{ + `(` $a `:` type($a) `)` `->` `(` $b `:` type($b) `)` attr-dict + }]; +} + //===----------------------------------------------------------------------===// // Test SideEffects //===----------------------------------------------------------------------===// diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp index a8116e4290b4..47c145df29e0 100644 --- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp +++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp @@ -741,10 +741,8 @@ void OperationFormat::genParserTypeResolution(Operator &op, // Initialize the set of buildable types. if (!buildableTypes.empty()) { - body << " Builder &builder = parser.getBuilder();\n"; - FmtContext typeBuilderCtx; - typeBuilderCtx.withBuilder("builder"); + typeBuilderCtx.withBuilder("parser.getBuilder()"); for (auto &it : buildableTypes) body << " Type odsBuildableType" << it.second << " = " << tgfmt(it.first, &typeBuilderCtx) << ";\n"; @@ -867,7 +865,7 @@ void OperationFormat::genParserVariadicSegmentResolution(Operator &op, OpMethodBody &body) { if (!allOperands && op.getTrait("OpTrait::AttrSizedOperandSegments")) { body << " result.addAttribute(\"operand_segment_sizes\", " - << "builder.getI32VectorAttr({"; + << "parser.getBuilder().getI32VectorAttr({"; auto interleaveFn = [&](const NamedTypeConstraint &operand) { // If the operand is variadic emit the parsed size. if (operand.isVariableLength()) From llvm-branch-commits at lists.llvm.org Wed Apr 29 11:09:44 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Wed, 29 Apr 2020 11:09:44 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] d2071b8 - Revert "Re-land [MC] Fix quadratic behavior in addPendingLabel" Message-ID: <5ea9c2e8.1c69fb81.7b8e6.4967@mx.google.com> Author: Tom Stellard Date: 2020-04-29T11:08:42-07:00 New Revision: d2071b8fcdc5e8794d467cec9ebab735d09218bf URL: https://github.com/llvm/llvm-project/commit/d2071b8fcdc5e8794d467cec9ebab735d09218bf DIFF: https://github.com/llvm/llvm-project/commit/d2071b8fcdc5e8794d467cec9ebab735d09218bf.diff LOG: Revert "Re-land [MC] Fix quadratic behavior in addPendingLabel" This reverts commit aa97472d211df67e91e8c1dd3188a0fb2ff942c8. This commit broke ABI compatibility: https://github.com/llvm/llvm-project/runs/624609989 Added: Modified: llvm/include/llvm/MC/MCObjectStreamer.h llvm/lib/MC/MCObjectStreamer.cpp Removed: ################################################################################ diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 701cdf30b479..9e3f87565e26 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -9,7 +9,6 @@ #ifndef LLVM_MC_MCOBJECTSTREAMER_H #define LLVM_MC_MCOBJECTSTREAMER_H -#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCSection.h" @@ -39,7 +38,7 @@ class MCObjectStreamer : public MCStreamer { bool EmitEHFrame; bool EmitDebugFrame; SmallVector PendingLabels; - SmallSetVector PendingLabelSections; + SmallVector PendingLabelSections; unsigned CurSubsectionIdx; struct PendingMCFixup { const MCSymbol *Sym; diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index e05a0ec11f56..3d1358df475f 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -59,8 +59,12 @@ void MCObjectStreamer::addPendingLabel(MCSymbol* S) { CurSection->addPendingLabel(S, CurSubsectionIdx); // Add this Section to the list of PendingLabelSections. - PendingLabelSections.insert(CurSection); - } else + auto SecIt = std::find(PendingLabelSections.begin(), + PendingLabelSections.end(), CurSection); + if (SecIt == PendingLabelSections.end()) + PendingLabelSections.push_back(CurSection); + } + else // There is no Section / Subsection for this label yet. PendingLabels.push_back(S); } From llvm-branch-commits at lists.llvm.org Wed Apr 29 15:25:11 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Wed, 29 Apr 2020 15:25:11 -0700 (PDT) Subject: [llvm-branch-commits] [clang] 9cf9cf2 - [Clang] Fix Hurd toolchain test on a two-stage build with ThinLTO Message-ID: <5ea9fec7.1c69fb81.82114.60c3@mx.google.com> Author: Alexandre Ganea Date: 2020-04-29T15:23:44-07:00 New Revision: 9cf9cf2a398ce70d9187afa59db6500e7a1f2cd0 URL: https://github.com/llvm/llvm-project/commit/9cf9cf2a398ce70d9187afa59db6500e7a1f2cd0 DIFF: https://github.com/llvm/llvm-project/commit/9cf9cf2a398ce70d9187afa59db6500e7a1f2cd0.diff LOG: [Clang] Fix Hurd toolchain test on a two-stage build with ThinLTO A two-stage ThinLTO build previously failed the clang/test/Driver/hurd.c test because of a static_cast in "tools::gnutools::Linker::ConstructJob()" which wrongly converted an instance of "clang::driver::toolchains::Hurd" into that of "clang::driver::toolchains::Linux". ThinLTO would later devirtualize the "ToolChain.getDynamicLinker(Args)" call and use "Linux::getDynamicLinker()" instead, causing the test to generate a wrong "-dynamic-linker" linker flag (/lib/ld-linux.so.2 instead of /lib/ld.so) Fixes PR45061. Differential Revision: https://reviews.llvm.org/D75373 (cherry picked from commit 7e77cf473ac9d8f8b65db017d660892f1c8f4b75) Added: Modified: clang/lib/Driver/ToolChains/Gnu.cpp clang/lib/Driver/ToolChains/Gnu.h clang/lib/Driver/ToolChains/Hurd.cpp clang/lib/Driver/ToolChains/Hurd.h clang/lib/Driver/ToolChains/Linux.cpp clang/lib/Driver/ToolChains/Linux.h Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index da197e476621..e8ef881e89ac 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -309,7 +309,7 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { } } -static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { +static bool getPIE(const ArgList &Args, const ToolChain &TC) { if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_r) || Args.hasArg(options::OPT_static_pie)) return false; @@ -317,17 +317,16 @@ static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, options::OPT_nopie); if (!A) - return ToolChain.isPIEDefault(); + return TC.isPIEDefault(); return A->getOption().matches(options::OPT_pie); } -static bool getStaticPIE(const ArgList &Args, - const toolchains::Linux &ToolChain) { +static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) { bool HasStaticPIE = Args.hasArg(options::OPT_static_pie); // -no-pie is an alias for -nopie. So, handling -nopie takes care of // -no-pie as well. if (HasStaticPIE && Args.hasArg(options::OPT_nopie)) { - const Driver &D = ToolChain.getDriver(); + const Driver &D = TC.getDriver(); const llvm::opt::OptTable &Opts = D.getOpts(); const char *StaticPIEName = Opts.getOptionName(options::OPT_static_pie); const char *NoPIEName = Opts.getOptionName(options::OPT_nopie); @@ -346,8 +345,12 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - const toolchains::Linux &ToolChain = - static_cast(getToolChain()); + // FIXME: The Linker class constructor takes a ToolChain and not a + // Generic_ELF, so the static_cast might return a reference to a invalid + // instance (see PR45061). Ideally, the Linker constructor needs to take a + // Generic_ELF instead. + const toolchains::Generic_ELF &ToolChain = + static_cast(getToolChain()); const Driver &D = ToolChain.getDriver(); const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); @@ -418,8 +421,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (isAndroid) CmdArgs.push_back("--warn-shared-textrel"); - for (const auto &Opt : ToolChain.ExtraOpts) - CmdArgs.push_back(Opt.c_str()); + ToolChain.addExtraOpts(CmdArgs); CmdArgs.push_back("--eh-frame-hdr"); diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h index 083f74c05477..fa50b56bf954 100644 --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -356,6 +356,12 @@ class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override; + + virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const { + return {}; + } + + virtual void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {} }; } // end namespace toolchains diff --git a/clang/lib/Driver/ToolChains/Hurd.cpp b/clang/lib/Driver/ToolChains/Hurd.cpp index 72166ca9f359..ee91f7d73b9c 100644 --- a/clang/lib/Driver/ToolChains/Hurd.cpp +++ b/clang/lib/Driver/ToolChains/Hurd.cpp @@ -61,8 +61,7 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { return Triple.isArch32Bit() ? "lib" : "lib64"; } -Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) +Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { std::string SysRoot = computeSysRoot(); path_list &Paths = getFilePaths(); @@ -170,3 +169,8 @@ void Hurd::AddClangSystemIncludeArgs(const ArgList &DriverArgs, addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); } + +void Hurd::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + for (const auto &Opt : ExtraOpts) + CmdArgs.push_back(Opt.c_str()); +} diff --git a/clang/lib/Driver/ToolChains/Hurd.h b/clang/lib/Driver/ToolChains/Hurd.h index 86c6c3f734dd..8f88d7e8e58e 100644 --- a/clang/lib/Driver/ToolChains/Hurd.h +++ b/clang/lib/Driver/ToolChains/Hurd.h @@ -27,9 +27,11 @@ class LLVM_LIBRARY_VISIBILITY Hurd : public Generic_ELF { AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - virtual std::string computeSysRoot() const; + std::string computeSysRoot() const; - virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const; + std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; + + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; std::vector ExtraOpts; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index bff1ab1009be..6532c899492a 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -986,3 +986,8 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args, Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); ToolChain::addProfileRTLibs(Args, CmdArgs); } + +void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + for (const auto &Opt : ExtraOpts) + CmdArgs.push_back(Opt.c_str()); +} diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index f5518eac218a..923ebecbd215 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -42,7 +42,9 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { llvm::opt::ArgStringList &CmdArgs) const override; virtual std::string computeSysRoot() const; - virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const; + std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; + + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; std::vector ExtraOpts; From llvm-branch-commits at lists.llvm.org Wed Apr 29 18:04:42 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Wed, 29 Apr 2020 18:04:42 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] e4312b9 - [Coroutines] Fix PR45130 Message-ID: <5eaa242a.1c69fb81.b2db2.5f95@mx.google.com> Author: Jun Ma Date: 2020-04-29T17:13:34-07:00 New Revision: e4312b950dd7b019e14b991a17d6ac260b8e8082 URL: https://github.com/llvm/llvm-project/commit/e4312b950dd7b019e14b991a17d6ac260b8e8082 DIFF: https://github.com/llvm/llvm-project/commit/e4312b950dd7b019e14b991a17d6ac260b8e8082.diff LOG: [Coroutines] Fix PR45130 For now, when final suspend can be simplified by simplifySuspendPoint, handleFinalSuspend is executed as well to remove last case in switch instruction. This patch fixes it. Differential Revision: https://reviews.llvm.org/D76345 (cherry picked from commit 032251e34d17c1cbf21e7571514bb775ed5cdf30) Added: Modified: llvm/lib/Transforms/Coroutines/CoroSplit.cpp llvm/test/Transforms/Coroutines/no-suspend.ll Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index 66cb3e74e53e..1e067a45d016 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -1155,7 +1155,10 @@ static void simplifySuspendPoints(coro::Shape &Shape) { if (N == 0) return; while (true) { - if (simplifySuspendPoint(cast(S[I]), Shape.CoroBegin)) { + auto SI = cast(S[I]); + // Leave final.suspend to handleFinalSuspend since it is undefined behavior + // to resume a coroutine suspended at the final suspend point. + if (!SI->isFinal() && simplifySuspendPoint(SI, Shape.CoroBegin)) { if (--N == I) break; std::swap(S[I], S[N]); diff --git a/llvm/test/Transforms/Coroutines/no-suspend.ll b/llvm/test/Transforms/Coroutines/no-suspend.ll index fca096fa48bb..beb2431b7f19 100644 --- a/llvm/test/Transforms/Coroutines/no-suspend.ll +++ b/llvm/test/Transforms/Coroutines/no-suspend.ll @@ -361,6 +361,58 @@ suspend: ret void } +; SimplifySuspendPoint should not simplify final suspend point +; +; CHECK-LABEL: define void @cannot_simplify_final_suspend( +; CHECK-NEXT: entry: +; CHECK-NEXT: llvm.coro.id +; +define void @cannot_simplify_final_suspend() "coroutine.presplit"="1" personality i32 0 { +entry: + %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id) + br i1 %need.dyn.alloc, label %dyn.alloc, label %coro.begin +dyn.alloc: + %size = call i32 @llvm.coro.size.i32() + %alloc = call i8* @malloc(i32 %size) + br label %coro.begin +coro.begin: + %phi = phi i8* [ null, %entry ], [ %alloc, %dyn.alloc ] + %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %phi) + br label %body +body: + %save = call token @llvm.coro.save(i8* %hdl) + %subfn = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1) + %bcast = bitcast i8* %subfn to void (i8*)* + invoke fastcc void %bcast(i8* %hdl) to label %real_susp unwind label %lpad + +real_susp: + %0 = call i8 @llvm.coro.suspend(token %save, i1 1) + switch i8 %0, label %suspend [i8 0, label %resume + i8 1, label %pre.cleanup] +resume: + call void @print(i32 0) + br label %cleanup + +pre.cleanup: + call void @print(i32 1) + br label %cleanup + +cleanup: + %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) + call void @free(i8* %mem) + br label %suspend +suspend: + call i1 @llvm.coro.end(i8* %hdl, i1 false) + ret void +lpad: + %lpval = landingpad { i8*, i32 } + cleanup + + call void @print(i32 2) + resume { i8*, i32 } %lpval +} + declare i8* @malloc(i32) declare void @free(i8*) declare void @print(i32) From llvm-branch-commits at lists.llvm.org Wed Apr 29 18:04:44 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Wed, 29 Apr 2020 18:04:44 -0700 (PDT) Subject: [llvm-branch-commits] [libclc] 199494f - libclc: Pass system libraries to the linker after llvm libraries Message-ID: <5eaa242c.1c69fb81.7d3ed.6d74@mx.google.com> Author: Tom Stellard Date: 2020-04-29T18:01:01-07:00 New Revision: 199494f512e96aa86592e849aff2bceb832629c0 URL: https://github.com/llvm/llvm-project/commit/199494f512e96aa86592e849aff2bceb832629c0 DIFF: https://github.com/llvm/llvm-project/commit/199494f512e96aa86592e849aff2bceb832629c0.diff LOG: libclc: Pass system libraries to the linker after llvm libraries Summary: The llvm libraries depend on the symbols in the system libaries, so the system libraries need to be added after. Reviewers: jvesely Reviewed By: jvesely Subscribers: mgorny, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D78535 (cherry picked from commit 174c41defc63db4ac7594e00a5044672ff624a31) Added: Modified: libclc/CMakeLists.txt Removed: ################################################################################ diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index 440eab076509..ca65cf930562 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -113,8 +113,8 @@ link_directories( ${LLVM_LIBDIR} ) add_executable( prepare_builtins utils/prepare-builtins.cpp ) target_compile_options( prepare_builtins PRIVATE ${LLVM_CXX_FLAGS} ) target_compile_definitions( prepare_builtins PRIVATE ${LLVM_VERSION_DEFINE} ) -target_link_libraries( prepare_builtins PRIVATE ${LLVM_SYSTEM_LIBS} ) target_link_libraries( prepare_builtins PRIVATE ${LLVM_LIBS} ) +target_link_libraries( prepare_builtins PRIVATE ${LLVM_SYSTEM_LIBS} ) # Setup arch devices set( r600--_devices cedar cypress barts cayman ) From llvm-branch-commits at lists.llvm.org Thu Apr 30 06:00:59 2020 From: llvm-branch-commits at lists.llvm.org (Alexander Potapenko via llvm-branch-commits) Date: Thu, 30 Apr 2020 06:00:59 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] c9cba16 - [AddressSanitizer] Refactor ClDebug{Min, Max} handling Message-ID: <5eaacc0b.1c69fb81.5524b.ca56@mx.google.com> Author: Jann Horn Date: 2020-04-30T15:00:48+02:00 New Revision: c9cba1600de842f803bb3d55cc4d97deba55f5c8 URL: https://github.com/llvm/llvm-project/commit/c9cba1600de842f803bb3d55cc4d97deba55f5c8 DIFF: https://github.com/llvm/llvm-project/commit/c9cba1600de842f803bb3d55cc4d97deba55f5c8.diff LOG: [AddressSanitizer] Refactor ClDebug{Min,Max} handling Summary: A following commit will split the loop over ToInstrument into two. To avoid having to duplicate the condition for suppressing instrumentation sites based on ClDebug{Min,Max}, refactor it out into a new function. While we're at it, we can also avoid the indirection through NumInstrumented for setting FunctionModified. This is patch 1/4 of a patch series: https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor ClDebug{Min,Max} handling https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory intrinsic handling https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval call arguments Reviewers: kcc, glider Reviewed By: glider Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77616 Added: Modified: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 4556e3275a10..d6dedc6f76ab 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -638,6 +638,7 @@ struct AddressSanitizer { Value *SizeArgument, uint32_t Exp); void instrumentMemIntrinsic(MemIntrinsic *MI); Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); + bool suppressInstrumentationSiteForDebug(int &Instrumented); bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI); bool maybeInsertAsanInitAtFunctionEntry(Function &F); void maybeInsertDynamicShadowAtFunctionEntry(Function &F); @@ -2610,6 +2611,14 @@ void AddressSanitizer::markEscapedLocalAllocas(Function &F) { } } +bool AddressSanitizer::suppressInstrumentationSiteForDebug(int &Instrumented) { + bool ShouldInstrument = + ClDebugMin < 0 || ClDebugMax < 0 || + (Instrumented >= ClDebugMin && Instrumented <= ClDebugMax); + Instrumented++; + return !ShouldInstrument; +} + bool AddressSanitizer::instrumentFunction(Function &F, const TargetLibraryInfo *TLI) { if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false; @@ -2710,15 +2719,14 @@ bool AddressSanitizer::instrumentFunction(Function &F, // Instrument. int NumInstrumented = 0; for (auto Inst : ToInstrument) { - if (ClDebugMin < 0 || ClDebugMax < 0 || - (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) { + if (!suppressInstrumentationSiteForDebug(NumInstrumented)) { if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment)) instrumentMop(ObjSizeVis, Inst, UseCalls, F.getParent()->getDataLayout()); else instrumentMemIntrinsic(cast(Inst)); } - NumInstrumented++; + FunctionModified = true; } FunctionStackPoisoner FSP(F, *this); @@ -2733,10 +2741,10 @@ bool AddressSanitizer::instrumentFunction(Function &F, for (auto Inst : PointerComparisonsOrSubtracts) { instrumentPointerComparisonOrSubtraction(Inst); - NumInstrumented++; + FunctionModified = true; } - if (NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty()) + if (ChangedStack || !NoReturnCalls.empty()) FunctionModified = true; LLVM_DEBUG(dbgs() << "ASAN done instrumenting: " << FunctionModified << " " From llvm-branch-commits at lists.llvm.org Thu Apr 30 06:01:01 2020 From: llvm-branch-commits at lists.llvm.org (Alexander Potapenko via llvm-branch-commits) Date: Thu, 30 Apr 2020 06:01:01 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] eea0313 - [AddressSanitizer] Split out memory intrinsic handling Message-ID: <5eaacc0d.1c69fb81.ea904.bc88@mx.google.com> Author: Jann Horn Date: 2020-04-30T15:00:48+02:00 New Revision: eea0313cd52e43cc48665ba989b6d861c6e35232 URL: https://github.com/llvm/llvm-project/commit/eea0313cd52e43cc48665ba989b6d861c6e35232 DIFF: https://github.com/llvm/llvm-project/commit/eea0313cd52e43cc48665ba989b6d861c6e35232.diff LOG: [AddressSanitizer] Split out memory intrinsic handling Summary: In both AddressSanitizer and HWAddressSanitizer, we first collect instructions whose operands should be instrumented and memory intrinsics, then instrument them. Both during collection and when inserting instrumentation, they are handled separately. Collect them separately and instrument them separately. This is a bit more straightforward, and prepares for collecting operands instead of instructions in a future patch. This is patch 2/4 of a patch series: https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor ClDebug{Min,Max} handling https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory intrinsic handling https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval call arguments Reviewers: kcc, glider Reviewed By: glider Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77617 Added: Modified: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index d6dedc6f76ab..fcb2b17a7cf5 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -2652,6 +2652,7 @@ bool AddressSanitizer::instrumentFunction(Function &F, // are calls between uses). SmallPtrSet TempsToInstrument; SmallVector ToInstrument; + SmallVector IntrinToInstrument; SmallVector NoReturnCalls; SmallVector AllBlocks; SmallVector PointerComparisonsOrSubtracts; @@ -2688,8 +2689,11 @@ bool AddressSanitizer::instrumentFunction(Function &F, isInterestingPointerSubtraction(&Inst))) { PointerComparisonsOrSubtracts.push_back(&Inst); continue; - } else if (isa(Inst)) { + } else if (MemIntrinsic *MI = dyn_cast(&Inst)) { // ok, take it. + IntrinToInstrument.push_back(MI); + NumInsnsPerBB++; + continue; } else { if (isa(Inst)) NumAllocas++; if (auto *CB = dyn_cast(&Inst)) { @@ -2708,9 +2712,9 @@ bool AddressSanitizer::instrumentFunction(Function &F, } } - bool UseCalls = - (ClInstrumentationWithCallsThreshold >= 0 && - ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold); + bool UseCalls = (ClInstrumentationWithCallsThreshold >= 0 && + ToInstrument.size() + IntrinToInstrument.size() > + (unsigned)ClInstrumentationWithCallsThreshold); const DataLayout &DL = F.getParent()->getDataLayout(); ObjectSizeOpts ObjSizeOpts; ObjSizeOpts.RoundToAlign = true; @@ -2723,9 +2727,11 @@ bool AddressSanitizer::instrumentFunction(Function &F, if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment)) instrumentMop(ObjSizeVis, Inst, UseCalls, F.getParent()->getDataLayout()); - else - instrumentMemIntrinsic(cast(Inst)); } + } + for (auto Inst : IntrinToInstrument) { + if (!suppressInstrumentationSiteForDebug(NumInstrumented)) + instrumentMemIntrinsic(Inst); FunctionModified = true; } diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 9470cb2cfb28..8c9bc428e7f4 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -720,11 +720,6 @@ bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) { uint64_t TypeSize = 0; Value *MaybeMask = nullptr; - if (ClInstrumentMemIntrinsics && isa(I)) { - instrumentMemIntrinsic(cast(I)); - return true; - } - Value *Addr = isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask); @@ -1090,6 +1085,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n"); SmallVector ToInstrument; + SmallVector IntrinToInstrument; SmallVector AllocasToInstrument; SmallVector RetVec; SmallVector LandingPadVec; @@ -1121,8 +1117,11 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { uint64_t TypeSize; Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize, &Alignment, &MaybeMask); - if (Addr || isa(Inst)) + if (Addr) ToInstrument.push_back(&Inst); + + if (MemIntrinsic *MI = dyn_cast(&Inst)) + IntrinToInstrument.push_back(MI); } } @@ -1138,7 +1137,8 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { F.setPersonalityFn(nullptr); } - if (AllocasToInstrument.empty() && ToInstrument.empty()) + if (AllocasToInstrument.empty() && ToInstrument.empty() && + IntrinToInstrument.empty()) return false; assert(!LocalDynamicShadow); @@ -1219,6 +1219,12 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { for (auto Inst : ToInstrument) Changed |= instrumentMemAccess(Inst); + if (ClInstrumentMemIntrinsics && !IntrinToInstrument.empty()) { + for (auto Inst : IntrinToInstrument) + instrumentMemIntrinsic(cast(Inst)); + Changed = true; + } + LocalDynamicShadow = nullptr; StackBaseTag = nullptr; From llvm-branch-commits at lists.llvm.org Thu Apr 30 06:01:03 2020 From: llvm-branch-commits at lists.llvm.org (Alexander Potapenko via llvm-branch-commits) Date: Thu, 30 Apr 2020 06:01:03 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 7df5537 - [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction Message-ID: <5eaacc0f.1c69fb81.7d414.ae62@mx.google.com> Author: Jann Horn Date: 2020-04-30T15:00:48+02:00 New Revision: 7df5537f8d3c4f8033b7b32809684cb688fe5ebe URL: https://github.com/llvm/llvm-project/commit/7df5537f8d3c4f8033b7b32809684cb688fe5ebe DIFF: https://github.com/llvm/llvm-project/commit/7df5537f8d3c4f8033b7b32809684cb688fe5ebe.diff LOG: [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction Summary: Refactor getInterestingMemoryOperands() so that information about the pointer operand is returned through an array of structures instead of passing each piece of information separately by-value. This is in preparation for returning information about multiple pointer operands from a single instruction. A side effect is that, instead of repeatedly generating the same information through isInterestingMemoryAccess(), it is now simply collected once and then passed around; that's probably more efficient. HWAddressSanitizer has a bunch of copypasted code from AddressSanitizer, so these changes have to be duplicated. This is patch 3/4 of a patch series: https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor ClDebug{Min,Max} handling https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory intrinsic handling https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval call arguments [glider: renamed llvm::InterestingMemoryOperand::Type to OpType to fix GCC compilation] Reviewers: kcc, glider Reviewed By: glider Subscribers: hiraditya, jfb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77618 Added: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h Modified: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp Removed: ################################################################################ diff --git a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h new file mode 100644 index 000000000000..ef33fa2147d1 --- /dev/null +++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h @@ -0,0 +1,49 @@ +//===--------- Definition of the AddressSanitizer class ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares common infrastructure for AddressSanitizer and +// HWAddressSanitizer. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H +#define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H + +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Module.h" + +namespace llvm { + +class InterestingMemoryOperand { +public: + Use *PtrUse; + bool IsWrite; + Type *OpType; + uint64_t TypeSize; + unsigned Alignment; + // The mask Value, if we're looking at a masked load/store. + Value *MaybeMask; + + InterestingMemoryOperand(Instruction *I, unsigned OperandNo, bool IsWrite, + class Type *OpType, unsigned Alignment, + Value *MaybeMask = nullptr) + : IsWrite(IsWrite), OpType(OpType), Alignment(Alignment), + MaybeMask(MaybeMask) { + const DataLayout &DL = I->getModule()->getDataLayout(); + TypeSize = DL.getTypeStoreSizeInBits(OpType); + PtrUse = &I->getOperandUse(OperandNo); + } + + Instruction *getInsn() { return cast(PtrUse->getUser()); } + + Value *getPtr() { return PtrUse->get(); } +}; + +} // namespace llvm + +#endif diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index fcb2b17a7cf5..6226bcd35381 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -69,6 +69,7 @@ #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h" #include "llvm/Transforms/Utils/ASanStackFrameLayout.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" @@ -612,16 +613,13 @@ struct AddressSanitizer { /// Check if we want (and can) handle this alloca. bool isInterestingAlloca(const AllocaInst &AI); - /// If it is an interesting memory access, return the PointerOperand - /// and set IsWrite/Alignment. Otherwise return nullptr. - /// MaybeMask is an output parameter for the mask Value, if we're looking at a - /// masked load/store. - Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, - uint64_t *TypeSize, unsigned *Alignment, - Value **MaybeMask = nullptr); + bool ignoreAccess(Value *Ptr); + void getInterestingMemoryOperands( + Instruction *I, SmallVectorImpl &Interesting); - void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, Instruction *I, - bool UseCalls, const DataLayout &DL); + void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, + InterestingMemoryOperand &O, bool UseCalls, + const DataLayout &DL); void instrumentPointerComparisonOrSubtraction(Instruction *I); void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore, Value *Addr, uint32_t TypeSize, bool IsWrite, @@ -1340,98 +1338,84 @@ bool AddressSanitizer::isInterestingAlloca(const AllocaInst &AI) { return IsInteresting; } -Value *AddressSanitizer::isInterestingMemoryAccess(Instruction *I, - bool *IsWrite, - uint64_t *TypeSize, - unsigned *Alignment, - Value **MaybeMask) { +bool AddressSanitizer::ignoreAccess(Value *Ptr) { + // Do not instrument acesses from diff erent address spaces; we cannot deal + // with them. + Type *PtrTy = cast(Ptr->getType()->getScalarType()); + if (PtrTy->getPointerAddressSpace() != 0) + return true; + + // Ignore swifterror addresses. + // swifterror memory addresses are mem2reg promoted by instruction + // selection. As such they cannot have regular uses like an instrumentation + // function and it makes no sense to track them as memory. + if (Ptr->isSwiftError()) + return true; + + // Treat memory accesses to promotable allocas as non-interesting since they + // will not cause memory violations. This greatly speeds up the instrumented + // executable at -O0. + if (auto AI = dyn_cast_or_null(Ptr)) + if (ClSkipPromotableAllocas && !isInterestingAlloca(*AI)) + return true; + + return false; +} + +void AddressSanitizer::getInterestingMemoryOperands( + Instruction *I, SmallVectorImpl &Interesting) { // Skip memory accesses inserted by another instrumentation. - if (I->hasMetadata("nosanitize")) return nullptr; + if (I->hasMetadata("nosanitize")) + return; // Do not instrument the load fetching the dynamic shadow address. if (LocalDynamicShadow == I) - return nullptr; + return; - Value *PtrOperand = nullptr; - const DataLayout &DL = I->getModule()->getDataLayout(); if (LoadInst *LI = dyn_cast(I)) { - if (!ClInstrumentReads) return nullptr; - *IsWrite = false; - *TypeSize = DL.getTypeStoreSizeInBits(LI->getType()); - *Alignment = LI->getAlignment(); - PtrOperand = LI->getPointerOperand(); + if (!ClInstrumentReads || ignoreAccess(LI->getPointerOperand())) + return; + Interesting.emplace_back(I, LI->getPointerOperandIndex(), false, + LI->getType(), LI->getAlignment()); } else if (StoreInst *SI = dyn_cast(I)) { - if (!ClInstrumentWrites) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType()); - *Alignment = SI->getAlignment(); - PtrOperand = SI->getPointerOperand(); + if (!ClInstrumentWrites || ignoreAccess(SI->getPointerOperand())) + return; + Interesting.emplace_back(I, SI->getPointerOperandIndex(), true, + SI->getValueOperand()->getType(), + SI->getAlignment()); } else if (AtomicRMWInst *RMW = dyn_cast(I)) { - if (!ClInstrumentAtomics) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType()); - *Alignment = 0; - PtrOperand = RMW->getPointerOperand(); + if (!ClInstrumentAtomics || ignoreAccess(RMW->getPointerOperand())) + return; + Interesting.emplace_back(I, RMW->getPointerOperandIndex(), true, + RMW->getValOperand()->getType(), 0); } else if (AtomicCmpXchgInst *XCHG = dyn_cast(I)) { - if (!ClInstrumentAtomics) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType()); - *Alignment = 0; - PtrOperand = XCHG->getPointerOperand(); + if (!ClInstrumentAtomics || ignoreAccess(XCHG->getPointerOperand())) + return; + Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true, + XCHG->getCompareOperand()->getType(), 0); } else if (auto CI = dyn_cast(I)) { auto *F = CI->getCalledFunction(); if (F && (F->getName().startswith("llvm.masked.load.") || F->getName().startswith("llvm.masked.store."))) { - unsigned OpOffset = 0; - if (F->getName().startswith("llvm.masked.store.")) { - if (!ClInstrumentWrites) - return nullptr; - // Masked store has an initial operand for the value. - OpOffset = 1; - *IsWrite = true; - } else { - if (!ClInstrumentReads) - return nullptr; - *IsWrite = false; - } - - auto BasePtr = CI->getOperand(0 + OpOffset); + bool IsWrite = F->getName().startswith("llvm.masked.store."); + // Masked store has an initial operand for the value. + unsigned OpOffset = IsWrite ? 1 : 0; + if (IsWrite ? !ClInstrumentWrites : !ClInstrumentReads) + return; + + auto BasePtr = CI->getOperand(OpOffset); + if (ignoreAccess(BasePtr)) + return; auto Ty = cast(BasePtr->getType())->getElementType(); - *TypeSize = DL.getTypeStoreSizeInBits(Ty); + unsigned Alignment = 1; + // Otherwise no alignment guarantees. We probably got Undef. if (auto AlignmentConstant = dyn_cast(CI->getOperand(1 + OpOffset))) - *Alignment = (unsigned)AlignmentConstant->getZExtValue(); - else - *Alignment = 1; // No alignment guarantees. We probably got Undef - if (MaybeMask) - *MaybeMask = CI->getOperand(2 + OpOffset); - PtrOperand = BasePtr; + Alignment = (unsigned)AlignmentConstant->getZExtValue(); + Value *Mask = CI->getOperand(2 + OpOffset); + Interesting.emplace_back(I, OpOffset, IsWrite, Ty, Alignment, Mask); } } - - if (PtrOperand) { - // Do not instrument acesses from diff erent address spaces; we cannot deal - // with them. - Type *PtrTy = cast(PtrOperand->getType()->getScalarType()); - if (PtrTy->getPointerAddressSpace() != 0) - return nullptr; - - // Ignore swifterror addresses. - // swifterror memory addresses are mem2reg promoted by instruction - // selection. As such they cannot have regular uses like an instrumentation - // function and it makes no sense to track them as memory. - if (PtrOperand->isSwiftError()) - return nullptr; - } - - // Treat memory accesses to promotable allocas as non-interesting since they - // will not cause memory violations. This greatly speeds up the instrumented - // executable at -O0. - if (ClSkipPromotableAllocas) - if (auto AI = dyn_cast_or_null(PtrOperand)) - return isInterestingAlloca(*AI) ? AI : nullptr; - - return PtrOperand; } static bool isPointerOperand(Value *V) { @@ -1546,15 +1530,9 @@ static void instrumentMaskedLoadOrStore(AddressSanitizer *Pass, } void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, - Instruction *I, bool UseCalls, + InterestingMemoryOperand &O, bool UseCalls, const DataLayout &DL) { - bool IsWrite = false; - unsigned Alignment = 0; - uint64_t TypeSize = 0; - Value *MaybeMask = nullptr; - Value *Addr = - isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask); - assert(Addr); + Value *Addr = O.getPtr(); // Optimization experiments. // The experiments can be used to evaluate potential optimizations that remove @@ -1574,7 +1552,7 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, // dynamically initialized global is always valid. GlobalVariable *G = dyn_cast(GetUnderlyingObject(Addr, DL)); if (G && (!ClInitializers || GlobalIsLinkerInitialized(G)) && - isSafeAccess(ObjSizeVis, Addr, TypeSize)) { + isSafeAccess(ObjSizeVis, Addr, O.TypeSize)) { NumOptimizedAccessesToGlobalVar++; return; } @@ -1583,25 +1561,26 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, if (ClOpt && ClOptStack) { // A direct inbounds access to a stack variable is always valid. if (isa(GetUnderlyingObject(Addr, DL)) && - isSafeAccess(ObjSizeVis, Addr, TypeSize)) { + isSafeAccess(ObjSizeVis, Addr, O.TypeSize)) { NumOptimizedAccessesToStackVar++; return; } } - if (IsWrite) + if (O.IsWrite) NumInstrumentedWrites++; else NumInstrumentedReads++; unsigned Granularity = 1 << Mapping.Scale; - if (MaybeMask) { - instrumentMaskedLoadOrStore(this, DL, IntptrTy, MaybeMask, I, Addr, - Alignment, Granularity, TypeSize, IsWrite, - nullptr, UseCalls, Exp); + if (O.MaybeMask) { + instrumentMaskedLoadOrStore(this, DL, IntptrTy, O.MaybeMask, O.getInsn(), + Addr, O.Alignment, Granularity, O.TypeSize, + O.IsWrite, nullptr, UseCalls, Exp); } else { - doInstrumentAddress(this, I, I, Addr, Alignment, Granularity, TypeSize, - IsWrite, nullptr, UseCalls, Exp); + doInstrumentAddress(this, O.getInsn(), O.getInsn(), Addr, O.Alignment, + Granularity, O.TypeSize, O.IsWrite, nullptr, UseCalls, + Exp); } } @@ -2651,15 +2630,12 @@ bool AddressSanitizer::instrumentFunction(Function &F, // We want to instrument every address only once per basic block (unless there // are calls between uses). SmallPtrSet TempsToInstrument; - SmallVector ToInstrument; + SmallVector OperandsToInstrument; SmallVector IntrinToInstrument; SmallVector NoReturnCalls; SmallVector AllBlocks; SmallVector PointerComparisonsOrSubtracts; int NumAllocas = 0; - bool IsWrite; - unsigned Alignment; - uint64_t TypeSize; // Fill the set of memory operations to instrument. for (auto &BB : F) { @@ -2668,32 +2644,36 @@ bool AddressSanitizer::instrumentFunction(Function &F, int NumInsnsPerBB = 0; for (auto &Inst : BB) { if (LooksLikeCodeInBug11395(&Inst)) return false; - Value *MaybeMask = nullptr; - if (Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize, - &Alignment, &MaybeMask)) { - if (ClOpt && ClOptSameTemp) { - // If we have a mask, skip instrumentation if we've already - // instrumented the full object. But don't add to TempsToInstrument - // because we might get another load/store with a diff erent mask. - if (MaybeMask) { - if (TempsToInstrument.count(Addr)) - continue; // We've seen this (whole) temp in the current BB. - } else { - if (!TempsToInstrument.insert(Addr).second) - continue; // We've seen this temp in the current BB. + SmallVector InterestingOperands; + getInterestingMemoryOperands(&Inst, InterestingOperands); + + if (!InterestingOperands.empty()) { + for (auto &Operand : InterestingOperands) { + if (ClOpt && ClOptSameTemp) { + Value *Ptr = Operand.getPtr(); + // If we have a mask, skip instrumentation if we've already + // instrumented the full object. But don't add to TempsToInstrument + // because we might get another load/store with a diff erent mask. + if (Operand.MaybeMask) { + if (TempsToInstrument.count(Ptr)) + continue; // We've seen this (whole) temp in the current BB. + } else { + if (!TempsToInstrument.insert(Ptr).second) + continue; // We've seen this temp in the current BB. + } } + OperandsToInstrument.push_back(Operand); + NumInsnsPerBB++; } } else if (((ClInvalidPointerPairs || ClInvalidPointerCmp) && isInterestingPointerComparison(&Inst)) || ((ClInvalidPointerPairs || ClInvalidPointerSub) && isInterestingPointerSubtraction(&Inst))) { PointerComparisonsOrSubtracts.push_back(&Inst); - continue; } else if (MemIntrinsic *MI = dyn_cast(&Inst)) { // ok, take it. IntrinToInstrument.push_back(MI); NumInsnsPerBB++; - continue; } else { if (isa(Inst)) NumAllocas++; if (auto *CB = dyn_cast(&Inst)) { @@ -2704,16 +2684,13 @@ bool AddressSanitizer::instrumentFunction(Function &F, } if (CallInst *CI = dyn_cast(&Inst)) maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI); - continue; } - ToInstrument.push_back(&Inst); - NumInsnsPerBB++; if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB) break; } } bool UseCalls = (ClInstrumentationWithCallsThreshold >= 0 && - ToInstrument.size() + IntrinToInstrument.size() > + OperandsToInstrument.size() + IntrinToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold); const DataLayout &DL = F.getParent()->getDataLayout(); ObjectSizeOpts ObjSizeOpts; @@ -2722,12 +2699,11 @@ bool AddressSanitizer::instrumentFunction(Function &F, // Instrument. int NumInstrumented = 0; - for (auto Inst : ToInstrument) { - if (!suppressInstrumentationSiteForDebug(NumInstrumented)) { - if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment)) - instrumentMop(ObjSizeVis, Inst, UseCalls, - F.getParent()->getDataLayout()); - } + for (auto &Operand : OperandsToInstrument) { + if (!suppressInstrumentationSiteForDebug(NumInstrumented)) + instrumentMop(ObjSizeVis, Operand, UseCalls, + F.getParent()->getDataLayout()); + FunctionModified = true; } for (auto Inst : IntrinToInstrument) { if (!suppressInstrumentationSiteForDebug(NumInstrumented)) diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 8c9bc428e7f4..982c1d3516cc 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -45,6 +45,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" @@ -211,10 +212,10 @@ class HWAddressSanitizer { unsigned AccessSizeIndex, Instruction *InsertBefore); void instrumentMemIntrinsic(MemIntrinsic *MI); - bool instrumentMemAccess(Instruction *I); - Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, - uint64_t *TypeSize, unsigned *Alignment, - Value **MaybeMask); + bool instrumentMemAccess(InterestingMemoryOperand &O); + bool ignoreAccess(Value *Ptr); + void getInterestingMemoryOperands( + Instruction *I, SmallVectorImpl &Interesting); bool isInterestingAlloca(const AllocaInst &AI); bool tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag, size_t Size); @@ -500,62 +501,55 @@ Value *HWAddressSanitizer::getDynamicShadowNonTls(IRBuilder<> &IRB) { } } -Value *HWAddressSanitizer::isInterestingMemoryAccess(Instruction *I, - bool *IsWrite, - uint64_t *TypeSize, - unsigned *Alignment, - Value **MaybeMask) { +bool HWAddressSanitizer::ignoreAccess(Value *Ptr) { + // Do not instrument acesses from diff erent address spaces; we cannot deal + // with them. + Type *PtrTy = cast(Ptr->getType()->getScalarType()); + if (PtrTy->getPointerAddressSpace() != 0) + return true; + + // Ignore swifterror addresses. + // swifterror memory addresses are mem2reg promoted by instruction + // selection. As such they cannot have regular uses like an instrumentation + // function and it makes no sense to track them as memory. + if (Ptr->isSwiftError()) + return true; + + return false; +} + +void HWAddressSanitizer::getInterestingMemoryOperands( + Instruction *I, SmallVectorImpl &Interesting) { // Skip memory accesses inserted by another instrumentation. - if (I->hasMetadata("nosanitize")) return nullptr; + if (I->hasMetadata("nosanitize")) + return; // Do not instrument the load fetching the dynamic shadow address. if (LocalDynamicShadow == I) - return nullptr; + return; - Value *PtrOperand = nullptr; - const DataLayout &DL = I->getModule()->getDataLayout(); if (LoadInst *LI = dyn_cast(I)) { - if (!ClInstrumentReads) return nullptr; - *IsWrite = false; - *TypeSize = DL.getTypeStoreSizeInBits(LI->getType()); - *Alignment = LI->getAlignment(); - PtrOperand = LI->getPointerOperand(); + if (!ClInstrumentReads || ignoreAccess(LI->getPointerOperand())) + return; + Interesting.emplace_back(I, LI->getPointerOperandIndex(), false, + LI->getType(), LI->getAlignment()); } else if (StoreInst *SI = dyn_cast(I)) { - if (!ClInstrumentWrites) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType()); - *Alignment = SI->getAlignment(); - PtrOperand = SI->getPointerOperand(); + if (!ClInstrumentWrites || ignoreAccess(SI->getPointerOperand())) + return; + Interesting.emplace_back(I, SI->getPointerOperandIndex(), true, + SI->getValueOperand()->getType(), + SI->getAlignment()); } else if (AtomicRMWInst *RMW = dyn_cast(I)) { - if (!ClInstrumentAtomics) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType()); - *Alignment = 0; - PtrOperand = RMW->getPointerOperand(); + if (!ClInstrumentAtomics || ignoreAccess(RMW->getPointerOperand())) + return; + Interesting.emplace_back(I, RMW->getPointerOperandIndex(), true, + RMW->getValOperand()->getType(), 0); } else if (AtomicCmpXchgInst *XCHG = dyn_cast(I)) { - if (!ClInstrumentAtomics) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType()); - *Alignment = 0; - PtrOperand = XCHG->getPointerOperand(); - } - - if (PtrOperand) { - // Do not instrument accesses from diff erent address spaces; we cannot deal - // with them. - Type *PtrTy = cast(PtrOperand->getType()->getScalarType()); - if (PtrTy->getPointerAddressSpace() != 0) - return nullptr; - - // Ignore swifterror addresses. - // swifterror memory addresses are mem2reg promoted by instruction - // selection. As such they cannot have regular uses like an instrumentation - // function and it makes no sense to track them as memory. - if (PtrOperand->isSwiftError()) - return nullptr; + if (!ClInstrumentAtomics || ignoreAccess(XCHG->getPointerOperand())) + return; + Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true, + XCHG->getCompareOperand()->getType(), 0); } - - return PtrOperand; } static unsigned getPointerOperandIndex(Instruction *I) { @@ -713,40 +707,32 @@ void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { MI->eraseFromParent(); } -bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) { - LLVM_DEBUG(dbgs() << "Instrumenting: " << *I << "\n"); - bool IsWrite = false; - unsigned Alignment = 0; - uint64_t TypeSize = 0; - Value *MaybeMask = nullptr; +bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) { + Value *Addr = O.getPtr(); - Value *Addr = - isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask); + LLVM_DEBUG(dbgs() << "Instrumenting: " << O.getInsn() << "\n"); - if (!Addr) - return false; - - if (MaybeMask) + if (O.MaybeMask) return false; //FIXME - IRBuilder<> IRB(I); - if (isPowerOf2_64(TypeSize) && - (TypeSize / 8 <= (1UL << (kNumberOfAccessSizes - 1))) && - (Alignment >= (1UL << Mapping.Scale) || Alignment == 0 || - Alignment >= TypeSize / 8)) { - size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); + IRBuilder<> IRB(O.getInsn()); + if (isPowerOf2_64(O.TypeSize) && + (O.TypeSize / 8 <= (1UL << (kNumberOfAccessSizes - 1))) && + (O.Alignment >= (1UL << Mapping.Scale) || O.Alignment == 0 || + O.Alignment >= O.TypeSize / 8)) { + size_t AccessSizeIndex = TypeSizeToSizeIndex(O.TypeSize); if (ClInstrumentWithCalls) { - IRB.CreateCall(HwasanMemoryAccessCallback[IsWrite][AccessSizeIndex], + IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex], IRB.CreatePointerCast(Addr, IntptrTy)); } else { - instrumentMemAccessInline(Addr, IsWrite, AccessSizeIndex, I); + instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn()); } } else { - IRB.CreateCall(HwasanMemoryAccessCallbackSized[IsWrite], + IRB.CreateCall(HwasanMemoryAccessCallbackSized[O.IsWrite], {IRB.CreatePointerCast(Addr, IntptrTy), - ConstantInt::get(IntptrTy, TypeSize / 8)}); + ConstantInt::get(IntptrTy, O.TypeSize / 8)}); } - untagPointerOperand(I, Addr); + untagPointerOperand(O.getInsn(), Addr); return true; } @@ -1084,7 +1070,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n"); - SmallVector ToInstrument; + SmallVector OperandsToInstrument; SmallVector IntrinToInstrument; SmallVector AllocasToInstrument; SmallVector RetVec; @@ -1111,14 +1097,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { if (InstrumentLandingPads && isa(Inst)) LandingPadVec.push_back(&Inst); - Value *MaybeMask = nullptr; - bool IsWrite; - unsigned Alignment; - uint64_t TypeSize; - Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize, - &Alignment, &MaybeMask); - if (Addr) - ToInstrument.push_back(&Inst); + getInterestingMemoryOperands(&Inst, OperandsToInstrument); if (MemIntrinsic *MI = dyn_cast(&Inst)) IntrinToInstrument.push_back(MI); @@ -1137,7 +1116,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { F.setPersonalityFn(nullptr); } - if (AllocasToInstrument.empty() && ToInstrument.empty() && + if (AllocasToInstrument.empty() && OperandsToInstrument.empty() && IntrinToInstrument.empty()) return false; @@ -1216,8 +1195,8 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { } } - for (auto Inst : ToInstrument) - Changed |= instrumentMemAccess(Inst); + for (auto &Operand : OperandsToInstrument) + Changed |= instrumentMemAccess(Operand); if (ClInstrumentMemIntrinsics && !IntrinToInstrument.empty()) { for (auto Inst : IntrinToInstrument) From llvm-branch-commits at lists.llvm.org Thu Apr 30 06:01:05 2020 From: llvm-branch-commits at lists.llvm.org (Alexander Potapenko via llvm-branch-commits) Date: Thu, 30 Apr 2020 06:01:05 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 84d341f - [AddressSanitizer] Instrument byval call arguments Message-ID: <5eaacc11.1c69fb81.a5c4d.6a31@mx.google.com> Author: Jann Horn Date: 2020-04-30T15:00:49+02:00 New Revision: 84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae URL: https://github.com/llvm/llvm-project/commit/84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae DIFF: https://github.com/llvm/llvm-project/commit/84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae.diff LOG: [AddressSanitizer] Instrument byval call arguments Summary: In the LLVM IR, "call" instructions read memory for each byval operand. For example: ``` $ cat blah.c struct foo { void *a, *b, *c; }; struct bar { struct foo foo; }; void func1(const struct foo); void func2(struct bar *bar) { func1(bar->foo); } $ [...]/bin/clang -S -flto -c blah.c -O2 ; cat blah.s [...] define dso_local void @func2(%struct.bar* %bar) local_unnamed_addr #0 { entry: %foo = getelementptr inbounds %struct.bar, %struct.bar* %bar, i64 0, i32 0 tail call void @func1(%struct.foo* byval(%struct.foo) align 8 %foo) #2 ret void } [...] $ [...]/bin/clang -S -c blah.c -O2 ; cat blah.s [...] func2: # @func2 [...] subq $24, %rsp [...] movq 16(%rdi), %rax movq %rax, 16(%rsp) movups (%rdi), %xmm0 movups %xmm0, (%rsp) callq func1 addq $24, %rsp [...] retq ``` Let ASAN instrument these hidden memory accesses. This is patch 4/4 of a patch series: https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor ClDebug{Min,Max} handling https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory intrinsic handling https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval call arguments Reviewers: kcc, glider Reviewed By: glider Subscribers: hiraditya, dexonsmith, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77619 Added: llvm/test/Instrumentation/AddressSanitizer/byval-args.ll Modified: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 6226bcd35381..93326c8fd13a 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -213,6 +213,11 @@ static cl::opt ClInstrumentAtomics( cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true)); +static cl::opt + ClInstrumentByval("asan-instrument-byval", + cl::desc("instrument byval call arguments"), cl::Hidden, + cl::init(true)); + static cl::opt ClAlwaysSlowPath( "asan-always-slow-path", cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, @@ -1414,6 +1419,14 @@ void AddressSanitizer::getInterestingMemoryOperands( Alignment = (unsigned)AlignmentConstant->getZExtValue(); Value *Mask = CI->getOperand(2 + OpOffset); Interesting.emplace_back(I, OpOffset, IsWrite, Ty, Alignment, Mask); + } else { + for (unsigned ArgNo = 0; ArgNo < CI->getNumArgOperands(); ArgNo++) { + if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) || + ignoreAccess(CI->getArgOperand(ArgNo))) + continue; + Type *Ty = CI->getParamByValType(ArgNo); + Interesting.emplace_back(I, ArgNo, false, Ty, 1); + } } } } diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 982c1d3516cc..0b9856b5126a 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -97,6 +97,10 @@ static cl::opt ClInstrumentAtomics( cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true)); +static cl::opt ClInstrumentByval("hwasan-instrument-byval", + cl::desc("instrument byval arguments"), + cl::Hidden, cl::init(true)); + static cl::opt ClRecover( "hwasan-recover", cl::desc("Enable recovery mode (continue-after-error)."), @@ -549,6 +553,14 @@ void HWAddressSanitizer::getInterestingMemoryOperands( return; Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true, XCHG->getCompareOperand()->getType(), 0); + } else if (auto CI = dyn_cast(I)) { + for (unsigned ArgNo = 0; ArgNo < CI->getNumArgOperands(); ArgNo++) { + if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) || + ignoreAccess(CI->getArgOperand(ArgNo))) + continue; + Type *Ty = CI->getParamByValType(ArgNo); + Interesting.emplace_back(I, ArgNo, false, Ty, 1); + } } } diff --git a/llvm/test/Instrumentation/AddressSanitizer/byval-args.ll b/llvm/test/Instrumentation/AddressSanitizer/byval-args.ll new file mode 100644 index 000000000000..a070cedca37d --- /dev/null +++ b/llvm/test/Instrumentation/AddressSanitizer/byval-args.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -asan -S | FileCheck %s +; Test that for call instructions, the by-value arguments are instrumented. + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.bar = type { %struct.foo } +%struct.foo = type { i8*, i8*, i8* } +define dso_local void @func2(%struct.foo* %foo) sanitize_address { +; CHECK-LABEL: @func2 + tail call void @func1(%struct.foo* byval(%struct.foo) align 8 %foo) #2 +; CHECK: call void @__asan_report_load + ret void +; CHECK: ret void +} +declare dso_local void @func1(%struct.foo* byval(%struct.foo) align 8) + +!0 = !{i32 1, !"wchar_size", i32 4} From llvm-branch-commits at lists.llvm.org Thu Apr 30 06:03:56 2020 From: llvm-branch-commits at lists.llvm.org (Alexander Potapenko via llvm-branch-commits) Date: Thu, 30 Apr 2020 06:03:56 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] c9cba16 - [AddressSanitizer] Refactor ClDebug{Min, Max} handling Message-ID: <5eaaccbc.1c69fb81.69f9b.a67e@mx.google.com> Author: Jann Horn Date: 2020-04-30T15:00:48+02:00 New Revision: c9cba1600de842f803bb3d55cc4d97deba55f5c8 URL: https://github.com/llvm/llvm-project/commit/c9cba1600de842f803bb3d55cc4d97deba55f5c8 DIFF: https://github.com/llvm/llvm-project/commit/c9cba1600de842f803bb3d55cc4d97deba55f5c8.diff LOG: [AddressSanitizer] Refactor ClDebug{Min,Max} handling Summary: A following commit will split the loop over ToInstrument into two. To avoid having to duplicate the condition for suppressing instrumentation sites based on ClDebug{Min,Max}, refactor it out into a new function. While we're at it, we can also avoid the indirection through NumInstrumented for setting FunctionModified. This is patch 1/4 of a patch series: https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor ClDebug{Min,Max} handling https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory intrinsic handling https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval call arguments Reviewers: kcc, glider Reviewed By: glider Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77616 Added: Modified: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 4556e3275a10..d6dedc6f76ab 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -638,6 +638,7 @@ struct AddressSanitizer { Value *SizeArgument, uint32_t Exp); void instrumentMemIntrinsic(MemIntrinsic *MI); Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); + bool suppressInstrumentationSiteForDebug(int &Instrumented); bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI); bool maybeInsertAsanInitAtFunctionEntry(Function &F); void maybeInsertDynamicShadowAtFunctionEntry(Function &F); @@ -2610,6 +2611,14 @@ void AddressSanitizer::markEscapedLocalAllocas(Function &F) { } } +bool AddressSanitizer::suppressInstrumentationSiteForDebug(int &Instrumented) { + bool ShouldInstrument = + ClDebugMin < 0 || ClDebugMax < 0 || + (Instrumented >= ClDebugMin && Instrumented <= ClDebugMax); + Instrumented++; + return !ShouldInstrument; +} + bool AddressSanitizer::instrumentFunction(Function &F, const TargetLibraryInfo *TLI) { if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false; @@ -2710,15 +2719,14 @@ bool AddressSanitizer::instrumentFunction(Function &F, // Instrument. int NumInstrumented = 0; for (auto Inst : ToInstrument) { - if (ClDebugMin < 0 || ClDebugMax < 0 || - (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) { + if (!suppressInstrumentationSiteForDebug(NumInstrumented)) { if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment)) instrumentMop(ObjSizeVis, Inst, UseCalls, F.getParent()->getDataLayout()); else instrumentMemIntrinsic(cast(Inst)); } - NumInstrumented++; + FunctionModified = true; } FunctionStackPoisoner FSP(F, *this); @@ -2733,10 +2741,10 @@ bool AddressSanitizer::instrumentFunction(Function &F, for (auto Inst : PointerComparisonsOrSubtracts) { instrumentPointerComparisonOrSubtraction(Inst); - NumInstrumented++; + FunctionModified = true; } - if (NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty()) + if (ChangedStack || !NoReturnCalls.empty()) FunctionModified = true; LLVM_DEBUG(dbgs() << "ASAN done instrumenting: " << FunctionModified << " " From llvm-branch-commits at lists.llvm.org Thu Apr 30 06:03:58 2020 From: llvm-branch-commits at lists.llvm.org (Alexander Potapenko via llvm-branch-commits) Date: Thu, 30 Apr 2020 06:03:58 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] eea0313 - [AddressSanitizer] Split out memory intrinsic handling Message-ID: <5eaaccbe.1c69fb81.a3fbc.6634@mx.google.com> Author: Jann Horn Date: 2020-04-30T15:00:48+02:00 New Revision: eea0313cd52e43cc48665ba989b6d861c6e35232 URL: https://github.com/llvm/llvm-project/commit/eea0313cd52e43cc48665ba989b6d861c6e35232 DIFF: https://github.com/llvm/llvm-project/commit/eea0313cd52e43cc48665ba989b6d861c6e35232.diff LOG: [AddressSanitizer] Split out memory intrinsic handling Summary: In both AddressSanitizer and HWAddressSanitizer, we first collect instructions whose operands should be instrumented and memory intrinsics, then instrument them. Both during collection and when inserting instrumentation, they are handled separately. Collect them separately and instrument them separately. This is a bit more straightforward, and prepares for collecting operands instead of instructions in a future patch. This is patch 2/4 of a patch series: https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor ClDebug{Min,Max} handling https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory intrinsic handling https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval call arguments Reviewers: kcc, glider Reviewed By: glider Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77617 Added: Modified: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index d6dedc6f76ab..fcb2b17a7cf5 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -2652,6 +2652,7 @@ bool AddressSanitizer::instrumentFunction(Function &F, // are calls between uses). SmallPtrSet TempsToInstrument; SmallVector ToInstrument; + SmallVector IntrinToInstrument; SmallVector NoReturnCalls; SmallVector AllBlocks; SmallVector PointerComparisonsOrSubtracts; @@ -2688,8 +2689,11 @@ bool AddressSanitizer::instrumentFunction(Function &F, isInterestingPointerSubtraction(&Inst))) { PointerComparisonsOrSubtracts.push_back(&Inst); continue; - } else if (isa(Inst)) { + } else if (MemIntrinsic *MI = dyn_cast(&Inst)) { // ok, take it. + IntrinToInstrument.push_back(MI); + NumInsnsPerBB++; + continue; } else { if (isa(Inst)) NumAllocas++; if (auto *CB = dyn_cast(&Inst)) { @@ -2708,9 +2712,9 @@ bool AddressSanitizer::instrumentFunction(Function &F, } } - bool UseCalls = - (ClInstrumentationWithCallsThreshold >= 0 && - ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold); + bool UseCalls = (ClInstrumentationWithCallsThreshold >= 0 && + ToInstrument.size() + IntrinToInstrument.size() > + (unsigned)ClInstrumentationWithCallsThreshold); const DataLayout &DL = F.getParent()->getDataLayout(); ObjectSizeOpts ObjSizeOpts; ObjSizeOpts.RoundToAlign = true; @@ -2723,9 +2727,11 @@ bool AddressSanitizer::instrumentFunction(Function &F, if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment)) instrumentMop(ObjSizeVis, Inst, UseCalls, F.getParent()->getDataLayout()); - else - instrumentMemIntrinsic(cast(Inst)); } + } + for (auto Inst : IntrinToInstrument) { + if (!suppressInstrumentationSiteForDebug(NumInstrumented)) + instrumentMemIntrinsic(Inst); FunctionModified = true; } diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 9470cb2cfb28..8c9bc428e7f4 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -720,11 +720,6 @@ bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) { uint64_t TypeSize = 0; Value *MaybeMask = nullptr; - if (ClInstrumentMemIntrinsics && isa(I)) { - instrumentMemIntrinsic(cast(I)); - return true; - } - Value *Addr = isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask); @@ -1090,6 +1085,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n"); SmallVector ToInstrument; + SmallVector IntrinToInstrument; SmallVector AllocasToInstrument; SmallVector RetVec; SmallVector LandingPadVec; @@ -1121,8 +1117,11 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { uint64_t TypeSize; Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize, &Alignment, &MaybeMask); - if (Addr || isa(Inst)) + if (Addr) ToInstrument.push_back(&Inst); + + if (MemIntrinsic *MI = dyn_cast(&Inst)) + IntrinToInstrument.push_back(MI); } } @@ -1138,7 +1137,8 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { F.setPersonalityFn(nullptr); } - if (AllocasToInstrument.empty() && ToInstrument.empty()) + if (AllocasToInstrument.empty() && ToInstrument.empty() && + IntrinToInstrument.empty()) return false; assert(!LocalDynamicShadow); @@ -1219,6 +1219,12 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { for (auto Inst : ToInstrument) Changed |= instrumentMemAccess(Inst); + if (ClInstrumentMemIntrinsics && !IntrinToInstrument.empty()) { + for (auto Inst : IntrinToInstrument) + instrumentMemIntrinsic(cast(Inst)); + Changed = true; + } + LocalDynamicShadow = nullptr; StackBaseTag = nullptr; From llvm-branch-commits at lists.llvm.org Thu Apr 30 06:04:00 2020 From: llvm-branch-commits at lists.llvm.org (Alexander Potapenko via llvm-branch-commits) Date: Thu, 30 Apr 2020 06:04:00 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 7df5537 - [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction Message-ID: <5eaaccc0.1c69fb81.6b1b.b2b2@mx.google.com> Author: Jann Horn Date: 2020-04-30T15:00:48+02:00 New Revision: 7df5537f8d3c4f8033b7b32809684cb688fe5ebe URL: https://github.com/llvm/llvm-project/commit/7df5537f8d3c4f8033b7b32809684cb688fe5ebe DIFF: https://github.com/llvm/llvm-project/commit/7df5537f8d3c4f8033b7b32809684cb688fe5ebe.diff LOG: [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction Summary: Refactor getInterestingMemoryOperands() so that information about the pointer operand is returned through an array of structures instead of passing each piece of information separately by-value. This is in preparation for returning information about multiple pointer operands from a single instruction. A side effect is that, instead of repeatedly generating the same information through isInterestingMemoryAccess(), it is now simply collected once and then passed around; that's probably more efficient. HWAddressSanitizer has a bunch of copypasted code from AddressSanitizer, so these changes have to be duplicated. This is patch 3/4 of a patch series: https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor ClDebug{Min,Max} handling https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory intrinsic handling https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval call arguments [glider: renamed llvm::InterestingMemoryOperand::Type to OpType to fix GCC compilation] Reviewers: kcc, glider Reviewed By: glider Subscribers: hiraditya, jfb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77618 Added: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h Modified: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp Removed: ################################################################################ diff --git a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h new file mode 100644 index 000000000000..ef33fa2147d1 --- /dev/null +++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h @@ -0,0 +1,49 @@ +//===--------- Definition of the AddressSanitizer class ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares common infrastructure for AddressSanitizer and +// HWAddressSanitizer. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H +#define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H + +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Module.h" + +namespace llvm { + +class InterestingMemoryOperand { +public: + Use *PtrUse; + bool IsWrite; + Type *OpType; + uint64_t TypeSize; + unsigned Alignment; + // The mask Value, if we're looking at a masked load/store. + Value *MaybeMask; + + InterestingMemoryOperand(Instruction *I, unsigned OperandNo, bool IsWrite, + class Type *OpType, unsigned Alignment, + Value *MaybeMask = nullptr) + : IsWrite(IsWrite), OpType(OpType), Alignment(Alignment), + MaybeMask(MaybeMask) { + const DataLayout &DL = I->getModule()->getDataLayout(); + TypeSize = DL.getTypeStoreSizeInBits(OpType); + PtrUse = &I->getOperandUse(OperandNo); + } + + Instruction *getInsn() { return cast(PtrUse->getUser()); } + + Value *getPtr() { return PtrUse->get(); } +}; + +} // namespace llvm + +#endif diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index fcb2b17a7cf5..6226bcd35381 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -69,6 +69,7 @@ #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h" #include "llvm/Transforms/Utils/ASanStackFrameLayout.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" @@ -612,16 +613,13 @@ struct AddressSanitizer { /// Check if we want (and can) handle this alloca. bool isInterestingAlloca(const AllocaInst &AI); - /// If it is an interesting memory access, return the PointerOperand - /// and set IsWrite/Alignment. Otherwise return nullptr. - /// MaybeMask is an output parameter for the mask Value, if we're looking at a - /// masked load/store. - Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, - uint64_t *TypeSize, unsigned *Alignment, - Value **MaybeMask = nullptr); + bool ignoreAccess(Value *Ptr); + void getInterestingMemoryOperands( + Instruction *I, SmallVectorImpl &Interesting); - void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, Instruction *I, - bool UseCalls, const DataLayout &DL); + void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, + InterestingMemoryOperand &O, bool UseCalls, + const DataLayout &DL); void instrumentPointerComparisonOrSubtraction(Instruction *I); void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore, Value *Addr, uint32_t TypeSize, bool IsWrite, @@ -1340,98 +1338,84 @@ bool AddressSanitizer::isInterestingAlloca(const AllocaInst &AI) { return IsInteresting; } -Value *AddressSanitizer::isInterestingMemoryAccess(Instruction *I, - bool *IsWrite, - uint64_t *TypeSize, - unsigned *Alignment, - Value **MaybeMask) { +bool AddressSanitizer::ignoreAccess(Value *Ptr) { + // Do not instrument acesses from diff erent address spaces; we cannot deal + // with them. + Type *PtrTy = cast(Ptr->getType()->getScalarType()); + if (PtrTy->getPointerAddressSpace() != 0) + return true; + + // Ignore swifterror addresses. + // swifterror memory addresses are mem2reg promoted by instruction + // selection. As such they cannot have regular uses like an instrumentation + // function and it makes no sense to track them as memory. + if (Ptr->isSwiftError()) + return true; + + // Treat memory accesses to promotable allocas as non-interesting since they + // will not cause memory violations. This greatly speeds up the instrumented + // executable at -O0. + if (auto AI = dyn_cast_or_null(Ptr)) + if (ClSkipPromotableAllocas && !isInterestingAlloca(*AI)) + return true; + + return false; +} + +void AddressSanitizer::getInterestingMemoryOperands( + Instruction *I, SmallVectorImpl &Interesting) { // Skip memory accesses inserted by another instrumentation. - if (I->hasMetadata("nosanitize")) return nullptr; + if (I->hasMetadata("nosanitize")) + return; // Do not instrument the load fetching the dynamic shadow address. if (LocalDynamicShadow == I) - return nullptr; + return; - Value *PtrOperand = nullptr; - const DataLayout &DL = I->getModule()->getDataLayout(); if (LoadInst *LI = dyn_cast(I)) { - if (!ClInstrumentReads) return nullptr; - *IsWrite = false; - *TypeSize = DL.getTypeStoreSizeInBits(LI->getType()); - *Alignment = LI->getAlignment(); - PtrOperand = LI->getPointerOperand(); + if (!ClInstrumentReads || ignoreAccess(LI->getPointerOperand())) + return; + Interesting.emplace_back(I, LI->getPointerOperandIndex(), false, + LI->getType(), LI->getAlignment()); } else if (StoreInst *SI = dyn_cast(I)) { - if (!ClInstrumentWrites) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType()); - *Alignment = SI->getAlignment(); - PtrOperand = SI->getPointerOperand(); + if (!ClInstrumentWrites || ignoreAccess(SI->getPointerOperand())) + return; + Interesting.emplace_back(I, SI->getPointerOperandIndex(), true, + SI->getValueOperand()->getType(), + SI->getAlignment()); } else if (AtomicRMWInst *RMW = dyn_cast(I)) { - if (!ClInstrumentAtomics) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType()); - *Alignment = 0; - PtrOperand = RMW->getPointerOperand(); + if (!ClInstrumentAtomics || ignoreAccess(RMW->getPointerOperand())) + return; + Interesting.emplace_back(I, RMW->getPointerOperandIndex(), true, + RMW->getValOperand()->getType(), 0); } else if (AtomicCmpXchgInst *XCHG = dyn_cast(I)) { - if (!ClInstrumentAtomics) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType()); - *Alignment = 0; - PtrOperand = XCHG->getPointerOperand(); + if (!ClInstrumentAtomics || ignoreAccess(XCHG->getPointerOperand())) + return; + Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true, + XCHG->getCompareOperand()->getType(), 0); } else if (auto CI = dyn_cast(I)) { auto *F = CI->getCalledFunction(); if (F && (F->getName().startswith("llvm.masked.load.") || F->getName().startswith("llvm.masked.store."))) { - unsigned OpOffset = 0; - if (F->getName().startswith("llvm.masked.store.")) { - if (!ClInstrumentWrites) - return nullptr; - // Masked store has an initial operand for the value. - OpOffset = 1; - *IsWrite = true; - } else { - if (!ClInstrumentReads) - return nullptr; - *IsWrite = false; - } - - auto BasePtr = CI->getOperand(0 + OpOffset); + bool IsWrite = F->getName().startswith("llvm.masked.store."); + // Masked store has an initial operand for the value. + unsigned OpOffset = IsWrite ? 1 : 0; + if (IsWrite ? !ClInstrumentWrites : !ClInstrumentReads) + return; + + auto BasePtr = CI->getOperand(OpOffset); + if (ignoreAccess(BasePtr)) + return; auto Ty = cast(BasePtr->getType())->getElementType(); - *TypeSize = DL.getTypeStoreSizeInBits(Ty); + unsigned Alignment = 1; + // Otherwise no alignment guarantees. We probably got Undef. if (auto AlignmentConstant = dyn_cast(CI->getOperand(1 + OpOffset))) - *Alignment = (unsigned)AlignmentConstant->getZExtValue(); - else - *Alignment = 1; // No alignment guarantees. We probably got Undef - if (MaybeMask) - *MaybeMask = CI->getOperand(2 + OpOffset); - PtrOperand = BasePtr; + Alignment = (unsigned)AlignmentConstant->getZExtValue(); + Value *Mask = CI->getOperand(2 + OpOffset); + Interesting.emplace_back(I, OpOffset, IsWrite, Ty, Alignment, Mask); } } - - if (PtrOperand) { - // Do not instrument acesses from diff erent address spaces; we cannot deal - // with them. - Type *PtrTy = cast(PtrOperand->getType()->getScalarType()); - if (PtrTy->getPointerAddressSpace() != 0) - return nullptr; - - // Ignore swifterror addresses. - // swifterror memory addresses are mem2reg promoted by instruction - // selection. As such they cannot have regular uses like an instrumentation - // function and it makes no sense to track them as memory. - if (PtrOperand->isSwiftError()) - return nullptr; - } - - // Treat memory accesses to promotable allocas as non-interesting since they - // will not cause memory violations. This greatly speeds up the instrumented - // executable at -O0. - if (ClSkipPromotableAllocas) - if (auto AI = dyn_cast_or_null(PtrOperand)) - return isInterestingAlloca(*AI) ? AI : nullptr; - - return PtrOperand; } static bool isPointerOperand(Value *V) { @@ -1546,15 +1530,9 @@ static void instrumentMaskedLoadOrStore(AddressSanitizer *Pass, } void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, - Instruction *I, bool UseCalls, + InterestingMemoryOperand &O, bool UseCalls, const DataLayout &DL) { - bool IsWrite = false; - unsigned Alignment = 0; - uint64_t TypeSize = 0; - Value *MaybeMask = nullptr; - Value *Addr = - isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask); - assert(Addr); + Value *Addr = O.getPtr(); // Optimization experiments. // The experiments can be used to evaluate potential optimizations that remove @@ -1574,7 +1552,7 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, // dynamically initialized global is always valid. GlobalVariable *G = dyn_cast(GetUnderlyingObject(Addr, DL)); if (G && (!ClInitializers || GlobalIsLinkerInitialized(G)) && - isSafeAccess(ObjSizeVis, Addr, TypeSize)) { + isSafeAccess(ObjSizeVis, Addr, O.TypeSize)) { NumOptimizedAccessesToGlobalVar++; return; } @@ -1583,25 +1561,26 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, if (ClOpt && ClOptStack) { // A direct inbounds access to a stack variable is always valid. if (isa(GetUnderlyingObject(Addr, DL)) && - isSafeAccess(ObjSizeVis, Addr, TypeSize)) { + isSafeAccess(ObjSizeVis, Addr, O.TypeSize)) { NumOptimizedAccessesToStackVar++; return; } } - if (IsWrite) + if (O.IsWrite) NumInstrumentedWrites++; else NumInstrumentedReads++; unsigned Granularity = 1 << Mapping.Scale; - if (MaybeMask) { - instrumentMaskedLoadOrStore(this, DL, IntptrTy, MaybeMask, I, Addr, - Alignment, Granularity, TypeSize, IsWrite, - nullptr, UseCalls, Exp); + if (O.MaybeMask) { + instrumentMaskedLoadOrStore(this, DL, IntptrTy, O.MaybeMask, O.getInsn(), + Addr, O.Alignment, Granularity, O.TypeSize, + O.IsWrite, nullptr, UseCalls, Exp); } else { - doInstrumentAddress(this, I, I, Addr, Alignment, Granularity, TypeSize, - IsWrite, nullptr, UseCalls, Exp); + doInstrumentAddress(this, O.getInsn(), O.getInsn(), Addr, O.Alignment, + Granularity, O.TypeSize, O.IsWrite, nullptr, UseCalls, + Exp); } } @@ -2651,15 +2630,12 @@ bool AddressSanitizer::instrumentFunction(Function &F, // We want to instrument every address only once per basic block (unless there // are calls between uses). SmallPtrSet TempsToInstrument; - SmallVector ToInstrument; + SmallVector OperandsToInstrument; SmallVector IntrinToInstrument; SmallVector NoReturnCalls; SmallVector AllBlocks; SmallVector PointerComparisonsOrSubtracts; int NumAllocas = 0; - bool IsWrite; - unsigned Alignment; - uint64_t TypeSize; // Fill the set of memory operations to instrument. for (auto &BB : F) { @@ -2668,32 +2644,36 @@ bool AddressSanitizer::instrumentFunction(Function &F, int NumInsnsPerBB = 0; for (auto &Inst : BB) { if (LooksLikeCodeInBug11395(&Inst)) return false; - Value *MaybeMask = nullptr; - if (Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize, - &Alignment, &MaybeMask)) { - if (ClOpt && ClOptSameTemp) { - // If we have a mask, skip instrumentation if we've already - // instrumented the full object. But don't add to TempsToInstrument - // because we might get another load/store with a diff erent mask. - if (MaybeMask) { - if (TempsToInstrument.count(Addr)) - continue; // We've seen this (whole) temp in the current BB. - } else { - if (!TempsToInstrument.insert(Addr).second) - continue; // We've seen this temp in the current BB. + SmallVector InterestingOperands; + getInterestingMemoryOperands(&Inst, InterestingOperands); + + if (!InterestingOperands.empty()) { + for (auto &Operand : InterestingOperands) { + if (ClOpt && ClOptSameTemp) { + Value *Ptr = Operand.getPtr(); + // If we have a mask, skip instrumentation if we've already + // instrumented the full object. But don't add to TempsToInstrument + // because we might get another load/store with a diff erent mask. + if (Operand.MaybeMask) { + if (TempsToInstrument.count(Ptr)) + continue; // We've seen this (whole) temp in the current BB. + } else { + if (!TempsToInstrument.insert(Ptr).second) + continue; // We've seen this temp in the current BB. + } } + OperandsToInstrument.push_back(Operand); + NumInsnsPerBB++; } } else if (((ClInvalidPointerPairs || ClInvalidPointerCmp) && isInterestingPointerComparison(&Inst)) || ((ClInvalidPointerPairs || ClInvalidPointerSub) && isInterestingPointerSubtraction(&Inst))) { PointerComparisonsOrSubtracts.push_back(&Inst); - continue; } else if (MemIntrinsic *MI = dyn_cast(&Inst)) { // ok, take it. IntrinToInstrument.push_back(MI); NumInsnsPerBB++; - continue; } else { if (isa(Inst)) NumAllocas++; if (auto *CB = dyn_cast(&Inst)) { @@ -2704,16 +2684,13 @@ bool AddressSanitizer::instrumentFunction(Function &F, } if (CallInst *CI = dyn_cast(&Inst)) maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI); - continue; } - ToInstrument.push_back(&Inst); - NumInsnsPerBB++; if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB) break; } } bool UseCalls = (ClInstrumentationWithCallsThreshold >= 0 && - ToInstrument.size() + IntrinToInstrument.size() > + OperandsToInstrument.size() + IntrinToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold); const DataLayout &DL = F.getParent()->getDataLayout(); ObjectSizeOpts ObjSizeOpts; @@ -2722,12 +2699,11 @@ bool AddressSanitizer::instrumentFunction(Function &F, // Instrument. int NumInstrumented = 0; - for (auto Inst : ToInstrument) { - if (!suppressInstrumentationSiteForDebug(NumInstrumented)) { - if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment)) - instrumentMop(ObjSizeVis, Inst, UseCalls, - F.getParent()->getDataLayout()); - } + for (auto &Operand : OperandsToInstrument) { + if (!suppressInstrumentationSiteForDebug(NumInstrumented)) + instrumentMop(ObjSizeVis, Operand, UseCalls, + F.getParent()->getDataLayout()); + FunctionModified = true; } for (auto Inst : IntrinToInstrument) { if (!suppressInstrumentationSiteForDebug(NumInstrumented)) diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 8c9bc428e7f4..982c1d3516cc 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -45,6 +45,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" @@ -211,10 +212,10 @@ class HWAddressSanitizer { unsigned AccessSizeIndex, Instruction *InsertBefore); void instrumentMemIntrinsic(MemIntrinsic *MI); - bool instrumentMemAccess(Instruction *I); - Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, - uint64_t *TypeSize, unsigned *Alignment, - Value **MaybeMask); + bool instrumentMemAccess(InterestingMemoryOperand &O); + bool ignoreAccess(Value *Ptr); + void getInterestingMemoryOperands( + Instruction *I, SmallVectorImpl &Interesting); bool isInterestingAlloca(const AllocaInst &AI); bool tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag, size_t Size); @@ -500,62 +501,55 @@ Value *HWAddressSanitizer::getDynamicShadowNonTls(IRBuilder<> &IRB) { } } -Value *HWAddressSanitizer::isInterestingMemoryAccess(Instruction *I, - bool *IsWrite, - uint64_t *TypeSize, - unsigned *Alignment, - Value **MaybeMask) { +bool HWAddressSanitizer::ignoreAccess(Value *Ptr) { + // Do not instrument acesses from diff erent address spaces; we cannot deal + // with them. + Type *PtrTy = cast(Ptr->getType()->getScalarType()); + if (PtrTy->getPointerAddressSpace() != 0) + return true; + + // Ignore swifterror addresses. + // swifterror memory addresses are mem2reg promoted by instruction + // selection. As such they cannot have regular uses like an instrumentation + // function and it makes no sense to track them as memory. + if (Ptr->isSwiftError()) + return true; + + return false; +} + +void HWAddressSanitizer::getInterestingMemoryOperands( + Instruction *I, SmallVectorImpl &Interesting) { // Skip memory accesses inserted by another instrumentation. - if (I->hasMetadata("nosanitize")) return nullptr; + if (I->hasMetadata("nosanitize")) + return; // Do not instrument the load fetching the dynamic shadow address. if (LocalDynamicShadow == I) - return nullptr; + return; - Value *PtrOperand = nullptr; - const DataLayout &DL = I->getModule()->getDataLayout(); if (LoadInst *LI = dyn_cast(I)) { - if (!ClInstrumentReads) return nullptr; - *IsWrite = false; - *TypeSize = DL.getTypeStoreSizeInBits(LI->getType()); - *Alignment = LI->getAlignment(); - PtrOperand = LI->getPointerOperand(); + if (!ClInstrumentReads || ignoreAccess(LI->getPointerOperand())) + return; + Interesting.emplace_back(I, LI->getPointerOperandIndex(), false, + LI->getType(), LI->getAlignment()); } else if (StoreInst *SI = dyn_cast(I)) { - if (!ClInstrumentWrites) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType()); - *Alignment = SI->getAlignment(); - PtrOperand = SI->getPointerOperand(); + if (!ClInstrumentWrites || ignoreAccess(SI->getPointerOperand())) + return; + Interesting.emplace_back(I, SI->getPointerOperandIndex(), true, + SI->getValueOperand()->getType(), + SI->getAlignment()); } else if (AtomicRMWInst *RMW = dyn_cast(I)) { - if (!ClInstrumentAtomics) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType()); - *Alignment = 0; - PtrOperand = RMW->getPointerOperand(); + if (!ClInstrumentAtomics || ignoreAccess(RMW->getPointerOperand())) + return; + Interesting.emplace_back(I, RMW->getPointerOperandIndex(), true, + RMW->getValOperand()->getType(), 0); } else if (AtomicCmpXchgInst *XCHG = dyn_cast(I)) { - if (!ClInstrumentAtomics) return nullptr; - *IsWrite = true; - *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType()); - *Alignment = 0; - PtrOperand = XCHG->getPointerOperand(); - } - - if (PtrOperand) { - // Do not instrument accesses from diff erent address spaces; we cannot deal - // with them. - Type *PtrTy = cast(PtrOperand->getType()->getScalarType()); - if (PtrTy->getPointerAddressSpace() != 0) - return nullptr; - - // Ignore swifterror addresses. - // swifterror memory addresses are mem2reg promoted by instruction - // selection. As such they cannot have regular uses like an instrumentation - // function and it makes no sense to track them as memory. - if (PtrOperand->isSwiftError()) - return nullptr; + if (!ClInstrumentAtomics || ignoreAccess(XCHG->getPointerOperand())) + return; + Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true, + XCHG->getCompareOperand()->getType(), 0); } - - return PtrOperand; } static unsigned getPointerOperandIndex(Instruction *I) { @@ -713,40 +707,32 @@ void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { MI->eraseFromParent(); } -bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) { - LLVM_DEBUG(dbgs() << "Instrumenting: " << *I << "\n"); - bool IsWrite = false; - unsigned Alignment = 0; - uint64_t TypeSize = 0; - Value *MaybeMask = nullptr; +bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) { + Value *Addr = O.getPtr(); - Value *Addr = - isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask); + LLVM_DEBUG(dbgs() << "Instrumenting: " << O.getInsn() << "\n"); - if (!Addr) - return false; - - if (MaybeMask) + if (O.MaybeMask) return false; //FIXME - IRBuilder<> IRB(I); - if (isPowerOf2_64(TypeSize) && - (TypeSize / 8 <= (1UL << (kNumberOfAccessSizes - 1))) && - (Alignment >= (1UL << Mapping.Scale) || Alignment == 0 || - Alignment >= TypeSize / 8)) { - size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); + IRBuilder<> IRB(O.getInsn()); + if (isPowerOf2_64(O.TypeSize) && + (O.TypeSize / 8 <= (1UL << (kNumberOfAccessSizes - 1))) && + (O.Alignment >= (1UL << Mapping.Scale) || O.Alignment == 0 || + O.Alignment >= O.TypeSize / 8)) { + size_t AccessSizeIndex = TypeSizeToSizeIndex(O.TypeSize); if (ClInstrumentWithCalls) { - IRB.CreateCall(HwasanMemoryAccessCallback[IsWrite][AccessSizeIndex], + IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex], IRB.CreatePointerCast(Addr, IntptrTy)); } else { - instrumentMemAccessInline(Addr, IsWrite, AccessSizeIndex, I); + instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn()); } } else { - IRB.CreateCall(HwasanMemoryAccessCallbackSized[IsWrite], + IRB.CreateCall(HwasanMemoryAccessCallbackSized[O.IsWrite], {IRB.CreatePointerCast(Addr, IntptrTy), - ConstantInt::get(IntptrTy, TypeSize / 8)}); + ConstantInt::get(IntptrTy, O.TypeSize / 8)}); } - untagPointerOperand(I, Addr); + untagPointerOperand(O.getInsn(), Addr); return true; } @@ -1084,7 +1070,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n"); - SmallVector ToInstrument; + SmallVector OperandsToInstrument; SmallVector IntrinToInstrument; SmallVector AllocasToInstrument; SmallVector RetVec; @@ -1111,14 +1097,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { if (InstrumentLandingPads && isa(Inst)) LandingPadVec.push_back(&Inst); - Value *MaybeMask = nullptr; - bool IsWrite; - unsigned Alignment; - uint64_t TypeSize; - Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize, - &Alignment, &MaybeMask); - if (Addr) - ToInstrument.push_back(&Inst); + getInterestingMemoryOperands(&Inst, OperandsToInstrument); if (MemIntrinsic *MI = dyn_cast(&Inst)) IntrinToInstrument.push_back(MI); @@ -1137,7 +1116,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { F.setPersonalityFn(nullptr); } - if (AllocasToInstrument.empty() && ToInstrument.empty() && + if (AllocasToInstrument.empty() && OperandsToInstrument.empty() && IntrinToInstrument.empty()) return false; @@ -1216,8 +1195,8 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) { } } - for (auto Inst : ToInstrument) - Changed |= instrumentMemAccess(Inst); + for (auto &Operand : OperandsToInstrument) + Changed |= instrumentMemAccess(Operand); if (ClInstrumentMemIntrinsics && !IntrinToInstrument.empty()) { for (auto Inst : IntrinToInstrument) From llvm-branch-commits at lists.llvm.org Thu Apr 30 06:04:02 2020 From: llvm-branch-commits at lists.llvm.org (Alexander Potapenko via llvm-branch-commits) Date: Thu, 30 Apr 2020 06:04:02 -0700 (PDT) Subject: [llvm-branch-commits] [llvm] 84d341f - [AddressSanitizer] Instrument byval call arguments Message-ID: <5eaaccc2.1c69fb81.c3868.cdc4@mx.google.com> Author: Jann Horn Date: 2020-04-30T15:00:49+02:00 New Revision: 84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae URL: https://github.com/llvm/llvm-project/commit/84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae DIFF: https://github.com/llvm/llvm-project/commit/84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae.diff LOG: [AddressSanitizer] Instrument byval call arguments Summary: In the LLVM IR, "call" instructions read memory for each byval operand. For example: ``` $ cat blah.c struct foo { void *a, *b, *c; }; struct bar { struct foo foo; }; void func1(const struct foo); void func2(struct bar *bar) { func1(bar->foo); } $ [...]/bin/clang -S -flto -c blah.c -O2 ; cat blah.s [...] define dso_local void @func2(%struct.bar* %bar) local_unnamed_addr #0 { entry: %foo = getelementptr inbounds %struct.bar, %struct.bar* %bar, i64 0, i32 0 tail call void @func1(%struct.foo* byval(%struct.foo) align 8 %foo) #2 ret void } [...] $ [...]/bin/clang -S -c blah.c -O2 ; cat blah.s [...] func2: # @func2 [...] subq $24, %rsp [...] movq 16(%rdi), %rax movq %rax, 16(%rsp) movups (%rdi), %xmm0 movups %xmm0, (%rsp) callq func1 addq $24, %rsp [...] retq ``` Let ASAN instrument these hidden memory accesses. This is patch 4/4 of a patch series: https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor ClDebug{Min,Max} handling https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory intrinsic handling https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval call arguments Reviewers: kcc, glider Reviewed By: glider Subscribers: hiraditya, dexonsmith, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77619 Added: llvm/test/Instrumentation/AddressSanitizer/byval-args.ll Modified: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 6226bcd35381..93326c8fd13a 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -213,6 +213,11 @@ static cl::opt ClInstrumentAtomics( cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true)); +static cl::opt + ClInstrumentByval("asan-instrument-byval", + cl::desc("instrument byval call arguments"), cl::Hidden, + cl::init(true)); + static cl::opt ClAlwaysSlowPath( "asan-always-slow-path", cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, @@ -1414,6 +1419,14 @@ void AddressSanitizer::getInterestingMemoryOperands( Alignment = (unsigned)AlignmentConstant->getZExtValue(); Value *Mask = CI->getOperand(2 + OpOffset); Interesting.emplace_back(I, OpOffset, IsWrite, Ty, Alignment, Mask); + } else { + for (unsigned ArgNo = 0; ArgNo < CI->getNumArgOperands(); ArgNo++) { + if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) || + ignoreAccess(CI->getArgOperand(ArgNo))) + continue; + Type *Ty = CI->getParamByValType(ArgNo); + Interesting.emplace_back(I, ArgNo, false, Ty, 1); + } } } } diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 982c1d3516cc..0b9856b5126a 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -97,6 +97,10 @@ static cl::opt ClInstrumentAtomics( cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true)); +static cl::opt ClInstrumentByval("hwasan-instrument-byval", + cl::desc("instrument byval arguments"), + cl::Hidden, cl::init(true)); + static cl::opt ClRecover( "hwasan-recover", cl::desc("Enable recovery mode (continue-after-error)."), @@ -549,6 +553,14 @@ void HWAddressSanitizer::getInterestingMemoryOperands( return; Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true, XCHG->getCompareOperand()->getType(), 0); + } else if (auto CI = dyn_cast(I)) { + for (unsigned ArgNo = 0; ArgNo < CI->getNumArgOperands(); ArgNo++) { + if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) || + ignoreAccess(CI->getArgOperand(ArgNo))) + continue; + Type *Ty = CI->getParamByValType(ArgNo); + Interesting.emplace_back(I, ArgNo, false, Ty, 1); + } } } diff --git a/llvm/test/Instrumentation/AddressSanitizer/byval-args.ll b/llvm/test/Instrumentation/AddressSanitizer/byval-args.ll new file mode 100644 index 000000000000..a070cedca37d --- /dev/null +++ b/llvm/test/Instrumentation/AddressSanitizer/byval-args.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -asan -S | FileCheck %s +; Test that for call instructions, the by-value arguments are instrumented. + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.bar = type { %struct.foo } +%struct.foo = type { i8*, i8*, i8* } +define dso_local void @func2(%struct.foo* %foo) sanitize_address { +; CHECK-LABEL: @func2 + tail call void @func1(%struct.foo* byval(%struct.foo) align 8 %foo) #2 +; CHECK: call void @__asan_report_load + ret void +; CHECK: ret void +} +declare dso_local void @func1(%struct.foo* byval(%struct.foo) align 8) + +!0 = !{i32 1, !"wchar_size", i32 4} From llvm-branch-commits at lists.llvm.org Thu Apr 30 07:25:02 2020 From: llvm-branch-commits at lists.llvm.org (Tom Stellard via llvm-branch-commits) Date: Thu, 30 Apr 2020 07:25:02 -0700 (PDT) Subject: [llvm-branch-commits] [libclc] 9c5a83e - libclc: cmake configure should depend on file list Message-ID: <5eaadfbe.1c69fb81.a029.0513@mx.google.com> Author: Jan Vesely Date: 2020-04-30T07:22:54-07:00 New Revision: 9c5a83ed9bff0d3c1b854e6a6deed0f6e7d64ff4 URL: https://github.com/llvm/llvm-project/commit/9c5a83ed9bff0d3c1b854e6a6deed0f6e7d64ff4 DIFF: https://github.com/llvm/llvm-project/commit/9c5a83ed9bff0d3c1b854e6a6deed0f6e7d64ff4.diff LOG: libclc: cmake configure should depend on file list This makes sure targets are rebuilt if a file is added or removed. Reviewer: tstellar Differential Revision: https://reviews.llvm.org/D74662 (cherry picked from commit 814fb658ca262f5c2df47f11d47f91fac188e0d6) Added: Modified: libclc/CMakeLists.txt Removed: ################################################################################ diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index ca65cf930562..a7a1e537cbf7 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -2,6 +2,16 @@ cmake_minimum_required( VERSION 3.9.2 ) project( libclc VERSION 0.2.0 LANGUAGES CXX ) include( GNUInstallDirs ) +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + amdgcn-amdhsa/lib/SOURCES; + amdgcn/lib/SOURCES; + amdgcn-mesa3d/lib/SOURCES; + amdgpu/lib/SOURCES; + generic/lib/SOURCES; + ptx/lib/SOURCES; + ptx-nvidiacl/lib/SOURCES; + r600/lib/SOURCES +) # List of all targets set( LIBCLC_TARGETS_ALL