diff options
Diffstat (limited to 'clang/include')
134 files changed, 4367 insertions, 1899 deletions
diff --git a/clang/include/clang/AST/ASTConsumer.h b/clang/include/clang/AST/ASTConsumer.h index 447f259..a1ef187 100644 --- a/clang/include/clang/AST/ASTConsumer.h +++ b/clang/include/clang/AST/ASTConsumer.h @@ -27,6 +27,7 @@ namespace clang { class VarDecl; class FunctionDecl; class ImportDecl; + class OpenACCRoutineDecl; /// ASTConsumer - This is an abstract interface that should be implemented by /// clients that read ASTs. This abstraction layer allows the client to be @@ -116,6 +117,11 @@ public: // variable has been instantiated. virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {} + /// Callback to handle the end-of-translation unit attachment of OpenACC + /// routine declaration information. + virtual void HandleOpenACCRoutineReference(const FunctionDecl *FD, + const OpenACCRoutineDecl *RD) {} + /// Callback involved at the end of a translation unit to /// notify the consumer that a vtable for the given C++ class is /// required. diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 33aa2d3..f64e29b 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -488,6 +488,10 @@ class ASTContext : public RefCountedBase<ASTContext> { /// Declaration for the CUDA cudaConfigureCall function. FunctionDecl *cudaConfigureCallDecl = nullptr; + /// Declaration for the CUDA cudaGetParameterBuffer function. + FunctionDecl *cudaGetParameterBufferDecl = nullptr; + /// Declaration for the CUDA cudaLaunchDevice function. + FunctionDecl *cudaLaunchDeviceDecl = nullptr; /// Keeps track of all declaration attributes. /// @@ -1641,6 +1645,18 @@ public: return cudaConfigureCallDecl; } + void setcudaGetParameterBufferDecl(FunctionDecl *FD) { + cudaGetParameterBufferDecl = FD; + } + + FunctionDecl *getcudaGetParameterBufferDecl() { + return cudaGetParameterBufferDecl; + } + + void setcudaLaunchDeviceDecl(FunctionDecl *FD) { cudaLaunchDeviceDecl = FD; } + + FunctionDecl *getcudaLaunchDeviceDecl() { return cudaLaunchDeviceDecl; } + /// Returns true iff we need copy/dispose helpers for the given type. bool BlockRequiresCopying(QualType Ty, const VarDecl *D); diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h index 4a0ca45..39d1429 100644 --- a/clang/include/clang/AST/ASTImporter.h +++ b/clang/include/clang/AST/ASTImporter.h @@ -190,6 +190,16 @@ class TypeSourceInfo; llvm::SmallDenseMap<Decl *, int, 32> Aux; }; + class FunctionDeclImportCycleDetector { + public: + auto makeScopedCycleDetection(const FunctionDecl *D); + + bool isCycle(const FunctionDecl *D) const; + + private: + llvm::DenseSet<const FunctionDecl *> FunctionDeclsWithImportInProgress; + }; + private: std::shared_ptr<ASTImporterSharedState> SharedState = nullptr; @@ -254,6 +264,12 @@ class TypeSourceInfo; /// Declaration (from, to) pairs that are known not to be equivalent /// (which we have already complained about). NonEquivalentDeclSet NonEquivalentDecls; + /// A FunctionDecl can have properties that have a reference to the + /// function itself and are imported before the function is created. This + /// can come for example from auto return type or when template parameters + /// are used in the return type or parameters. This member is used to detect + /// cyclic import of FunctionDecl objects to avoid infinite recursion. + FunctionDeclImportCycleDetector FindFunctionDeclImportCycle; using FoundDeclsTy = SmallVector<NamedDecl *, 2>; FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name); diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 14d7caa..e36184f 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -233,44 +233,19 @@ public: } }; -class HLSLSemanticAttr : public HLSLAnnotationAttr { - unsigned SemanticIndex = 0; - LLVM_PREFERRED_TYPE(bool) - unsigned SemanticIndexable : 1; - LLVM_PREFERRED_TYPE(bool) - unsigned SemanticExplicitIndex : 1; - - Decl *TargetDecl = nullptr; - +class HLSLSemanticBaseAttr : public HLSLAnnotationAttr { protected: - HLSLSemanticAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, - attr::Kind AK, bool IsLateParsed, - bool InheritEvenIfAlreadyPresent, bool SemanticIndexable) + HLSLSemanticBaseAttr(ASTContext &Context, + const AttributeCommonInfo &CommonInfo, attr::Kind AK, + bool IsLateParsed, bool InheritEvenIfAlreadyPresent) : HLSLAnnotationAttr(Context, CommonInfo, AK, IsLateParsed, - InheritEvenIfAlreadyPresent) { - this->SemanticIndexable = SemanticIndexable; - this->SemanticExplicitIndex = false; - } + InheritEvenIfAlreadyPresent) {} public: - bool isSemanticIndexable() const { return SemanticIndexable; } - - void setSemanticIndex(unsigned SemanticIndex) { - this->SemanticIndex = SemanticIndex; - this->SemanticExplicitIndex = true; - } - - unsigned getSemanticIndex() const { return SemanticIndex; } - - bool isSemanticIndexExplicit() const { return SemanticExplicitIndex; } - - void setTargetDecl(Decl *D) { TargetDecl = D; } - Decl *getTargetDecl() const { return TargetDecl; } - // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { - return A->getKind() >= attr::FirstHLSLSemanticAttr && - A->getKind() <= attr::LastHLSLSemanticAttr; + return A->getKind() >= attr::FirstHLSLSemanticBaseAttr && + A->getKind() <= attr::LastHLSLSemanticBaseAttr; } }; diff --git a/clang/include/clang/AST/CXXInheritance.h b/clang/include/clang/AST/CXXInheritance.h index e8932608..72d365b 100644 --- a/clang/include/clang/AST/CXXInheritance.h +++ b/clang/include/clang/AST/CXXInheritance.h @@ -192,7 +192,7 @@ public: /// Determine whether the path from the most-derived type to the /// given base type is ambiguous (i.e., it refers to multiple subobjects of /// the same base type). - bool isAmbiguous(CanQualType BaseType); + bool isAmbiguous(CanQualType BaseType) const; /// Whether we are finding multiple paths to detect ambiguities. bool isFindingAmbiguities() const { return FindAmbiguities; } diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 406d79e..2e8ceff 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -2335,7 +2335,7 @@ public: } void setDefaultedOrDeletedInfo(DefaultedOrDeletedFunctionInfo *Info); - DefaultedOrDeletedFunctionInfo *getDefalutedOrDeletedInfo() const; + DefaultedOrDeletedFunctionInfo *getDefaultedOrDeletedInfo() const; /// Whether this function is variadic. bool isVariadic() const; @@ -4040,6 +4040,11 @@ class EnumDecl : public TagDecl { /// and can be accessed with the provided accessors. unsigned ODRHash; + /// Source range covering the enum key: + /// - 'enum' (unscoped) + /// - 'enum class|struct' (scoped) + SourceRange EnumKeyRange; + EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, bool Scoped, bool ScopedUsingClassTag, bool Fixed); @@ -4077,6 +4082,10 @@ public: /// Microsoft-style enumeration with a fixed underlying type. void setFixed(bool Fixed = true) { EnumDeclBits.IsFixed = Fixed; } + SourceRange getEnumKeyRange() const { return EnumKeyRange; } + + void setEnumKeyRange(SourceRange Range) { EnumKeyRange = Range; } + private: /// True if a valid hash is stored in ODRHash. bool hasODRHash() const { return EnumDeclBits.HasODRHash; } @@ -4524,6 +4533,11 @@ public: return field_begin() == field_end(); } + /// Returns the number of fields (non-static data members) in this record. + unsigned getNumFields() const { + return std::distance(field_begin(), field_end()); + } + /// noload_fields - Iterate over the fields stored in this record /// that are currently loaded; don't attempt to retrieve anything /// from an external source. diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index c6326a8..5519787 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -2642,7 +2642,7 @@ public: using udir_iterator_base = llvm::iterator_adaptor_base<udir_iterator, lookup_iterator, - typename lookup_iterator::iterator_category, + lookup_iterator::iterator_category, UsingDirectiveDecl *>; struct udir_iterator : udir_iterator_base { diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index d78c7b6..9435ab0 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -978,8 +978,7 @@ public: } const_child_range children() const { - auto Children = const_cast<MSPropertyRefExpr *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<MSPropertyRefExpr *>(this)->children(); } static bool classof(const Stmt *T) { @@ -1741,8 +1740,7 @@ public: } const_child_range children() const { - auto Children = const_cast<CXXConstructExpr *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<CXXConstructExpr *>(this)->children(); } }; diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h index b923230..8070618 100644 --- a/clang/include/clang/AST/ExprObjC.h +++ b/clang/include/clang/AST/ExprObjC.h @@ -247,8 +247,7 @@ public: } const_child_range children() const { - auto Children = const_cast<ObjCArrayLiteral *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<ObjCArrayLiteral *>(this)->children(); } static bool classof(const Stmt *T) { @@ -394,8 +393,7 @@ public: } const_child_range children() const { - auto Children = const_cast<ObjCDictionaryLiteral *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<ObjCDictionaryLiteral *>(this)->children(); } static bool classof(const Stmt *T) { @@ -790,8 +788,7 @@ public: } const_child_range children() const { - auto Children = const_cast<ObjCPropertyRefExpr *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<ObjCPropertyRefExpr *>(this)->children(); } static bool classof(const Stmt *T) { diff --git a/clang/include/clang/AST/IgnoreExpr.h b/clang/include/clang/AST/IgnoreExpr.h index 917bada..bf098f3 100644 --- a/clang/include/clang/AST/IgnoreExpr.h +++ b/clang/include/clang/AST/IgnoreExpr.h @@ -17,16 +17,6 @@ #include "clang/AST/ExprCXX.h" namespace clang { -namespace detail { -/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, -/// Return Fn_n(...(Fn_1(E))) -inline Expr *IgnoreExprNodesImpl(Expr *E) { return E; } -template <typename FnTy, typename... FnTys> -Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) { - return IgnoreExprNodesImpl(std::forward<FnTy>(Fn)(E), - std::forward<FnTys>(Fns)...); -} -} // namespace detail /// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, /// Recursively apply each of the functions to E until reaching a fixed point. @@ -35,7 +25,7 @@ template <typename... FnTys> Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) { Expr *LastE = nullptr; while (E != LastE) { LastE = E; - E = detail::IgnoreExprNodesImpl(E, std::forward<FnTys>(Fns)...); + ((E = std::forward<FnTys>(Fns)(E)), ...); } return E; } diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h index 427a9c5..cc165dc 100644 --- a/clang/include/clang/AST/JSONNodeDumper.h +++ b/clang/include/clang/AST/JSONNodeDumper.h @@ -149,7 +149,7 @@ class JSONNodeDumper void writeIncludeStack(PresumedLoc Loc, bool JustFirst = false); // Writes the attributes of a SourceLocation object without. - void writeBareSourceLocation(SourceLocation Loc, bool IsSpelling); + void writeBareSourceLocation(SourceLocation Loc); // Writes the attributes of a SourceLocation to JSON based on its presumed // spelling location. If the given location represents a macro invocation, @@ -315,6 +315,7 @@ public: void VisitRequiresExpr(const RequiresExpr *RE); void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node); void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node); + void VisitLambdaExpr(const LambdaExpr *LE); void VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE); void VisitObjCMessageExpr(const ObjCMessageExpr *OME); diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h index 83f2b18..0b4226d 100644 --- a/clang/include/clang/AST/OpenACCClause.h +++ b/clang/include/clang/AST/OpenACCClause.h @@ -51,8 +51,7 @@ public: child_range children(); const_child_range children() const { - auto Children = const_cast<OpenACCClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OpenACCClause *>(this)->children(); } virtual ~OpenACCClause() = default; @@ -474,8 +473,7 @@ public: } const_child_range children() const { - child_range Children = const_cast<OpenACCSelfClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OpenACCSelfClause *>(this)->children(); } static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc, @@ -523,9 +521,7 @@ public: } const_child_range children() const { - child_range Children = - const_cast<OpenACCClauseWithExprs *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OpenACCClauseWithExprs *>(this)->children(); } }; diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 4f50748..d9c3cf2 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -91,8 +91,7 @@ public: child_range children(); const_child_range children() const { - auto Children = const_cast<OMPClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPClause *>(this)->children(); } /// Get the iterator range for the expressions used in the clauses. Used @@ -100,8 +99,7 @@ public: /// runtime before entering the construct. child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPClause *>(this)->children(); } static bool classof(const OMPClause *) { return true; } @@ -315,12 +313,8 @@ public: unsigned varlist_size() const { return NumVars; } bool varlist_empty() const { return NumVars == 0; } - varlist_range varlist() { - return varlist_range(varlist_begin(), varlist_end()); - } - varlist_const_range varlist() const { - return varlist_const_range(varlist_begin(), varlist_end()); - } + varlist_range varlist() { return getVarRefs(); } + varlist_const_range varlist() const { return getVarRefs(); } varlist_iterator varlist_begin() { return getVarRefs().begin(); } varlist_iterator varlist_end() { return getVarRefs().end(); } @@ -650,8 +644,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPAllocateClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPAllocateClause *>(this)->children(); } child_range used_children() { @@ -758,8 +751,7 @@ public: child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPIfClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPIfClause *>(this)->used_children(); } static bool classof(const OMPClause *T) { @@ -808,8 +800,7 @@ public: child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPFinalClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPFinalClause *>(this)->used_children(); } }; /// This represents 'num_threads' clause in the '#pragma omp ...' @@ -2256,8 +2247,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPScheduleClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPScheduleClause *>(this)->children(); } child_range used_children() { @@ -2426,8 +2416,7 @@ public: child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPNowaitClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPNowaitClause *>(this)->used_children(); } static bool classof(const OMPClause *T) { @@ -3411,14 +3400,10 @@ public: using private_copies_const_range = llvm::iterator_range<private_copies_const_iterator>; - private_copies_range private_copies() { - return private_copies_range(getPrivateCopies().begin(), - getPrivateCopies().end()); - } + private_copies_range private_copies() { return getPrivateCopies(); } private_copies_const_range private_copies() const { - return private_copies_const_range(getPrivateCopies().begin(), - getPrivateCopies().end()); + return getPrivateCopies(); } child_range children() { @@ -3427,8 +3412,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPPrivateClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPPrivateClause *>(this)->children(); } child_range used_children() { @@ -3539,13 +3523,9 @@ public: using private_copies_const_range = llvm::iterator_range<private_copies_const_iterator>; - private_copies_range private_copies() { - return private_copies_range(getPrivateCopies().begin(), - getPrivateCopies().end()); - } + private_copies_range private_copies() { return getPrivateCopies(); } private_copies_const_range private_copies() const { - return private_copies_const_range(getPrivateCopies().begin(), - getPrivateCopies().end()); + return getPrivateCopies(); } using inits_iterator = MutableArrayRef<Expr *>::iterator; @@ -3553,12 +3533,8 @@ public: using inits_range = llvm::iterator_range<inits_iterator>; using inits_const_range = llvm::iterator_range<inits_const_iterator>; - inits_range inits() { - return inits_range(getInits().begin(), getInits().end()); - } - inits_const_range inits() const { - return inits_const_range(getInits().begin(), getInits().end()); - } + inits_range inits() { return getInits(); } + inits_const_range inits() const { return getInits(); } child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), @@ -3566,8 +3542,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPFirstprivateClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPFirstprivateClause *>(this)->children(); } child_range used_children() { @@ -3575,8 +3550,7 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } const_child_range used_children() const { - auto Children = const_cast<OMPFirstprivateClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPFirstprivateClause *>(this)->used_children(); } static bool classof(const OMPClause *T) { @@ -3762,44 +3736,23 @@ public: /// copies of original lastprivate variables. void setPrivateCopies(ArrayRef<Expr *> PrivateCopies); - helper_expr_const_range private_copies() const { - return helper_expr_const_range(getPrivateCopies().begin(), - getPrivateCopies().end()); - } + helper_expr_const_range private_copies() const { return getPrivateCopies(); } - helper_expr_range private_copies() { - return helper_expr_range(getPrivateCopies().begin(), - getPrivateCopies().end()); - } + helper_expr_range private_copies() { return getPrivateCopies(); } - helper_expr_const_range source_exprs() const { - return helper_expr_const_range(getSourceExprs().begin(), - getSourceExprs().end()); - } + helper_expr_const_range source_exprs() const { return getSourceExprs(); } - helper_expr_range source_exprs() { - return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end()); - } + helper_expr_range source_exprs() { return getSourceExprs(); } helper_expr_const_range destination_exprs() const { - return helper_expr_const_range(getDestinationExprs().begin(), - getDestinationExprs().end()); + return getDestinationExprs(); } - helper_expr_range destination_exprs() { - return helper_expr_range(getDestinationExprs().begin(), - getDestinationExprs().end()); - } + helper_expr_range destination_exprs() { return getDestinationExprs(); } - helper_expr_const_range assignment_ops() const { - return helper_expr_const_range(getAssignmentOps().begin(), - getAssignmentOps().end()); - } + helper_expr_const_range assignment_ops() const { return getAssignmentOps(); } - helper_expr_range assignment_ops() { - return helper_expr_range(getAssignmentOps().begin(), - getAssignmentOps().end()); - } + helper_expr_range assignment_ops() { return getAssignmentOps(); } child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), @@ -3807,8 +3760,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPLastprivateClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPLastprivateClause *>(this)->children(); } child_range used_children() { @@ -3879,8 +3831,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPSharedClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPSharedClause *>(this)->children(); } child_range used_children() { @@ -4190,79 +4141,45 @@ public: using helper_flag_const_range = llvm::iterator_range<helper_flag_const_iterator>; - helper_expr_const_range privates() const { - return helper_expr_const_range(getPrivates().begin(), getPrivates().end()); - } + helper_expr_const_range privates() const { return getPrivates(); } - helper_expr_range privates() { - return helper_expr_range(getPrivates().begin(), getPrivates().end()); - } + helper_expr_range privates() { return getPrivates(); } - helper_expr_const_range lhs_exprs() const { - return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end()); - } + helper_expr_const_range lhs_exprs() const { return getLHSExprs(); } - helper_expr_range lhs_exprs() { - return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end()); - } + helper_expr_range lhs_exprs() { return getLHSExprs(); } - helper_expr_const_range rhs_exprs() const { - return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end()); - } + helper_expr_const_range rhs_exprs() const { return getRHSExprs(); } - helper_expr_range rhs_exprs() { - return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end()); - } + helper_expr_range rhs_exprs() { return getRHSExprs(); } helper_flag_const_range private_var_reduction_flags() const { - return helper_flag_const_range(getPrivateVariableReductionFlags().begin(), - getPrivateVariableReductionFlags().end()); + return getPrivateVariableReductionFlags(); } helper_flag_range private_var_reduction_flags() { - return helper_flag_range(getPrivateVariableReductionFlags().begin(), - getPrivateVariableReductionFlags().end()); + return getPrivateVariableReductionFlags(); } - helper_expr_const_range reduction_ops() const { - return helper_expr_const_range(getReductionOps().begin(), - getReductionOps().end()); - } + helper_expr_const_range reduction_ops() const { return getReductionOps(); } - helper_expr_range reduction_ops() { - return helper_expr_range(getReductionOps().begin(), - getReductionOps().end()); - } + helper_expr_range reduction_ops() { return getReductionOps(); } - helper_expr_const_range copy_ops() const { - return helper_expr_const_range(getInscanCopyOps().begin(), - getInscanCopyOps().end()); - } + helper_expr_const_range copy_ops() const { return getInscanCopyOps(); } - helper_expr_range copy_ops() { - return helper_expr_range(getInscanCopyOps().begin(), - getInscanCopyOps().end()); - } + helper_expr_range copy_ops() { return getInscanCopyOps(); } helper_expr_const_range copy_array_temps() const { - return helper_expr_const_range(getInscanCopyArrayTemps().begin(), - getInscanCopyArrayTemps().end()); + return getInscanCopyArrayTemps(); } - helper_expr_range copy_array_temps() { - return helper_expr_range(getInscanCopyArrayTemps().begin(), - getInscanCopyArrayTemps().end()); - } + helper_expr_range copy_array_temps() { return getInscanCopyArrayTemps(); } helper_expr_const_range copy_array_elems() const { - return helper_expr_const_range(getInscanCopyArrayElems().begin(), - getInscanCopyArrayElems().end()); + return getInscanCopyArrayElems(); } - helper_expr_range copy_array_elems() { - return helper_expr_range(getInscanCopyArrayElems().begin(), - getInscanCopyArrayElems().end()); - } + helper_expr_range copy_array_elems() { return getInscanCopyArrayElems(); } child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), @@ -4270,8 +4187,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPReductionClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPReductionClause *>(this)->children(); } child_range used_children() { @@ -4279,8 +4195,7 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } const_child_range used_children() const { - auto Children = const_cast<OMPReductionClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPReductionClause *>(this)->used_children(); } static bool classof(const OMPClause *T) { @@ -4464,39 +4379,21 @@ public: using helper_expr_const_range = llvm::iterator_range<helper_expr_const_iterator>; - helper_expr_const_range privates() const { - return helper_expr_const_range(getPrivates().begin(), getPrivates().end()); - } + helper_expr_const_range privates() const { return getPrivates(); } - helper_expr_range privates() { - return helper_expr_range(getPrivates().begin(), getPrivates().end()); - } + helper_expr_range privates() { return getPrivates(); } - helper_expr_const_range lhs_exprs() const { - return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end()); - } + helper_expr_const_range lhs_exprs() const { return getLHSExprs(); } - helper_expr_range lhs_exprs() { - return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end()); - } + helper_expr_range lhs_exprs() { return getLHSExprs(); } - helper_expr_const_range rhs_exprs() const { - return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end()); - } + helper_expr_const_range rhs_exprs() const { return getRHSExprs(); } - helper_expr_range rhs_exprs() { - return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end()); - } + helper_expr_range rhs_exprs() { return getRHSExprs(); } - helper_expr_const_range reduction_ops() const { - return helper_expr_const_range(getReductionOps().begin(), - getReductionOps().end()); - } + helper_expr_const_range reduction_ops() const { return getReductionOps(); } - helper_expr_range reduction_ops() { - return helper_expr_range(getReductionOps().begin(), - getReductionOps().end()); - } + helper_expr_range reduction_ops() { return getReductionOps(); } child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), @@ -4504,8 +4401,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPTaskReductionClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPTaskReductionClause *>(this)->children(); } child_range used_children() { @@ -4709,48 +4605,28 @@ public: using helper_expr_const_range = llvm::iterator_range<helper_expr_const_iterator>; - helper_expr_const_range privates() const { - return helper_expr_const_range(getPrivates().begin(), getPrivates().end()); - } + helper_expr_const_range privates() const { return getPrivates(); } - helper_expr_range privates() { - return helper_expr_range(getPrivates().begin(), getPrivates().end()); - } + helper_expr_range privates() { return getPrivates(); } - helper_expr_const_range lhs_exprs() const { - return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end()); - } + helper_expr_const_range lhs_exprs() const { return getLHSExprs(); } - helper_expr_range lhs_exprs() { - return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end()); - } + helper_expr_range lhs_exprs() { return getLHSExprs(); } - helper_expr_const_range rhs_exprs() const { - return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end()); - } + helper_expr_const_range rhs_exprs() const { return getRHSExprs(); } - helper_expr_range rhs_exprs() { - return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end()); - } + helper_expr_range rhs_exprs() { return getRHSExprs(); } - helper_expr_const_range reduction_ops() const { - return helper_expr_const_range(getReductionOps().begin(), - getReductionOps().end()); - } + helper_expr_const_range reduction_ops() const { return getReductionOps(); } - helper_expr_range reduction_ops() { - return helper_expr_range(getReductionOps().begin(), - getReductionOps().end()); - } + helper_expr_range reduction_ops() { return getReductionOps(); } helper_expr_const_range taskgroup_descriptors() const { - return helper_expr_const_range(getTaskgroupDescriptors().begin(), - getTaskgroupDescriptors().end()); + return getTaskgroupDescriptors(); } helper_expr_range taskgroup_descriptors() { - return helper_expr_range(getTaskgroupDescriptors().begin(), - getTaskgroupDescriptors().end()); + return getTaskgroupDescriptors(); } child_range children() { @@ -4759,8 +4635,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPInReductionClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPInReductionClause *>(this)->children(); } child_range used_children() { @@ -4981,52 +4856,36 @@ public: using privates_range = llvm::iterator_range<privates_iterator>; using privates_const_range = llvm::iterator_range<privates_const_iterator>; - privates_range privates() { - return privates_range(getPrivates().begin(), getPrivates().end()); - } + privates_range privates() { return getPrivates(); } - privates_const_range privates() const { - return privates_const_range(getPrivates().begin(), getPrivates().end()); - } + privates_const_range privates() const { return getPrivates(); } using inits_iterator = MutableArrayRef<Expr *>::iterator; using inits_const_iterator = ArrayRef<const Expr *>::iterator; using inits_range = llvm::iterator_range<inits_iterator>; using inits_const_range = llvm::iterator_range<inits_const_iterator>; - inits_range inits() { - return inits_range(getInits().begin(), getInits().end()); - } + inits_range inits() { return getInits(); } - inits_const_range inits() const { - return inits_const_range(getInits().begin(), getInits().end()); - } + inits_const_range inits() const { return getInits(); } using updates_iterator = MutableArrayRef<Expr *>::iterator; using updates_const_iterator = ArrayRef<const Expr *>::iterator; using updates_range = llvm::iterator_range<updates_iterator>; using updates_const_range = llvm::iterator_range<updates_const_iterator>; - updates_range updates() { - return updates_range(getUpdates().begin(), getUpdates().end()); - } + updates_range updates() { return getUpdates(); } - updates_const_range updates() const { - return updates_const_range(getUpdates().begin(), getUpdates().end()); - } + updates_const_range updates() const { return getUpdates(); } using finals_iterator = MutableArrayRef<Expr *>::iterator; using finals_const_iterator = ArrayRef<const Expr *>::iterator; using finals_range = llvm::iterator_range<finals_iterator>; using finals_const_range = llvm::iterator_range<finals_const_iterator>; - finals_range finals() { - return finals_range(getFinals().begin(), getFinals().end()); - } + finals_range finals() { return getFinals(); } - finals_const_range finals() const { - return finals_const_range(getFinals().begin(), getFinals().end()); - } + finals_const_range finals() const { return getFinals(); } using used_expressions_iterator = MutableArrayRef<Expr *>::iterator; using used_expressions_const_iterator = ArrayRef<const Expr *>::iterator; @@ -5049,15 +4908,13 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPLinearClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPLinearClause *>(this)->children(); } child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPLinearClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPLinearClause *>(this)->used_children(); } static bool classof(const OMPClause *T) { @@ -5148,8 +5005,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPAlignedClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPAlignedClause *>(this)->children(); } child_range used_children() { @@ -5289,34 +5145,19 @@ public: using helper_expr_const_range = llvm::iterator_range<helper_expr_const_iterator>; - helper_expr_const_range source_exprs() const { - return helper_expr_const_range(getSourceExprs().begin(), - getSourceExprs().end()); - } + helper_expr_const_range source_exprs() const { return getSourceExprs(); } - helper_expr_range source_exprs() { - return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end()); - } + helper_expr_range source_exprs() { return getSourceExprs(); } helper_expr_const_range destination_exprs() const { - return helper_expr_const_range(getDestinationExprs().begin(), - getDestinationExprs().end()); + return getDestinationExprs(); } - helper_expr_range destination_exprs() { - return helper_expr_range(getDestinationExprs().begin(), - getDestinationExprs().end()); - } + helper_expr_range destination_exprs() { return getDestinationExprs(); } - helper_expr_const_range assignment_ops() const { - return helper_expr_const_range(getAssignmentOps().begin(), - getAssignmentOps().end()); - } + helper_expr_const_range assignment_ops() const { return getAssignmentOps(); } - helper_expr_range assignment_ops() { - return helper_expr_range(getAssignmentOps().begin(), - getAssignmentOps().end()); - } + helper_expr_range assignment_ops() { return getAssignmentOps(); } child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), @@ -5324,8 +5165,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPCopyinClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPCopyinClause *>(this)->children(); } child_range used_children() { @@ -5453,34 +5293,19 @@ public: using helper_expr_const_range = llvm::iterator_range<helper_expr_const_iterator>; - helper_expr_const_range source_exprs() const { - return helper_expr_const_range(getSourceExprs().begin(), - getSourceExprs().end()); - } + helper_expr_const_range source_exprs() const { return getSourceExprs(); } - helper_expr_range source_exprs() { - return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end()); - } + helper_expr_range source_exprs() { return getSourceExprs(); } helper_expr_const_range destination_exprs() const { - return helper_expr_const_range(getDestinationExprs().begin(), - getDestinationExprs().end()); + return getDestinationExprs(); } - helper_expr_range destination_exprs() { - return helper_expr_range(getDestinationExprs().begin(), - getDestinationExprs().end()); - } + helper_expr_range destination_exprs() { return getDestinationExprs(); } - helper_expr_const_range assignment_ops() const { - return helper_expr_const_range(getAssignmentOps().begin(), - getAssignmentOps().end()); - } + helper_expr_const_range assignment_ops() const { return getAssignmentOps(); } - helper_expr_range assignment_ops() { - return helper_expr_range(getAssignmentOps().begin(), - getAssignmentOps().end()); - } + helper_expr_range assignment_ops() { return getAssignmentOps(); } child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), @@ -5488,8 +5313,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPCopyprivateClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPCopyprivateClause *>(this)->children(); } child_range used_children() { @@ -5565,8 +5389,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPFlushClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPFlushClause *>(this)->children(); } child_range used_children() { @@ -5652,8 +5475,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPDepobjClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPDepobjClause *>(this)->children(); } child_range used_children() { @@ -5806,8 +5628,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPDependClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPDependClause *>(this)->children(); } child_range used_children() { @@ -6656,18 +6477,14 @@ public: using const_all_decls_iterator = ArrayRef<ValueDecl *>::iterator; using const_all_decls_range = llvm::iterator_range<const_all_decls_iterator>; - const_all_decls_range all_decls() const { - auto A = getUniqueDeclsRef(); - return const_all_decls_range(A.begin(), A.end()); - } + const_all_decls_range all_decls() const { return getUniqueDeclsRef(); } using const_all_num_lists_iterator = ArrayRef<unsigned>::iterator; using const_all_num_lists_range = llvm::iterator_range<const_all_num_lists_iterator>; const_all_num_lists_range all_num_lists() const { - auto A = getDeclNumListsRef(); - return const_all_num_lists_range(A.begin(), A.end()); + return getDeclNumListsRef(); } using const_all_lists_sizes_iterator = ArrayRef<unsigned>::iterator; @@ -6675,8 +6492,7 @@ public: llvm::iterator_range<const_all_lists_sizes_iterator>; const_all_lists_sizes_range all_lists_sizes() const { - auto A = getComponentListSizesRef(); - return const_all_lists_sizes_range(A.begin(), A.end()); + return getComponentListSizesRef(); } using const_all_components_iterator = ArrayRef<MappableComponent>::iterator; @@ -6684,8 +6500,7 @@ public: llvm::iterator_range<const_all_components_iterator>; const_all_components_range all_components() const { - auto A = getComponentsRef(); - return const_all_components_range(A.begin(), A.end()); + return getComponentsRef(); } using mapperlist_iterator = MutableArrayRef<Expr *>::iterator; @@ -6954,8 +6769,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPMapClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPMapClause *>(this)->children(); } child_range used_children() { @@ -6965,8 +6779,7 @@ public: return child_range(child_iterator(), child_iterator()); } const_child_range used_children() const { - auto Children = const_cast<OMPMapClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPMapClause *>(this)->used_children(); } @@ -7052,8 +6865,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPNumTeamsClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPNumTeamsClause *>(this)->children(); } child_range used_children() { @@ -7146,8 +6958,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPThreadLimitClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPThreadLimitClause *>(this)->children(); } child_range used_children() { @@ -7227,8 +7038,7 @@ public: child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPPriorityClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPPriorityClause *>(this)->used_children(); } static bool classof(const OMPClause *T) { @@ -7319,8 +7129,7 @@ public: child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPGrainsizeClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPGrainsizeClause *>(this)->used_children(); } static bool classof(const OMPClause *T) { @@ -7451,8 +7260,7 @@ public: child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPNumTasksClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPNumTasksClause *>(this)->used_children(); } static bool classof(const OMPClause *T) { @@ -7626,8 +7434,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPDistScheduleClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPDistScheduleClause *>(this)->children(); } child_range used_children() { @@ -7775,7 +7582,8 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>, /// Motion-modifiers for the 'to' clause. OpenMPMotionModifierKind MotionModifiers[NumberOfOMPMotionModifiers] = { - OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown}; + OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown, + OMPC_MOTION_MODIFIER_unknown}; /// Location of motion-modifiers for the 'to' clause. SourceLocation MotionModifiersLoc[NumberOfOMPMotionModifiers]; @@ -7847,6 +7655,9 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>, MotionModifiersLoc[I] = TLoc; } + void setIteratorModifier(Expr *IteratorModifier) { + getTrailingObjects<Expr *>()[2 * varlist_size()] = IteratorModifier; + } /// Set colon location. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } @@ -7855,7 +7666,7 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>, size_t numTrailingObjects(OverloadToken<Expr *>) const { // There are varlist_size() of expressions, and varlist_size() of // user-defined mappers. - return 2 * varlist_size(); + return 2 * varlist_size() + 1; } size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { return getUniqueDeclarationsNum(); @@ -7881,15 +7692,14 @@ public: /// \param UDMQualifierLoc C++ nested name specifier for the associated /// user-defined mapper. /// \param MapperId The identifier of associated user-defined mapper. - static OMPToClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs, - ArrayRef<Expr *> Vars, - ArrayRef<ValueDecl *> Declarations, - MappableExprComponentListsRef ComponentLists, - ArrayRef<Expr *> UDMapperRefs, - ArrayRef<OpenMPMotionModifierKind> MotionModifiers, - ArrayRef<SourceLocation> MotionModifiersLoc, - NestedNameSpecifierLoc UDMQualifierLoc, - DeclarationNameInfo MapperId); + static OMPToClause * + Create(const ASTContext &C, const OMPVarListLocTy &Locs, + ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists, + ArrayRef<Expr *> UDMapperRefs, Expr *IteratorModifier, + ArrayRef<OpenMPMotionModifierKind> MotionModifiers, + ArrayRef<SourceLocation> MotionModifiersLoc, + NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId); /// Creates an empty clause with the place for \a NumVars variables. /// @@ -7910,7 +7720,9 @@ public: "Requested modifier exceeds the total number of modifiers."); return MotionModifiers[Cnt]; } - + Expr *getIteratorModifier() const { + return getTrailingObjects<Expr *>()[2 * varlist_size()]; + } /// Fetches the motion-modifier location at 'Cnt' index of array of modifiers' /// locations. /// @@ -7940,8 +7752,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPToClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPToClause *>(this)->children(); } child_range used_children() { @@ -7976,7 +7787,8 @@ class OMPFromClause final /// Motion-modifiers for the 'from' clause. OpenMPMotionModifierKind MotionModifiers[NumberOfOMPMotionModifiers] = { - OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown}; + OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown, + OMPC_MOTION_MODIFIER_unknown}; /// Location of motion-modifiers for the 'from' clause. SourceLocation MotionModifiersLoc[NumberOfOMPMotionModifiers]; @@ -8037,7 +7849,9 @@ class OMPFromClause final "Unexpected index to store motion modifier, exceeds array size."); MotionModifiers[I] = T; } - + void setIteratorModifier(Expr *IteratorModifier) { + getTrailingObjects<Expr *>()[2 * varlist_size()] = IteratorModifier; + } /// Set location for the motion-modifier. /// /// \param I index for motion-modifier location. @@ -8056,7 +7870,7 @@ class OMPFromClause final size_t numTrailingObjects(OverloadToken<Expr *>) const { // There are varlist_size() of expressions, and varlist_size() of // user-defined mappers. - return 2 * varlist_size(); + return 2 * varlist_size() + 1; } size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { return getUniqueDeclarationsNum(); @@ -8086,7 +7900,7 @@ public: Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, - ArrayRef<Expr *> UDMapperRefs, + ArrayRef<Expr *> UDMapperRefs, Expr *IteratorExpr, ArrayRef<OpenMPMotionModifierKind> MotionModifiers, ArrayRef<SourceLocation> MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId); @@ -8110,7 +7924,9 @@ public: "Requested modifier exceeds the total number of modifiers."); return MotionModifiers[Cnt]; } - + Expr *getIteratorModifier() const { + return getTrailingObjects<Expr *>()[2 * varlist_size()]; + } /// Fetches the motion-modifier location at 'Cnt' index of array of modifiers' /// locations. /// @@ -8140,8 +7956,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPFromClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPFromClause *>(this)->children(); } child_range used_children() { @@ -8275,14 +8090,10 @@ public: using private_copies_const_range = llvm::iterator_range<private_copies_const_iterator>; - private_copies_range private_copies() { - return private_copies_range(getPrivateCopies().begin(), - getPrivateCopies().end()); - } + private_copies_range private_copies() { return getPrivateCopies(); } private_copies_const_range private_copies() const { - return private_copies_const_range(getPrivateCopies().begin(), - getPrivateCopies().end()); + return getPrivateCopies(); } using inits_iterator = MutableArrayRef<Expr *>::iterator; @@ -8290,13 +8101,9 @@ public: using inits_range = llvm::iterator_range<inits_iterator>; using inits_const_range = llvm::iterator_range<inits_const_iterator>; - inits_range inits() { - return inits_range(getInits().begin(), getInits().end()); - } + inits_range inits() { return getInits(); } - inits_const_range inits() const { - return inits_const_range(getInits().begin(), getInits().end()); - } + inits_const_range inits() const { return getInits(); } child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), @@ -8304,8 +8111,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPUseDevicePtrClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPUseDevicePtrClause *>(this)->children(); } child_range used_children() { @@ -8408,8 +8214,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPUseDeviceAddrClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPUseDeviceAddrClause *>(this)->children(); } child_range used_children() { @@ -8511,8 +8316,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPIsDevicePtrClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPIsDevicePtrClause *>(this)->children(); } child_range used_children() { @@ -8615,8 +8419,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPHasDeviceAddrClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPHasDeviceAddrClause *>(this)->children(); } child_range used_children() { @@ -8702,8 +8505,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPNontemporalClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPNontemporalClause *>(this)->children(); } child_range private_refs() { @@ -8712,8 +8514,7 @@ public: } const_child_range private_refs() const { - auto Children = const_cast<OMPNontemporalClause *>(this)->private_refs(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPNontemporalClause *>(this)->private_refs(); } child_range used_children() { @@ -8923,8 +8724,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPInitClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPInitClause *>(this)->children(); } child_range used_children() { @@ -8945,8 +8745,7 @@ public: } const_prefs_range prefs() const { - auto Prefs = const_cast<OMPInitClause *>(this)->prefs(); - return const_prefs_range(Prefs.begin(), Prefs.end()); + return const_prefs_range(const_cast<OMPInitClause *>(this)->prefs()); } static bool classof(const OMPClause *T) { @@ -9156,8 +8955,7 @@ public: child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPNovariantsClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPNovariantsClause *>(this)->used_children(); } }; @@ -9202,8 +9000,7 @@ public: child_range used_children(); const_child_range used_children() const { - auto Children = const_cast<OMPNocontextClause *>(this)->used_children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPNocontextClause *>(this)->used_children(); } }; @@ -9297,8 +9094,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPInclusiveClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPInclusiveClause *>(this)->children(); } child_range used_children() { @@ -9371,8 +9167,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPExclusiveClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPExclusiveClause *>(this)->children(); } child_range used_children() { @@ -9593,8 +9388,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPAffinityClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPAffinityClause *>(this)->children(); } child_range used_children() { @@ -10068,6 +9862,151 @@ public: Expr *getSize() const { return getStmtAs<Expr>(); } }; +/// This represents 'dyn_groupprivate' clause in '#pragma omp target ...' +/// and '#pragma omp teams ...' directives. +/// +/// \code +/// #pragma omp target [...] dyn_groupprivate(a,b: N) +/// \endcode +class OMPDynGroupprivateClause : public OMPClause, public OMPClauseWithPreInit { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// Modifiers for 'dyn_groupprivate' clause. + enum { SIMPLE, FALLBACK, NUM_MODIFIERS }; + unsigned Modifiers[NUM_MODIFIERS]; + + /// Locations of modifiers. + SourceLocation ModifiersLoc[NUM_MODIFIERS]; + + /// The size of the dyn_groupprivate. + Expr *Size = nullptr; + + /// Set the first dyn_groupprivate modifier. + /// + /// \param M The modifier. + void setDynGroupprivateModifier(OpenMPDynGroupprivateClauseModifier M) { + Modifiers[SIMPLE] = M; + } + + /// Set the second dyn_groupprivate modifier. + /// + /// \param M The modifier. + void setDynGroupprivateFallbackModifier( + OpenMPDynGroupprivateClauseFallbackModifier M) { + Modifiers[FALLBACK] = M; + } + + /// Set location of the first dyn_groupprivate modifier. + void setDynGroupprivateModifierLoc(SourceLocation Loc) { + ModifiersLoc[SIMPLE] = Loc; + } + + /// Set location of the second dyn_groupprivate modifier. + void setDynGroupprivateFallbackModifierLoc(SourceLocation Loc) { + ModifiersLoc[FALLBACK] = Loc; + } + + /// Sets the location of '('. + /// + /// \param Loc Location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Set size. + /// + /// \param E Size. + void setSize(Expr *E) { Size = E; } + +public: + /// Build 'dyn_groupprivate' clause with a size expression \a Size. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param Size Size. + /// \param M1 The first modifier applied to 'dyn_groupprivate' clause. + /// \param M1Loc Location of the first modifier. + /// \param M2 The second modifier applied to 'dyn_groupprivate' clause. + /// \param M2Loc Location of the second modifier. + OMPDynGroupprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, Expr *Size, Stmt *HelperSize, + OpenMPDirectiveKind CaptureRegion, + OpenMPDynGroupprivateClauseModifier M1, + SourceLocation M1Loc, + OpenMPDynGroupprivateClauseFallbackModifier M2, + SourceLocation M2Loc) + : OMPClause(llvm::omp::OMPC_dyn_groupprivate, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Size(Size) { + setPreInitStmt(HelperSize, CaptureRegion); + Modifiers[SIMPLE] = M1; + Modifiers[FALLBACK] = M2; + ModifiersLoc[SIMPLE] = M1Loc; + ModifiersLoc[FALLBACK] = M2Loc; + } + + /// Build an empty clause. + explicit OMPDynGroupprivateClause() + : OMPClause(llvm::omp::OMPC_dyn_groupprivate, SourceLocation(), + SourceLocation()), + OMPClauseWithPreInit(this) { + Modifiers[SIMPLE] = OMPC_DYN_GROUPPRIVATE_unknown; + Modifiers[FALLBACK] = OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown; + } + + /// Get the first modifier of the clause. + OpenMPDynGroupprivateClauseModifier getDynGroupprivateModifier() const { + return static_cast<OpenMPDynGroupprivateClauseModifier>(Modifiers[SIMPLE]); + } + + /// Get the second modifier of the clause. + OpenMPDynGroupprivateClauseFallbackModifier + getDynGroupprivateFallbackModifier() const { + return static_cast<OpenMPDynGroupprivateClauseFallbackModifier>( + Modifiers[FALLBACK]); + } + + /// Get location of '('. + SourceLocation getLParenLoc() { return LParenLoc; } + + /// Get the first modifier location. + SourceLocation getDynGroupprivateModifierLoc() const { + return ModifiersLoc[SIMPLE]; + } + + /// Get the second modifier location. + SourceLocation getDynGroupprivateFallbackModifierLoc() const { + return ModifiersLoc[FALLBACK]; + } + + /// Get size. + Expr *getSize() { return Size; } + + /// Get size. + const Expr *getSize() const { return Size; } + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(&Size), + reinterpret_cast<Stmt **>(&Size) + 1); + } + + const_child_range children() const { + return const_cast<OMPDynGroupprivateClause *>(this)->children(); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_dyn_groupprivate; + } +}; + /// This represents the 'doacross' clause for the '#pragma omp ordered' /// directive. /// @@ -10178,8 +10117,7 @@ public: } const_child_range children() const { - auto Children = const_cast<OMPDoacrossClause *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<OMPDoacrossClause *>(this)->children(); } child_range used_children() { diff --git a/clang/include/clang/AST/OperationKinds.def b/clang/include/clang/AST/OperationKinds.def index c2dca89..8a13ad9 100644 --- a/clang/include/clang/AST/OperationKinds.def +++ b/clang/include/clang/AST/OperationKinds.def @@ -364,6 +364,9 @@ CAST_OPERATION(IntToOCLSampler) // Truncate a vector type by dropping elements from the end (HLSL only). CAST_OPERATION(HLSLVectorTruncation) +// Truncate a matrix type by dropping elements from the end (HLSL only). +CAST_OPERATION(HLSLMatrixTruncation) + // Non-decaying array RValue cast (HLSL only). CAST_OPERATION(HLSLArrayRValue) diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h index fd995a6..48105b3 100644 --- a/clang/include/clang/AST/PrettyPrinter.h +++ b/clang/include/clang/AST/PrettyPrinter.h @@ -15,6 +15,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" +#include "llvm/ADT/STLForwardCompat.h" namespace clang { @@ -55,14 +56,15 @@ public: /// This type is intended to be small and suitable for passing by value. /// It is very frequently copied. struct PrintingPolicy { - enum SuppressInlineNamespaceMode : uint8_t { None, Redundant, All }; + enum class SuppressInlineNamespaceMode : uint8_t { None, Redundant, All }; /// Create a default printing policy for the specified language. PrintingPolicy(const LangOptions &LO) : Indentation(2), SuppressSpecifiers(false), SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false), SuppressScope(false), SuppressUnwrittenScope(false), - SuppressInlineNamespace(SuppressInlineNamespaceMode::Redundant), + SuppressInlineNamespace( + llvm::to_underlying(SuppressInlineNamespaceMode::Redundant)), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 8cb0a65..8f42742 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -4166,6 +4166,14 @@ bool RecursiveASTVisitor<Derived>::VisitOMPXDynCGroupMemClause( } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPDynGroupprivateClause( + OMPDynGroupprivateClause *C) { + TRY_TO(VisitOMPClauseWithPreInit(C)); + TRY_TO(TraverseStmt(C->getSize())); + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPDoacrossClause( OMPDoacrossClause *C) { TRY_TO(VisitOMPClauseList(C)); diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 76942f1a..e1cca34 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -1564,8 +1564,7 @@ public: child_range children(); const_child_range children() const { - auto Children = const_cast<Stmt *>(this)->children(); - return const_child_range(Children.begin(), Children.end()); + return const_cast<Stmt *>(this)->children(); } child_iterator child_begin() { return children().begin(); } @@ -1831,26 +1830,6 @@ public: return const_reverse_body_iterator(body_begin()); } - // Get the Stmt that StmtExpr would consider to be the result of this - // compound statement. This is used by StmtExpr to properly emulate the GCC - // compound expression extension, which ignores trailing NullStmts when - // getting the result of the expression. - // i.e. ({ 5;;; }) - // ^^ ignored - // If we don't find something that isn't a NullStmt, just return the last - // Stmt. - Stmt *getStmtExprResult() { - for (auto *B : llvm::reverse(body())) { - if (!isa<NullStmt>(B)) - return B; - } - return body_back(); - } - - const Stmt *getStmtExprResult() const { - return const_cast<CompoundStmt *>(this)->getStmtExprResult(); - } - SourceLocation getBeginLoc() const { return LBraceLoc; } SourceLocation getEndLoc() const { return RBraceLoc; } diff --git a/clang/include/clang/AST/StmtOpenACC.h b/clang/include/clang/AST/StmtOpenACC.h index ae80297..2bd0b52 100644 --- a/clang/include/clang/AST/StmtOpenACC.h +++ b/clang/include/clang/AST/StmtOpenACC.h @@ -818,14 +818,63 @@ public: // A struct to represent a broken-down version of the associated statement, // providing the information specified in OpenACC3.3 Section 2.12. - struct StmtInfo { + struct SingleStmtInfo { + // Holds the entire expression for this. In the case of a normal + // read/write/update, this should just be the associated statement. in the + // case of an update, this is going to be the sub-expression this + // represents. + const Expr *WholeExpr; const Expr *V; const Expr *X; // Listed as 'expr' in the standard, this is typically a generic expression // as a component. const Expr *RefExpr; - // TODO: OpenACC: We should expand this as we're implementing the other - // atomic construct kinds. + // If this is an 'update', records whether this is a post-fix + // increment/decrement. In the case where we have a single-line variant of + // 'capture' we have to form the IR differently if this is the case to make + // sure the old value is 'read' in the 2nd step. + bool IsPostfixIncDec = false; + static SingleStmtInfo Empty() { + return {nullptr, nullptr, nullptr, nullptr, false}; + } + + static SingleStmtInfo createRead(const Expr *WholeExpr, const Expr *V, + const Expr *X) { + return {WholeExpr, V, X, /*RefExpr=*/nullptr}; + } + static SingleStmtInfo createWrite(const Expr *WholeExpr, const Expr *X, + const Expr *RefExpr) { + return {WholeExpr, /*V=*/nullptr, X, RefExpr}; + } + static SingleStmtInfo createUpdate(const Expr *WholeExpr, const Expr *X, + bool PostfixIncDec) { + return {WholeExpr, /*V=*/nullptr, X, /*RefExpr=*/nullptr, PostfixIncDec}; + } + }; + + struct StmtInfo { + enum class StmtForm { + Read, + Write, + Update, + ReadWrite, + ReadUpdate, + UpdateRead + } Form; + SingleStmtInfo First, Second; + + static StmtInfo createUpdateRead(SingleStmtInfo First, + SingleStmtInfo Second) { + return {StmtForm::UpdateRead, First, Second}; + } + static StmtInfo createReadWrite(SingleStmtInfo First, + SingleStmtInfo Second) { + return {StmtForm::ReadWrite, First, Second}; + } + static StmtInfo createReadUpdate(SingleStmtInfo First, + SingleStmtInfo Second) { + return {StmtForm::ReadUpdate, First, Second}; + } }; const StmtInfo getAssociatedStmtInfo() const; diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h index f07861f..30b9efe 100644 --- a/clang/include/clang/AST/TypeBase.h +++ b/clang/include/clang/AST/TypeBase.h @@ -2607,7 +2607,7 @@ public: bool isAnyPointerType() const; // Any C pointer or ObjC object pointer bool isCountAttributedType() const; bool isCFIUncheckedCalleeFunctionType() const; - bool hasPointeeToToCFIUncheckedCalleeFunctionType() const; + bool hasPointeeToCFIUncheckedCalleeFunctionType() const; bool isBlockPointerType() const; bool isVoidPointerType() const; bool isReferenceType() const; @@ -8564,7 +8564,7 @@ inline bool Type::isCFIUncheckedCalleeFunctionType() const { return false; } -inline bool Type::hasPointeeToToCFIUncheckedCalleeFunctionType() const { +inline bool Type::hasPointeeToCFIUncheckedCalleeFunctionType() const { QualType Pointee; if (const auto *PT = getAs<PointerType>()) Pointee = PT->getPointeeType(); diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 98e62de..e3ec2620 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2478,6 +2478,21 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt; /// matches '__asm("mov al, 2")' extern const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt; +/// Matches top level asm declarations. +/// +/// Given +/// \code +/// __asm("nop"); +/// void f() { +/// __asm("mov al, 2"); +/// } +/// \endcode +/// fileScopeAsmDecl() +/// matches '__asm("nop")', +/// but not '__asm("mov al, 2")'. +extern const internal::VariadicDynCastAllOfMatcher<Decl, FileScopeAsmDecl> + fileScopeAsmDecl; + /// Matches bool literals. /// /// Example matches true @@ -6988,6 +7003,19 @@ AST_MATCHER_P(ReferenceTypeLoc, hasReferentLoc, internal::Matcher<TypeLoc>, return ReferentMatcher.matches(Node.getPointeeLoc(), Finder, Builder); } +/// Matches `ArrayTypeLoc`s. +/// +/// Given +/// \code +/// int a[] = {1, 2}; +/// int b[3]; +/// void f() { int c[a[0]]; } +/// \endcode +/// arrayTypeLoc() +/// matches "int a[]", "int b[3]" and "int c[a[0]]". +extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ArrayTypeLoc> + arrayTypeLoc; + /// Matches template specialization `TypeLoc`s. /// /// Given diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h index 6a90aeb..b5f7f87 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h @@ -16,6 +16,7 @@ #include "clang/Analysis/Analyses/LifetimeSafety/Loans.h" #include "clang/Analysis/Analyses/LifetimeSafety/Origins.h" +#include "clang/Analysis/Analyses/LifetimeSafety/Utils.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/CFG.h" #include "llvm/ADT/SmallVector.h" @@ -23,6 +24,9 @@ #include <cstdint> namespace clang::lifetimes::internal { + +using FactID = utils::ID<struct FactTag>; + /// An abstract base class for a single, atomic lifetime-relevant event. class Fact { @@ -38,16 +42,17 @@ public: /// it. Otherwise, the source's loan set is merged into the destination's /// loan set. OriginFlow, - /// An origin escapes the function by flowing into the return value. - ReturnOfOrigin, /// An origin is used (eg. appears as l-value expression like DeclRefExpr). Use, /// A marker for a specific point in the code, for testing. TestPoint, + /// An origin that escapes the function scope (e.g., via return). + OriginEscapes, }; private: Kind K; + FactID ID; protected: Fact(Kind K) : K(K) {} @@ -56,6 +61,9 @@ public: virtual ~Fact() = default; Kind getKind() const { return K; } + void setID(FactID ID) { this->ID = ID; } + FactID getID() const { return ID; } + template <typename T> const T *getAs() const { if (T::classof(this)) return static_cast<const T *>(this); @@ -128,22 +136,26 @@ public: const OriginManager &OM) const override; }; -class ReturnOfOriginFact : public Fact { +class OriginEscapesFact : public Fact { OriginID OID; + const Expr *EscapeExpr; public: static bool classof(const Fact *F) { - return F->getKind() == Kind::ReturnOfOrigin; + return F->getKind() == Kind::OriginEscapes; } - ReturnOfOriginFact(OriginID OID) : Fact(Kind::ReturnOfOrigin), OID(OID) {} - OriginID getReturnedOriginID() const { return OID; } + OriginEscapesFact(OriginID OID, const Expr *EscapeExpr) + : Fact(Kind::OriginEscapes), OID(OID), EscapeExpr(EscapeExpr) {} + OriginID getEscapedOriginID() const { return OID; } + const Expr *getEscapeExpr() const { return EscapeExpr; }; void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM) const override; }; class UseFact : public Fact { const Expr *UseExpr; + OriginID OID; // True if this use is a write operation (e.g., left-hand side of assignment). // Write operations are exempted from use-after-free checks. bool IsWritten = false; @@ -151,12 +163,10 @@ class UseFact : public Fact { public: static bool classof(const Fact *F) { return F->getKind() == Kind::Use; } - UseFact(const Expr *UseExpr) : Fact(Kind::Use), UseExpr(UseExpr) {} + UseFact(const Expr *UseExpr, OriginManager &OM) + : Fact(Kind::Use), UseExpr(UseExpr), OID(OM.get(*UseExpr)) {} - OriginID getUsedOrigin(const OriginManager &OM) const { - // TODO: Remove const cast and make OriginManager::get as const. - return const_cast<OriginManager &>(OM).get(*UseExpr); - } + OriginID getUsedOrigin() const { return OID; } const Expr *getUseExpr() const { return UseExpr; } void markAsWritten() { IsWritten = true; } bool isWritten() const { return IsWritten; } @@ -184,22 +194,26 @@ public: class FactManager { public: + void init(const CFG &Cfg) { + assert(BlockToFacts.empty() && "FactManager already initialized"); + BlockToFacts.resize(Cfg.getNumBlockIDs()); + } + llvm::ArrayRef<const Fact *> getFacts(const CFGBlock *B) const { - auto It = BlockToFactsMap.find(B); - if (It != BlockToFactsMap.end()) - return It->second; - return {}; + return BlockToFacts[B->getBlockID()]; } void addBlockFacts(const CFGBlock *B, llvm::ArrayRef<Fact *> NewFacts) { if (!NewFacts.empty()) - BlockToFactsMap[B].assign(NewFacts.begin(), NewFacts.end()); + BlockToFacts[B->getBlockID()].assign(NewFacts.begin(), NewFacts.end()); } template <typename FactType, typename... Args> FactType *createFact(Args &&...args) { void *Mem = FactAllocator.Allocate<FactType>(); - return new (Mem) FactType(std::forward<Args>(args)...); + FactType *Res = new (Mem) FactType(std::forward<Args>(args)...); + Res->setID(NextFactID++); + return Res; } void dump(const CFG &Cfg, AnalysisDeclContext &AC) const; @@ -214,6 +228,11 @@ public: /// user-defined locations in the code. /// \note This is intended for testing only. llvm::StringMap<ProgramPoint> getTestPoints() const; + /// Retrieves all the facts in the block containing Program Point P. + /// \note This is intended for testing only. + llvm::ArrayRef<const Fact *> getBlockContaining(ProgramPoint P) const; + + unsigned getNumFacts() const { return NextFactID.Value; } LoanManager &getLoanMgr() { return LoanMgr; } const LoanManager &getLoanMgr() const { return LoanMgr; } @@ -221,10 +240,11 @@ public: const OriginManager &getOriginMgr() const { return OriginMgr; } private: + FactID NextFactID{0}; LoanManager LoanMgr; OriginManager OriginMgr; - llvm::DenseMap<const clang::CFGBlock *, llvm::SmallVector<const Fact *>> - BlockToFactsMap; + /// Facts for each CFG block, indexed by block ID. + llvm::SmallVector<llvm::SmallVector<const Fact *>> BlockToFacts; llvm::BumpPtrAllocator FactAllocator; }; } // namespace clang::lifetimes::internal diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h index 5e58abe..a1acd86 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h @@ -43,13 +43,14 @@ public: void VisitUnaryOperator(const UnaryOperator *UO); void VisitReturnStmt(const ReturnStmt *RS); void VisitBinaryOperator(const BinaryOperator *BO); + void VisitConditionalOperator(const ConditionalOperator *CO); void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE); void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *FCE); void VisitInitListExpr(const InitListExpr *ILE); void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *MTE); private: - void handleDestructor(const CFGAutomaticObjDtor &DtorOpt); + void handleLifetimeEnds(const CFGLifetimeEnds &LifetimeEnds); void handleGSLPointerConstruction(const CXXConstructExpr *CCE); @@ -90,9 +91,14 @@ private: void markUseAsWrite(const DeclRefExpr *DRE); + llvm::SmallVector<Fact *> issuePlaceholderLoans(); FactManager &FactMgr; AnalysisDeclContext &AC; llvm::SmallVector<Fact *> CurrentBlockFacts; + // Collect origins that escape the function in this block (OriginEscapesFact), + // appended at the end of CurrentBlockFacts to ensure they appear after + // ExpireFact entries. + llvm::SmallVector<Fact *> EscapesInCurrentBlock; // To distinguish between reads and writes for use-after-free checks, this map // stores the `UseFact` for each `DeclRefExpr`. We initially identify all // `DeclRefExpr`s as "read" uses. When an assignment is processed, the use diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h index f02969e..1a16fb8 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h @@ -38,6 +38,11 @@ bool isAssignmentOperatorLifetimeBound(const CXXMethodDecl *CMD); /// method or because it's a normal assignment operator. bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD); +// Tells whether the type is annotated with [[gsl::Pointer]]. +bool isGslPointerType(QualType QT); +// Tells whether the type is annotated with [[gsl::Owner]]. +bool isGslOwnerType(QualType QT); + } // namespace clang::lifetimes #endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h index 91ffbb1..31fae55 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h @@ -42,6 +42,15 @@ public: virtual void reportUseAfterFree(const Expr *IssueExpr, const Expr *UseExpr, SourceLocation FreeLoc, Confidence Confidence) {} + + virtual void reportUseAfterReturn(const Expr *IssueExpr, + const Expr *EscapeExpr, + SourceLocation ExpiryLoc, + Confidence Confidence) {} + + // Suggests lifetime bound annotations for function paramters + virtual void suggestAnnotation(const ParmVarDecl *PVD, + const Expr *EscapeExpr) {} }; /// The main entry point for the analysis. diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LiveOrigins.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LiveOrigins.h index c4f5f0e..8ad17db 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LiveOrigins.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LiveOrigins.h @@ -31,6 +31,9 @@ namespace clang::lifetimes::internal { +using CausingFactType = + ::llvm::PointerUnion<const UseFact *, const OriginEscapesFact *>; + enum class LivenessKind : uint8_t { Dead, // Not alive Maybe, // Live on some path but not all paths (may-be-live) @@ -43,7 +46,7 @@ struct LivenessInfo { /// multiple uses along different paths, this will point to the use appearing /// earlier in the translation unit. /// This is 'null' when the origin is not live. - const UseFact *CausingUseFact; + CausingFactType CausingFact; /// The kind of liveness of the origin. /// `Must`: The origin is live on all control-flow paths from the current @@ -56,17 +59,16 @@ struct LivenessInfo { /// while `Maybe`-be-alive suggests a potential one on some paths. LivenessKind Kind; - LivenessInfo() : CausingUseFact(nullptr), Kind(LivenessKind::Dead) {} - LivenessInfo(const UseFact *UF, LivenessKind K) - : CausingUseFact(UF), Kind(K) {} + LivenessInfo() : CausingFact(nullptr), Kind(LivenessKind::Dead) {} + LivenessInfo(CausingFactType CF, LivenessKind K) : CausingFact(CF), Kind(K) {} bool operator==(const LivenessInfo &Other) const { - return CausingUseFact == Other.CausingUseFact && Kind == Other.Kind; + return CausingFact == Other.CausingFact && Kind == Other.Kind; } bool operator!=(const LivenessInfo &Other) const { return !(*this == Other); } void Profile(llvm::FoldingSetNodeID &IDBuilder) const { - IDBuilder.AddPointer(CausingUseFact); + IDBuilder.AddPointer(CausingFact.getOpaqueValue()); IDBuilder.Add(Kind); } }; diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Loans.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Loans.h index 7f5cf03..e9bccd4 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Loans.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Loans.h @@ -34,21 +34,81 @@ struct AccessPath { AccessPath(const clang::ValueDecl *D) : D(D) {} }; -/// Information about a single borrow, or "Loan". A loan is created when a -/// reference or pointer is created. -struct Loan { +/// An abstract base class for a single "Loan" which represents lending a +/// storage in memory. +class Loan { /// TODO: Represent opaque loans. /// TODO: Represent nullptr: loans to no path. Accessing it UB! Currently it /// is represented as empty LoanSet - LoanID ID; +public: + enum class Kind : uint8_t { + /// A loan with an access path to a storage location. + Path, + /// A non-expiring placeholder loan for a parameter, representing a borrow + /// from the function's caller. + Placeholder + }; + + Loan(Kind K, LoanID ID) : K(K), ID(ID) {} + virtual ~Loan() = default; + + Kind getKind() const { return K; } + LoanID getID() const { return ID; } + + virtual void dump(llvm::raw_ostream &OS) const = 0; + +private: + const Kind K; + const LoanID ID; +}; + +/// PathLoan represents lending a storage location that is visible within the +/// function's scope (e.g., a local variable on stack). +class PathLoan : public Loan { AccessPath Path; /// The expression that creates the loan, e.g., &x. const Expr *IssueExpr; - Loan(LoanID id, AccessPath path, const Expr *IssueExpr) - : ID(id), Path(path), IssueExpr(IssueExpr) {} +public: + PathLoan(LoanID ID, AccessPath Path, const Expr *IssueExpr) + : Loan(Kind::Path, ID), Path(Path), IssueExpr(IssueExpr) {} + + const AccessPath &getAccessPath() const { return Path; } + const Expr *getIssueExpr() const { return IssueExpr; } - void dump(llvm::raw_ostream &OS) const; + void dump(llvm::raw_ostream &OS) const override; + + static bool classof(const Loan *L) { return L->getKind() == Kind::Path; } +}; + +/// A placeholder loan held by a function parameter, representing a borrow from +/// the caller's scope. +/// +/// Created at function entry for each pointer or reference parameter with an +/// origin. Unlike PathLoan, placeholder loans: +/// - Have no IssueExpr (created at function entry, not at a borrow site) +/// - Have no AccessPath (the borrowed object is not visible to the function) +/// - Do not currently expire, but may in the future when modeling function +/// invalidations (e.g., vector::push_back) +/// +/// When a placeholder loan escapes the function (e.g., via return), it +/// indicates the parameter should be marked [[clang::lifetimebound]], enabling +/// lifetime annotation suggestions. +class PlaceholderLoan : public Loan { + /// The function parameter that holds this placeholder loan. + const ParmVarDecl *PVD; + +public: + PlaceholderLoan(LoanID ID, const ParmVarDecl *PVD) + : Loan(Kind::Placeholder, ID), PVD(PVD) {} + + const ParmVarDecl *getParmVarDecl() const { return PVD; } + + void dump(llvm::raw_ostream &OS) const override; + + static bool classof(const Loan *L) { + return L->getKind() == Kind::Placeholder; + } }; /// Manages the creation, storage and retrieval of loans. @@ -56,16 +116,24 @@ class LoanManager { public: LoanManager() = default; - Loan &addLoan(AccessPath Path, const Expr *IssueExpr) { - AllLoans.emplace_back(getNextLoanID(), Path, IssueExpr); - return AllLoans.back(); + template <typename LoanType, typename... Args> + LoanType *createLoan(Args &&...args) { + static_assert( + std::is_same_v<LoanType, PathLoan> || + std::is_same_v<LoanType, PlaceholderLoan>, + "createLoan can only be used with PathLoan or PlaceholderLoan"); + void *Mem = LoanAllocator.Allocate<LoanType>(); + auto *NewLoan = + new (Mem) LoanType(getNextLoanID(), std::forward<Args>(args)...); + AllLoans.push_back(NewLoan); + return NewLoan; } - const Loan &getLoan(LoanID ID) const { + const Loan *getLoan(LoanID ID) const { assert(ID.Value < AllLoans.size()); return AllLoans[ID.Value]; } - llvm::ArrayRef<Loan> getLoans() const { return AllLoans; } + llvm::ArrayRef<const Loan *> getLoans() const { return AllLoans; } private: LoanID getNextLoanID() { return NextLoanID++; } @@ -73,7 +141,8 @@ private: LoanID NextLoanID{0}; /// TODO(opt): Profile and evaluate the usefullness of small buffer /// optimisation. - llvm::SmallVector<Loan> AllLoans; + llvm::SmallVector<const Loan *> AllLoans; + llvm::BumpPtrAllocator LoanAllocator; }; } // namespace clang::lifetimes::internal diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h index ba138b0..56b9010 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h @@ -74,6 +74,8 @@ public: OriginID getOrCreate(const ValueDecl &D); + unsigned getNumOrigins() const { return NextOriginID.Value; } + void dump(OriginID OID, llvm::raw_ostream &OS) const; private: diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h index a404b06..3e57f30 100644 --- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h +++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h @@ -19,7 +19,6 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/Type.h" #include "clang/Analysis/FlowSensitive/StorageLocation.h" -#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SetVector.h" namespace clang { @@ -145,17 +144,17 @@ struct ReferencedDecls { FieldSet Fields; /// All variables with static storage duration, notably including static /// member variables and static variables declared within a function. - llvm::DenseSet<const VarDecl *> Globals; + llvm::SetVector<const VarDecl *> Globals; /// Local variables, not including parameters or static variables declared /// within a function. - llvm::DenseSet<const VarDecl *> Locals; + llvm::SetVector<const VarDecl *> Locals; /// Free functions and member functions which are referenced (but not /// necessarily called). - llvm::DenseSet<const FunctionDecl *> Functions; + llvm::SetVector<const FunctionDecl *> Functions; /// When analyzing a lambda's call operator, the set of all parameters (from /// the surrounding function) that the lambda captures. Captured local /// variables are already included in `Locals` above. - llvm::DenseSet<const ParmVarDecl *> LambdaCapturedParams; + llvm::SetVector<const ParmVarDecl *> LambdaCapturedParams; }; /// Returns declarations that are declared in or referenced from `FD`. diff --git a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h index 696c9f4..c547d6c 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h +++ b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h @@ -46,6 +46,9 @@ struct UncheckedOptionalAccessModelOptions { /// are confident in this const accessor caching, we shouldn't need the /// IgnoreSmartPointerDereference option anymore. bool IgnoreSmartPointerDereference = false; + + /// In generating diagnostics, ignore calls to `optional::value()`. + bool IgnoreValueCalls = false; }; using UncheckedOptionalAccessLattice = CachedConstAccessorsLattice<NoopLattice>; diff --git a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.h b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.h index 24f8b0b..2d54bd3 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.h +++ b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.h @@ -13,6 +13,7 @@ #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h" +#include "clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h" #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/MatchSwitch.h" @@ -69,7 +70,8 @@ struct UncheckedStatusOrAccessModelOptions {}; // Dataflow analysis that discovers unsafe uses of StatusOr values. class UncheckedStatusOrAccessModel - : public DataflowAnalysis<UncheckedStatusOrAccessModel, NoopLattice> { + : public DataflowAnalysis<UncheckedStatusOrAccessModel, + CachedConstAccessorsLattice<NoopLattice>> { public: explicit UncheckedStatusOrAccessModel(ASTContext &Ctx, Environment &Env); diff --git a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h index 5d9a0f7..8948428 100644 --- a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h +++ b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h @@ -131,7 +131,7 @@ public: << " on StorageLocation " << this << " of type " << getType() << "\n"; llvm::dbgs() << "Existing children:\n"; - for ([[maybe_unused]] auto [Field, Loc] : Children) { + for (const auto &Field : Children.keys()) { llvm::dbgs() << Field->getNameAsString() << "\n"; } } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 749f531..d8d1675 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -508,6 +508,10 @@ def TargetMicrosoftRecordLayout : TargetArch<["x86", "x86_64", "arm", "thumb", let CustomCode = [{ Target.hasMicrosoftRecordLayout() }]; } +def TargetMustTailAvailable: TargetSpec { + let CustomCode = [{ Target.hasMustTail() }]; +} + def TargetELF : TargetSpec { let ObjectFormats = ["ELF"]; } @@ -737,6 +741,17 @@ class Attr { // our existing general parsing we need to have a separate flag that // opts an attribute into strict parsing of attribute parameters bit StrictEnumParameters = 0; + // Set to true for attributes which have Sema checks which requires the type + // to be deduced. + // When `IsTypeDependent` is set to true, you should add an `ActOn*Attr` + // function to `Sema.h`. The signature of the function must be: + // `void ActOn*Attr(Decl *, const Attr *);` where the `Decl *` is the + // declaration the attribute will be attached to; its type will have already + // been deduced, and the `Attr *` is the attribute being applied to that + // declaration. This function should handle all type-sensitive semantics for + // the attribute. This function will be automatically called by + // `Sema::CheckAttributesOnDeducedType()`. + bit IsTypeDependent = 0; // Lists language options, one of which is required to be true for the // attribute to be applicable. If empty, no language options are required. list<LangOpt> LangOpts = []; @@ -779,18 +794,6 @@ class DeclOrStmtAttr : InheritableAttr; /// An attribute class for HLSL Annotations. class HLSLAnnotationAttr : InheritableAttr; -class HLSLSemanticAttr<bit Indexable> : HLSLAnnotationAttr { - bit SemanticIndexable = Indexable; - int SemanticIndex = 0; - bit SemanticExplicitIndex = 0; - - let Spellings = []; - let Subjects = SubjectList<[ParmVar, Field, Function]>; - let LangOpts = [HLSL]; - let Args = [DeclArgument<Named, "Target">, IntArgument<"SemanticIndex">, - BoolArgument<"SemanticExplicitIndex">]; -} - /// A target-specific attribute. This class is meant to be used as a mixin /// with InheritableAttr or Attr depending on the attribute's needs. class TargetSpecificAttr<TargetSpec target> { @@ -1069,7 +1072,7 @@ def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> { } def AsmLabel : InheritableAttr { - let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">]; + let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm">, CustomKeyword<"__asm__">]; let Args = [ // Label specifies the mangled name for the decl. StringArgument<"Label">, ]; @@ -1408,6 +1411,7 @@ def Cleanup : InheritableAttr { let Args = [DeclArgument<Function, "FunctionDecl">]; let Subjects = SubjectList<[LocalVar]>; let Documentation = [CleanupDocs]; + let IsTypeDependent = 1; // FIXME: DeclArgument should be reworked to also store the // Expr instead of adding attr specific hacks like the following. // See the discussion in https://github.com/llvm/llvm-project/pull/14023. @@ -1913,7 +1917,7 @@ def NoMerge : DeclOrStmtAttr { "functions, statements and variables">; } -def MustTail : StmtAttr { +def MustTail : StmtAttr, TargetSpecificAttr<TargetMustTailAvailable> { let Spellings = [Clang<"musttail">]; let Documentation = [MustTailDocs]; let Subjects = SubjectList<[ReturnStmt], ErrorDiag, "return statements">; @@ -2068,6 +2072,12 @@ def Restrict : InheritableAttr { let Documentation = [RestrictDocs]; } +def MallocSpan : InheritableAttr { + let Spellings = [Clang<"malloc_span">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [MallocSpanDocs]; +} + def LayoutVersion : InheritableAttr, TargetSpecificAttr<TargetMicrosoftRecordLayout> { let Spellings = [Declspec<"layout_version">]; let Args = [UnsignedArgument<"Version">]; @@ -5017,24 +5027,28 @@ def HLSLUnparsedSemantic : HLSLAnnotationAttr { let Documentation = [InternalOnly]; } -def HLSLSV_Position : HLSLSemanticAttr</* Indexable= */ 1> { - let Documentation = [HLSLSV_PositionDocs]; -} +class HLSLSemanticBaseAttr : HLSLAnnotationAttr { + int SemanticIndex = 0; -def HLSLSV_GroupThreadID : HLSLSemanticAttr</* Indexable= */ 0> { - let Documentation = [HLSLSV_GroupThreadIDDocs]; -} + let Spellings = []; + let Subjects = SubjectList<[ParmVar, Field, Function]>; + let LangOpts = [HLSL]; -def HLSLSV_GroupID : HLSLSemanticAttr</* Indexable= */ 0> { - let Documentation = [HLSLSV_GroupIDDocs]; + let Args = [StringArgument<"SemanticName">, IntArgument<"SemanticIndex">]; } -def HLSLSV_GroupIndex : HLSLSemanticAttr</* Indexable= */ 0> { - let Documentation = [HLSLSV_GroupIndexDocs]; +def HLSLParsedSemantic : HLSLSemanticBaseAttr { + let Spellings = []; + let Subjects = SubjectList<[ParmVar, Field, Function]>; + let LangOpts = [HLSL]; + let Documentation = [InternalOnly]; } -def HLSLSV_DispatchThreadID : HLSLSemanticAttr</* Indexable= */ 0> { - let Documentation = [HLSLSV_DispatchThreadIDDocs]; +def HLSLAppliedSemantic : HLSLSemanticBaseAttr { + let Spellings = []; + let Subjects = SubjectList<[ParmVar, Field, Function]>; + let LangOpts = [HLSL]; + let Documentation = [InternalOnly]; } def HLSLPackOffset: HLSLAnnotationAttr { @@ -5158,6 +5172,14 @@ def HLSLVkConstantId : InheritableAttr { let Documentation = [VkConstantIdDocs]; } +def HLSLVkLocation : HLSLAnnotationAttr { + let Spellings = [CXX11<"vk", "location">]; + let Args = [IntArgument<"Location">]; + let Subjects = SubjectList<[ParmVar, Field, Function], ErrorDiag>; + let LangOpts = [HLSL]; + let Documentation = [HLSLVkLocationDocs]; +} + def RandomizeLayout : InheritableAttr { let Spellings = [GCC<"randomize_layout">]; let Subjects = SubjectList<[Record]>; @@ -5309,3 +5331,11 @@ def NonString : InheritableAttr { let Subjects = SubjectList<[Var, Field]>; let Documentation = [NonStringDocs]; } + +def ModularFormat : InheritableAttr { + let Spellings = [Clang<"modular_format">]; + let Args = [IdentifierArgument<"ModularImplFn">, StringArgument<"ImplName">, + VariadicStringArgument<"Aspects">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [ModularFormatDocs]; +} diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 2fdd041..ae929c7 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3450,9 +3450,9 @@ Mac, and BSD. This attribute has no effect on other targets. def MSABIDocs : Documentation { let Category = DocCatCallingConvs; let Content = [{ -On non-Windows x86_64 targets, this attribute changes the calling convention of -a function to match the default convention used on Windows x86_64. This -attribute has no effect on Windows targets or non-x86_64 targets. +On non-Windows x86_64 and aarch64 targets, this attribute changes the calling convention of +a function to match the default convention used on Windows. This +attribute has no effect on Windows targets or non-x86_64, non-aarch64 targets. }]; } @@ -4295,17 +4295,17 @@ used by other languages. (This prefix is also added to the standard Itanium C++ ABI prefix on "mangled" symbol names, so that e.g. on such targets the true symbol name for a C++ variable declared as ``int cppvar;`` would be ``__Z6cppvar``; note the two underscores.) This prefix is *not* added to the -symbol names specified by the ``asm`` attribute; programmers wishing to match a -C symbol name must compensate for this. +symbol names specified by the ``__asm`` attribute; programmers wishing to match +a C symbol name must compensate for this. For example, consider the following C code: .. code-block:: c - int var1 asm("altvar") = 1; // "altvar" in symbol table. + int var1 __asm("altvar") = 1; // "altvar" in symbol table. int var2 = 1; // "_var2" in symbol table. - void func1(void) asm("altfunc"); + void func1(void) __asm("altfunc"); void func1(void) {} // "altfunc" in symbol table. void func2(void) {} // "_func2" in symbol table. @@ -5247,6 +5247,23 @@ yet implemented in clang. }]; } +def MallocSpanDocs : Documentation { + let Category = DocCatFunction; + let Heading = "malloc_span"; + let Content = [{ +The ``malloc_span`` attribute can be used to mark that a function which acts +like a system memory allocation function and returns a span-like structure, +where the returned memory range does not alias storage from any other object +accessible to the caller. + +In this context, a span-like structure is assumed to have two non-static data +members, one of which is a pointer to the start of the allocated memory and +the other one is either an integer type containing the size of the actually +allocated memory or a pointer to the end of the allocated region. Note, static +data members do not impact whether a type is span-like or not. + }]; +} + def ReturnsNonNullDocs : Documentation { let Category = NullabilityDocs; let Content = [{ @@ -8672,38 +8689,6 @@ randomized. }]; } -def HLSLSV_GroupThreadIDDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_GroupThreadID`` semantic, when applied to an input parameter, specifies which -individual thread within a thread group is executing in. This attribute is -only supported in compute shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupthreadid - }]; -} - -def HLSLSV_GroupIDDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_GroupID`` semantic, when applied to an input parameter, specifies which -thread group a shader is executing in. This attribute is only supported in compute shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupid - }]; -} - -def HLSLSV_GroupIndexDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_GroupIndex`` semantic, when applied to an input parameter, specifies a -data binding to map the group index to the specified parameter. This attribute -is only supported in compute shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupindex - }]; -} - def HLSLResourceBindingDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -8750,35 +8735,6 @@ The full documentation is available here: https://learn.microsoft.com/en-us/wind }]; } -def HLSLSV_DispatchThreadIDDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_DispatchThreadID`` semantic, when applied to an input parameter, -specifies a data binding to map the global thread offset within the Dispatch -call (per dimension of the group) to the specified parameter. -When applied to a field of a struct, the data binding is specified to the field -when the struct is used as a parameter type. -The semantic on the field is ignored when not used as a parameter. -This attribute is only supported in compute shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-dispatchthreadid - }]; -} - -def HLSLSV_PositionDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_Position`` semantic, when applied to an input parameter in a pixel -shader, contains the location of the pixel center (x, y) in screen space. -This semantic can be applied to the parameter, or a field in a struct used -as an input parameter. -This attribute is supported as an input in pixel, hull, domain and mesh shaders. -This attribute is supported as an output in vertex, geometry and domain shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics - }]; -} - def HLSLGroupSharedAddressSpaceDocs : Documentation { let Category = DocCatVariable; let Content = [{ @@ -9025,6 +8981,18 @@ The descriptor set is optional and defaults to 0 if not provided. }]; } +def HLSLVkLocationDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +Attribute used for specifying the location number for the stage input/output +variables. Allowed on function parameters, function returns, and struct +fields. This parameter has no effect when used outside of an entrypoint +parameter/parameter field/return value. + +This attribute maps to the 'Location' SPIR-V decoration. + }]; +} + def WebAssemblyFuncrefDocs : Documentation { let Category = DocCatType; let Content = [{ @@ -9674,3 +9642,43 @@ silence diagnostics with code like: __attribute__((nonstring)) char NotAStr[3] = "foo"; // Not diagnosed }]; } + +def ModularFormatDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``modular_format`` attribute can be applied to a function that bears the +``format`` attribute (or standard library functions) to indicate that the +implementation is "modular", that is, that the implementation is logically +divided into a number of named aspects. When the compiler can determine that +not all aspects of the implementation are needed for a given call, the compiler +may redirect the call to the identifier given as the first argument to the +attribute (the modular implementation function). + +The second argument is a implementation name, and the remaining arguments are +aspects of the format string for the compiler to report. The implementation +name is an unevaluated identifier be in the C namespace. + +The compiler reports that a call requires an aspect by issuing a relocation for +the symbol ``<impl_name>_<aspect>`` at the point of the call. This arranges for +code and data needed to support the aspect of the implementation to be brought +into the link to satisfy weak references in the modular implemenation function. +If the compiler does not understand an aspect, it must summarily consider any +call to require that aspect. + +For example, say ``printf`` is annotated with +``modular_format(__modular_printf, "__printf", "float")``. Then, a call to +``printf(var, 42)`` would be untouched. A call to ``printf("%d", 42)`` would +become a call to ``__modular_printf`` with the same arguments, as would +``printf("%f", 42.0)``. The latter would be accompanied with a strong +relocation against the symbol ``__printf_float``, which would bring floating +point support for ``printf`` into the link. + +If the attribute appears more than once on a declaration, or across a chain of +redeclarations, it is an error for the attributes to have different arguments, +excepting that the aspects may be in any order. + +The following aspects are currently supported: + +- ``float``: The call has a floating point argument + }]; +} diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h index 3a5e31de..51f0745 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -19,6 +19,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringTable.h" +#include "llvm/TargetParser/Triple.h" #include <cstring> // VC++ defines 'alloca' as an object-like macro, which interferes with our @@ -94,6 +95,12 @@ struct Info { /// /// Must be provided the `Shard` for this `Info` object. std::string getName(const InfosShard &Shard) const; + + // Builtin non-null attribute modes. + // NonOptimizing: attaches Clang's `_Nonnull` type qualifier to parameters. + // Optimizing: emits the classic GNU-style `nonnull` attribute for + // optimization. + enum class NonNullMode { NonOptimizing, Optimizing }; }; /// A constexpr function to construct an infos array from X-macros. @@ -392,6 +399,11 @@ public: bool performsCallback(unsigned ID, llvm::SmallVectorImpl<int> &Encoding) const; + /// Return true if this builtin has parameters that must be non-null. + /// The parameter indices are appended into 'Indxs'. + bool isNonNull(unsigned ID, llvm::SmallVectorImpl<int> &Indxs, + Info::NonNullMode &Mode) const; + /// Return true if this function has no side effects and doesn't /// read memory, except for possibly errno or raising FP exceptions. /// @@ -405,6 +417,22 @@ public: return strchr(getAttributesString(ID), 'g') != nullptr; } + /// Determine whether we can generate LLVM intrinsics for the given + /// builtin ID, based on whether it has side effects such as setting errno. + /// + /// \param BuiltinID The builtin ID to check. + /// \param Trip The target triple. + /// \param ErrnoOverwritten Indicates whether the errno setting behavior + /// has been overwritten via '#pragma float_control(precise, on/off)'. + /// \param MathErrnoEnabled Indicates whether math-errno is enabled on + /// command line. + /// \param HasOptNoneAttr True iff 'attribute__((optnone))' is used. + /// \param IsOptimizationEnabled True iff the optimization level is not 'O0'. + bool shouldGenerateFPMathIntrinsic(unsigned BuiltinID, llvm::Triple Trip, + std::optional<bool> ErrnoOverwritten, + bool MathErrnoEnabled, bool HasOptNoneAttr, + bool IsOptimizationEnabled) const; + const char *getRequiredFeatures(unsigned ID) const; unsigned getRequiredVectorWidth(unsigned ID) const; diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 0275447..98fb2de 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -755,6 +755,12 @@ def BSwap : Builtin, Template<["unsigned short", "uint32_t", "uint64_t"], let Prototype = "T(T)"; } +def BSwapg : Builtin { + let Spellings = ["__builtin_bswapg"]; + let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking]; + let Prototype = "int(...)"; +} + def Bitreverse : BitInt8_16_32_64BuiltinsTemplate, Builtin { let Spellings = ["__builtin_bitreverse"]; let Attributes = [NoThrow, Const, Constexpr]; @@ -1418,6 +1424,12 @@ def ElementwiseExp10 : Builtin { let Prototype = "void(...)"; } +def ElementwiseLdexp : Builtin { + let Spellings = ["__builtin_elementwise_ldexp"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + def ElementwiseFloor : Builtin { let Spellings = ["__builtin_elementwise_floor"]; let Attributes = [NoThrow, Const, CustomTypeChecking]; @@ -2278,6 +2290,18 @@ def ScopedAtomicMaxFetch : AtomicBuiltin { let Prototype = "void(...)"; } +def ScopedAtomicUIncWrap : AtomicBuiltin { + let Spellings = ["__scoped_atomic_uinc_wrap"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicUDecWrap : AtomicBuiltin { + let Spellings = ["__scoped_atomic_udec_wrap"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + // OpenCL 2.0 atomic builtins. def OpenCLAtomicInit : AtomicBuiltin { let Spellings = ["__opencl_atomic_init"]; @@ -3095,104 +3119,105 @@ def StrLen : LibBuiltin<"string.h"> { // FIXME: This list is incomplete. def Printf : LibBuiltin<"stdio.h"> { let Spellings = ["printf"]; - let Attributes = [PrintfFormat<0>]; + let Attributes = [PrintfFormat<0>, NonNull<NonOptimizing, [0]>]; let Prototype = "int(char const*, ...)"; } // FIXME: The builtin and library function should have the same signature. def BuiltinPrintf : Builtin { let Spellings = ["__builtin_printf"]; - let Attributes = [NoThrow, PrintfFormat<0>, FunctionWithBuiltinPrefix]; + let Attributes = [NoThrow, PrintfFormat<0>, FunctionWithBuiltinPrefix, + NonNull<NonOptimizing, [0]>]; let Prototype = "int(char const* restrict, ...)"; } def FPrintf : LibBuiltin<"stdio.h"> { let Spellings = ["fprintf"]; - let Attributes = [NoThrow, PrintfFormat<1>]; + let Attributes = [NoThrow, PrintfFormat<1>, NonNull<NonOptimizing, [0, 1]>]; let Prototype = "int(FILE* restrict, char const* restrict, ...)"; let AddBuiltinPrefixedAlias = 1; } def SnPrintf : LibBuiltin<"stdio.h"> { let Spellings = ["snprintf"]; - let Attributes = [NoThrow, PrintfFormat<2>]; + let Attributes = [NoThrow, PrintfFormat<2>, NonNull<NonOptimizing, [2]>]; let Prototype = "int(char* restrict, size_t, char const* restrict, ...)"; let AddBuiltinPrefixedAlias = 1; } def SPrintf : LibBuiltin<"stdio.h"> { let Spellings = ["sprintf"]; - let Attributes = [NoThrow, PrintfFormat<1>]; + let Attributes = [NoThrow, PrintfFormat<1>, NonNull<NonOptimizing, [0, 1]>]; let Prototype = "int(char* restrict, char const* restrict, ...)"; let AddBuiltinPrefixedAlias = 1; } def VPrintf : LibBuiltin<"stdio.h"> { let Spellings = ["vprintf"]; - let Attributes = [NoThrow, VPrintfFormat<0>]; + let Attributes = [NoThrow, VPrintfFormat<0>, NonNull<NonOptimizing, [0]>]; let Prototype = "int(char const* restrict, __builtin_va_list)"; let AddBuiltinPrefixedAlias = 1; } def VfPrintf : LibBuiltin<"stdio.h"> { let Spellings = ["vfprintf"]; - let Attributes = [NoThrow, VPrintfFormat<1>]; + let Attributes = [NoThrow, VPrintfFormat<1>, NonNull<NonOptimizing, [0, 1]>]; let Prototype = "int(FILE* restrict, char const* restrict, __builtin_va_list)"; let AddBuiltinPrefixedAlias = 1; } def VsnPrintf : LibBuiltin<"stdio.h"> { let Spellings = ["vsnprintf"]; - let Attributes = [NoThrow, VPrintfFormat<2>]; + let Attributes = [NoThrow, VPrintfFormat<2>, NonNull<NonOptimizing, [2]>]; let Prototype = "int(char* restrict, size_t, char const* restrict, __builtin_va_list)"; let AddBuiltinPrefixedAlias = 1; } def VsPrintf : LibBuiltin<"stdio.h"> { let Spellings = ["vsprintf"]; - let Attributes = [NoThrow, VPrintfFormat<1>]; + let Attributes = [NoThrow, VPrintfFormat<1>, NonNull<NonOptimizing, [0, 1]>]; let Prototype = "int(char* restrict, char const* restrict, __builtin_va_list)"; let AddBuiltinPrefixedAlias = 1; } def Scanf : LibBuiltin<"stdio.h"> { let Spellings = ["scanf"]; - let Attributes = [ScanfFormat<0>]; + let Attributes = [ScanfFormat<0>, NonNull<NonOptimizing, [0]>]; let Prototype = "int(char const* restrict, ...)"; let AddBuiltinPrefixedAlias = 1; } def FScanf : LibBuiltin<"stdio.h"> { let Spellings = ["fscanf"]; - let Attributes = [ScanfFormat<1>]; + let Attributes = [ScanfFormat<1>, NonNull<NonOptimizing, [0, 1]>]; let Prototype = "int(FILE* restrict, char const* restrict, ...)"; let AddBuiltinPrefixedAlias = 1; } def SScanf : LibBuiltin<"stdio.h"> { let Spellings = ["sscanf"]; - let Attributes = [ScanfFormat<1>]; + let Attributes = [ScanfFormat<1>, NonNull<NonOptimizing, [0, 1]>]; let Prototype = "int(char const* restrict, char const* restrict, ...)"; let AddBuiltinPrefixedAlias = 1; } def VScanf : LibBuiltin<"stdio.h"> { let Spellings = ["vscanf"]; - let Attributes = [VScanfFormat<0>]; + let Attributes = [VScanfFormat<0>, NonNull<NonOptimizing, [0]>]; let Prototype = "int(char const* restrict, __builtin_va_list)"; let AddBuiltinPrefixedAlias = 1; } def VFScanf : LibBuiltin<"stdio.h"> { let Spellings = ["vfscanf"]; - let Attributes = [VScanfFormat<1>]; + let Attributes = [VScanfFormat<1>, NonNull<NonOptimizing, [0, 1]>]; let Prototype = "int(FILE* restrict, char const* restrict, __builtin_va_list)"; let AddBuiltinPrefixedAlias = 1; } def VSScanf : LibBuiltin<"stdio.h"> { let Spellings = ["vsscanf"]; - let Attributes = [VScanfFormat<1>]; + let Attributes = [VScanfFormat<1>, NonNull<NonOptimizing, [0, 1]>]; let Prototype = "int(char const* restrict, char const* restrict, __builtin_va_list)"; let AddBuiltinPrefixedAlias = 1; } @@ -4934,28 +4959,34 @@ def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLResourceLoadWithStatus : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_resource_load_with_status"]; + let Attributes = [NoThrow]; + let Prototype = "void(...)"; +} + def HLSLResourceUninitializedHandle : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_resource_uninitializedhandle"]; let Attributes = [NoThrow]; - let Prototype = "void(...)"; + let Prototype = "__hlsl_resource_t(__hlsl_resource_t)"; } def HLSLResourceHandleFromBinding : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_resource_handlefrombinding"]; let Attributes = [NoThrow]; - let Prototype = "void(...)"; + let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t, int32_t, uint32_t, char const*)"; } def HLSLResourceHandleFromImplicitBinding : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_resource_handlefromimplicitbinding"]; let Attributes = [NoThrow]; - let Prototype = "void(...)"; + let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t, int32_t, uint32_t, char const*)"; } def HLSLResourceCounterHandleFromImplicitBinding : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_resource_counterhandlefromimplicitbinding"]; - let Attributes = [NoThrow, CustomTypeChecking]; - let Prototype = "void(...)"; + let Attributes = [NoThrow]; + let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t)"; } def HLSLResourceNonUniformIndex : LangBuiltin<"HLSL_LANG"> { @@ -4967,13 +4998,13 @@ def HLSLResourceNonUniformIndex : LangBuiltin<"HLSL_LANG"> { def HLSLResourceGetDimensionsX : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_resource_getdimensions_x"]; let Attributes = [NoThrow]; - let Prototype = "void(...)"; + let Prototype = "void(__hlsl_resource_t, uint32_t&)"; } def HLSLResourceGetStride : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_resource_getstride"]; let Attributes = [NoThrow]; - let Prototype = "void(...)"; + let Prototype = "void(__hlsl_resource_t, uint32_t&)"; } def HLSLAll : LangBuiltin<"HLSL_LANG"> { @@ -5201,7 +5232,7 @@ def HLSLRadians : LangBuiltin<"HLSL_LANG"> { def HLSLBufferUpdateCounter : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_buffer_update_counter"]; let Attributes = [NoThrow]; - let Prototype = "uint32_t(...)"; + let Prototype = "uint32_t(__hlsl_resource_t, int)"; } def HLSLSplitDouble: LangBuiltin<"HLSL_LANG"> { @@ -5241,6 +5272,18 @@ def HLSLF16ToF32 : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLDdxCoarse : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_ddx_coarse"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HLSLDdyCoarse : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_ddy_coarse"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index b2aa36a..adb6c94 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -109,12 +109,6 @@ BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") // Misc BUILTIN(__builtin_sponentry, "v*", "c") -// Transactional Memory Extension -BUILTIN(__builtin_arm_tstart, "WUi", "nj") -BUILTIN(__builtin_arm_tcommit, "v", "n") -BUILTIN(__builtin_arm_tcancel, "vWUIi", "n") -BUILTIN(__builtin_arm_ttest, "WUi", "nc") - // Armv8.5-A FP rounding intrinsics TARGET_BUILTIN(__builtin_arm_rint32zf, "ff", "", "v8.5a") TARGET_BUILTIN(__builtin_arm_rint32z, "dd", "", "v8.5a") diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index 36cb527..5b3074a 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -122,13 +122,13 @@ BUILTIN(__builtin_amdgcn_frexp_exp, "id", "nc") BUILTIN(__builtin_amdgcn_frexp_expf, "if", "nc") BUILTIN(__builtin_amdgcn_fract, "dd", "nc") BUILTIN(__builtin_amdgcn_fractf, "ff", "nc") -BUILTIN(__builtin_amdgcn_lerp, "UiUiUiUi", "nc") +TARGET_BUILTIN(__builtin_amdgcn_lerp, "UiUiUiUi", "nc", "lerp-inst") BUILTIN(__builtin_amdgcn_class, "bdi", "nc") BUILTIN(__builtin_amdgcn_classf, "bfi", "nc") -BUILTIN(__builtin_amdgcn_cubeid, "ffff", "nc") -BUILTIN(__builtin_amdgcn_cubesc, "ffff", "nc") -BUILTIN(__builtin_amdgcn_cubetc, "ffff", "nc") -BUILTIN(__builtin_amdgcn_cubema, "ffff", "nc") +TARGET_BUILTIN(__builtin_amdgcn_cubeid, "ffff", "nc", "cube-insts") +TARGET_BUILTIN(__builtin_amdgcn_cubesc, "ffff", "nc", "cube-insts") +TARGET_BUILTIN(__builtin_amdgcn_cubetc, "ffff", "nc", "cube-insts") +TARGET_BUILTIN(__builtin_amdgcn_cubema, "ffff", "nc", "cube-insts") BUILTIN(__builtin_amdgcn_s_sleep, "vIi", "n") BUILTIN(__builtin_amdgcn_s_incperflevel, "vIi", "n") BUILTIN(__builtin_amdgcn_s_decperflevel, "vIi", "n") @@ -149,17 +149,17 @@ BUILTIN(__builtin_amdgcn_alignbyte, "UiUiUiUi", "nc") BUILTIN(__builtin_amdgcn_ubfe, "UiUiUiUi", "nc") BUILTIN(__builtin_amdgcn_sbfe, "UiUiUiUi", "nc") BUILTIN(__builtin_amdgcn_cvt_pkrtz, "E2hff", "nc") -BUILTIN(__builtin_amdgcn_cvt_pknorm_i16, "E2sff", "nc") -BUILTIN(__builtin_amdgcn_cvt_pknorm_u16, "E2Usff", "nc") +TARGET_BUILTIN(__builtin_amdgcn_cvt_pknorm_i16, "E2sff", "nc", "cvt-pknorm-vop2-insts") +TARGET_BUILTIN(__builtin_amdgcn_cvt_pknorm_u16, "E2Usff", "nc", "cvt-pknorm-vop2-insts") BUILTIN(__builtin_amdgcn_cvt_pk_i16, "E2sii", "nc") BUILTIN(__builtin_amdgcn_cvt_pk_u16, "E2UsUiUi", "nc") BUILTIN(__builtin_amdgcn_cvt_pk_u8_f32, "UifUiUi", "nc") BUILTIN(__builtin_amdgcn_cvt_off_f32_i4, "fi", "nc") -BUILTIN(__builtin_amdgcn_sad_u8, "UiUiUiUi", "nc") BUILTIN(__builtin_amdgcn_msad_u8, "UiUiUiUi", "nc") -BUILTIN(__builtin_amdgcn_sad_hi_u8, "UiUiUiUi", "nc") -BUILTIN(__builtin_amdgcn_sad_u16, "UiUiUiUi", "nc") -BUILTIN(__builtin_amdgcn_qsad_pk_u16_u8, "WUiWUiUiWUi", "nc") +TARGET_BUILTIN(__builtin_amdgcn_sad_u8, "UiUiUiUi", "nc", "sad-insts") +TARGET_BUILTIN(__builtin_amdgcn_sad_hi_u8, "UiUiUiUi", "nc", "sad-insts") +TARGET_BUILTIN(__builtin_amdgcn_sad_u16, "UiUiUiUi", "nc", "sad-insts") +TARGET_BUILTIN(__builtin_amdgcn_qsad_pk_u16_u8, "WUiWUiUiWUi", "nc", "qsad-insts") BUILTIN(__builtin_amdgcn_mqsad_pk_u16_u8, "WUiWUiUiWUi", "nc") BUILTIN(__builtin_amdgcn_mqsad_u32_u8, "V4UiWUiUiV4Ui", "nc") @@ -180,15 +180,15 @@ BUILTIN(__builtin_amdgcn_raw_buffer_load_b128, "V4UiQbiiIi", "n") BUILTIN(__builtin_amdgcn_raw_ptr_buffer_atomic_add_i32, "iiQbiiIi", "") TARGET_BUILTIN(__builtin_amdgcn_raw_ptr_buffer_atomic_fadd_f32, "ffQbiiIi", "", "atomic-fadd-rtn-insts") -TARGET_BUILTIN(__builtin_amdgcn_raw_ptr_buffer_atomic_fadd_v2f16, "V2hV2hQbiiIi", "t", "atomic-buffer-global-pk-add-f16-insts") +TARGET_BUILTIN(__builtin_amdgcn_raw_ptr_buffer_atomic_fadd_v2f16, "V2hV2hQbiiIi", "", "atomic-buffer-global-pk-add-f16-insts") TARGET_BUILTIN(__builtin_amdgcn_raw_ptr_buffer_atomic_fmin_f32, "ffQbiiIi", "", "atomic-fmin-fmax-global-f32") TARGET_BUILTIN(__builtin_amdgcn_raw_ptr_buffer_atomic_fmax_f32, "ffQbiiIi", "", "atomic-fmin-fmax-global-f32") TARGET_BUILTIN(__builtin_amdgcn_raw_ptr_buffer_atomic_fmin_f64, "ddQbiiIi", "", "atomic-fmin-fmax-global-f64") TARGET_BUILTIN(__builtin_amdgcn_raw_ptr_buffer_atomic_fmax_f64, "ddQbiiIi", "", "atomic-fmin-fmax-global-f64") -TARGET_BUILTIN(__builtin_amdgcn_raw_ptr_buffer_load_lds, "vQbv*3IUiiiIiIi", "t", "vmem-to-lds-load-insts") -TARGET_BUILTIN(__builtin_amdgcn_struct_ptr_buffer_load_lds, "vQbv*3IUiiiiIiIi", "t", "vmem-to-lds-load-insts") +TARGET_BUILTIN(__builtin_amdgcn_raw_ptr_buffer_load_lds, "vQbv*3IUiiiIiIi", "", "vmem-to-lds-load-insts") +TARGET_BUILTIN(__builtin_amdgcn_struct_ptr_buffer_load_lds, "vQbv*3IUiiiiIiIi", "", "vmem-to-lds-load-insts") //===----------------------------------------------------------------------===// // Ballot builtins. @@ -286,7 +286,7 @@ TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fadd_v2bf16, "V2sV2s*1V2s", "t", " TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2bf16, "V2sV2s*3V2s", "t", "atomic-ds-pk-add-16-insts") TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2f16, "V2hV2h*3V2h", "t", "atomic-ds-pk-add-16-insts") TARGET_BUILTIN(__builtin_amdgcn_load_to_lds, "vv*v*3IUiIiIUi", "", "vmem-to-lds-load-insts") -TARGET_BUILTIN(__builtin_amdgcn_global_load_lds, "vv*1v*3IUiIiIUi", "t", "vmem-to-lds-load-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_lds, "vv*1v*3IUiIiIUi", "", "vmem-to-lds-load-insts") //===----------------------------------------------------------------------===// // Deep learning builtins. @@ -402,6 +402,10 @@ BUILTIN(__builtin_amdgcn_wave_reduce_max_u64, "WUiWUiZi", "nc") BUILTIN(__builtin_amdgcn_wave_reduce_and_b64, "WiWiZi", "nc") BUILTIN(__builtin_amdgcn_wave_reduce_or_b64, "WiWiZi", "nc") BUILTIN(__builtin_amdgcn_wave_reduce_xor_b64, "WiWiZi", "nc") +BUILTIN(__builtin_amdgcn_wave_reduce_fadd_f32, "ffZi", "nc") +BUILTIN(__builtin_amdgcn_wave_reduce_fsub_f32, "ffZi", "nc") +BUILTIN(__builtin_amdgcn_wave_reduce_fmin_f32, "ffZi", "nc") +BUILTIN(__builtin_amdgcn_wave_reduce_fmax_f32, "ffZi", "nc") //===----------------------------------------------------------------------===// // R600-NI only builtins. @@ -898,115 +902,115 @@ TARGET_BUILTIN(__builtin_amdgcn_cooperative_atomic_store_8x16B, "vV4i*V4iIicC*", // Image builtins //===----------------------------------------------------------------------===// TARGET_BUILTIN(__builtin_amdgcn_image_load_1d_v4f32_i32, "V4fiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_1d_v4f16_i32, "V4hiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_1d_v4f16_i32, "V4xiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_1darray_v4f32_i32, "V4fiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_1darray_v4f16_i32, "V4hiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_1darray_v4f16_i32, "V4xiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_2d_f32_i32, "fiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_2d_v4f32_i32, "V4fiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_2d_v4f16_i32, "V4hiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_2d_v4f16_i32, "V4xiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_2darray_f32_i32, "fiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_2darray_v4f32_i32, "V4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_2darray_v4f16_i32, "V4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_2darray_v4f16_i32, "V4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_3d_v4f32_i32, "V4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_3d_v4f16_i32, "V4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_3d_v4f16_i32, "V4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_cube_v4f32_i32, "V4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_cube_v4f16_i32, "V4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_cube_v4f16_i32, "V4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_1d_v4f32_i32, "V4fiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_1d_v4f16_i32, "V4hiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_1d_v4f16_i32, "V4xiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_1darray_v4f32_i32, "V4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_1darray_v4f16_i32, "V4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_1darray_v4f16_i32, "V4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_2d_f32_i32, "fiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_2d_v4f32_i32, "V4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_2d_v4f16_i32, "V4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_2d_v4f16_i32, "V4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_2darray_f32_i32, "fiiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_2darray_v4f32_i32, "V4fiiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_2darray_v4f16_i32, "V4hiiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_2darray_v4f16_i32, "V4xiiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_3d_v4f32_i32, "V4fiiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_3d_v4f16_i32, "V4hiiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_3d_v4f16_i32, "V4xiiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_cube_v4f32_i32, "V4fiiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_cube_v4f16_i32, "V4hiiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_load_mip_cube_v4f16_i32, "V4xiiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_1d_v4f32_i32, "vV4fiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_1d_v4f16_i32, "vV4hiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_1d_v4f16_i32, "vV4xiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_1darray_v4f32_i32, "vV4fiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_1darray_v4f16_i32, "vV4hiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_1darray_v4f16_i32, "vV4xiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_2d_f32_i32, "vfiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_2d_v4f32_i32, "vV4fiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_2d_v4f16_i32, "vV4hiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_2d_v4f16_i32, "vV4xiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_2darray_f32_i32, "vfiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_2darray_v4f32_i32, "vV4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_2darray_v4f16_i32, "vV4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_2darray_v4f16_i32, "vV4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_3d_v4f32_i32, "vV4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_3d_v4f16_i32, "vV4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_3d_v4f16_i32, "vV4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_cube_v4f32_i32, "vV4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_cube_v4f16_i32, "vV4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_cube_v4f16_i32, "vV4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_1d_v4f32_i32, "vV4fiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_1d_v4f16_i32, "vV4hiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_1d_v4f16_i32, "vV4xiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_1darray_v4f32_i32, "vV4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_1darray_v4f16_i32, "vV4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_1darray_v4f16_i32, "vV4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_2d_f32_i32, "vfiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_2d_v4f32_i32, "vV4fiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_2d_v4f16_i32, "vV4hiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_2d_v4f16_i32, "vV4xiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_2darray_f32_i32, "vfiiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_2darray_v4f32_i32, "vV4fiiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_2darray_v4f16_i32, "vV4hiiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_2darray_v4f16_i32, "vV4xiiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_3d_v4f32_i32, "vV4fiiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_3d_v4f16_i32, "vV4hiiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_3d_v4f16_i32, "vV4xiiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_cube_v4f32_i32, "vV4fiiiiiQtii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_cube_v4f16_i32, "vV4hiiiiiQtii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_store_mip_cube_v4f16_i32, "vV4xiiiiiQtii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_1d_v4f32_f32, "V4fifQtV4ibii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_1d_v4f16_f32, "V4hifQtV4ibii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_1d_v4f16_f32, "V4xifQtV4ibii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_1darray_v4f32_f32, "V4fiffQtV4ibii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_1darray_v4f16_f32, "V4hiffQtV4ibii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_1darray_v4f16_f32, "V4xiffQtV4ibii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_2d_f32_f32, "fiffQtV4ibii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_2d_v4f32_f32, "V4fiffQtV4ibii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_2d_v4f16_f32, "V4hiffQtV4ibii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_2d_v4f16_f32, "V4xiffQtV4ibii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_2darray_f32_f32, "fifffQtV4ibii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_2darray_v4f32_f32, "V4fifffQtV4ibii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_2darray_v4f16_f32, "V4hifffQtV4ibii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_2darray_v4f16_f32, "V4xifffQtV4ibii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_3d_v4f32_f32, "V4fifffQtV4ibii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_3d_v4f16_f32, "V4hifffQtV4ibii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_3d_v4f16_f32, "V4xifffQtV4ibii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_cube_v4f32_f32, "V4fifffQtV4ibii", "nc", "image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_cube_v4f16_f32, "V4hifffQtV4ibii", "nc", "image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_cube_v4f16_f32, "V4xifffQtV4ibii", "nc", "image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_1d_v4f32_f32, "V4fifQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_1d_v4f16_f32, "V4eifQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_1d_v4f16_f32, "V4xifQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_1darray_v4f32_f32, "V4fiffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_1darray_v4f16_f32, "V4eiffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_1darray_v4f16_f32, "V4xiffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_2d_f32_f32, "fiffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_2d_v4f32_f32, "V4fiffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_2d_v4f16_f32, "V4eiffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_2d_v4f16_f32, "V4xiffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_2darray_f32_f32, "fifffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_2darray_v4f32_f32, "V4fifffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_2darray_v4f16_f32, "V4eifffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_2darray_v4f16_f32, "V4xifffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_3d_v4f32_f32, "V4fifffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_3d_v4f16_f32, "V4eifffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_3d_v4f16_f32, "V4xifffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_cube_v4f32_f32, "V4fifffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_cube_v4f16_f32, "V4eifffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_lz_cube_v4f16_f32, "V4xifffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_1d_v4f32_f32, "V4fiffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_1d_v4f16_f32, "V4eiffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_1d_v4f16_f32, "V4xiffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_1darray_v4f32_f32, "V4fifffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_1darray_v4f16_f32, "V4eifffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_1darray_v4f16_f32, "V4xifffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_2d_f32_f32, "fifffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_2d_v4f32_f32, "V4fifffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_2d_v4f16_f32, "V4eifffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_2d_v4f16_f32, "V4xifffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_2darray_f32_f32, "fiffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_2darray_v4f32_f32, "V4fiffffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_2darray_v4f16_f32, "V4eiffffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_2darray_v4f16_f32, "V4xiffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_3d_v4f32_f32, "V4fiffffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_3d_v4f16_f32, "V4eiffffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_3d_v4f16_f32, "V4xiffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_cube_v4f32_f32, "V4fiffffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_cube_v4f16_f32, "V4eiffffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_l_cube_v4f16_f32, "V4xiffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_1d_v4f32_f32, "V4fifffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_1d_v4f16_f32, "V4eifffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_1d_v4f16_f32, "V4xifffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_1darray_v4f32_f32, "V4fiffffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_1darray_v4f16_f32, "V4eiffffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_1darray_v4f16_f32, "V4xiffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_2d_f32_f32, "fiffffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_2d_v4f32_f32, "V4fiffffffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_2d_v4f16_f32, "V4eiffffffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_2d_v4f16_f32, "V4xiffffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_2darray_f32_f32, "fifffffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_2darray_v4f32_f32, "V4fifffffffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_2darray_v4f16_f32, "V4eifffffffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_2darray_v4f16_f32, "V4xifffffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_3d_v4f32_f32, "V4fifffffffffQtV4ibii", "nc", "extended-image-insts") -TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_3d_v4f16_f32, "V4eifffffffffQtV4ibii", "nc", "extended-image-insts") +TARGET_BUILTIN(__builtin_amdgcn_image_sample_d_3d_v4f16_f32, "V4xifffffffffQtV4ibii", "nc", "extended-image-insts") TARGET_BUILTIN(__builtin_amdgcn_image_gather4_lz_2d_v4f32_f32, "V4fiffQtV4ibii", "nc", "extended-image-insts") #undef BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsBase.td b/clang/include/clang/Basic/BuiltinsBase.td index 09bc9f8..7394f0e 100644 --- a/clang/include/clang/Basic/BuiltinsBase.td +++ b/clang/include/clang/Basic/BuiltinsBase.td @@ -32,7 +32,17 @@ def Const : Attribute<"c">; def NoThrow : Attribute<"n">; def Pure : Attribute<"U">; def ReturnsTwice : Attribute<"j">; -// FIXME: gcc has nonnull + +class NonNullOptMode<int mode> { + int value = mode; +} + +def NonOptimizing : NonNullOptMode<0>; +def Optimizing : NonNullOptMode<1>; + +class NonNull<NonNullOptMode Mode, list<int> Is> : MultiIndexAttribute<"N:" # Mode.value # ":", Is> { + int optMode = Mode.value; +} // builtin-specific attributes // --------------------------- diff --git a/clang/include/clang/Basic/BuiltinsHexagon.td b/clang/include/clang/Basic/BuiltinsHexagon.td index cf18359..00f84cd 100644 --- a/clang/include/clang/Basic/BuiltinsHexagon.td +++ b/clang/include/clang/Basic/BuiltinsHexagon.td @@ -2146,3 +2146,69 @@ let Features = HVXV79.Features in { def V6_vsub_hf_f8 : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; def V6_vsub_hf_f8_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; } + +// V81 HVX Instructions. +let Features = HVXV81.Features in { + def V6_vabs_qf16_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabs_qf16_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vabs_qf16_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabs_qf16_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vabs_qf32_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabs_qf32_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vabs_qf32_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabs_qf32_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_valign4 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_valign4_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vconv_bf_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>)">; + def V6_vconv_bf_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>)">; + def V6_vconv_f8_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_f8_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_h_hf_rnd : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_h_hf_rnd_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_qf16_f8 : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vconv_qf16_f8_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vconv_qf16_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_qf16_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_qf16_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_qf16_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_qf32_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_qf32_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_qf32_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_qf32_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_veqhf : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_veqhf_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_veqhf_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqhf_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqhf_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqhf_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqhf_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqhf_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqsf : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_veqsf_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_veqsf_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqsf_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqsf_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqsf_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqsf_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqsf_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vilog2_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vilog2_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vilog2_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vilog2_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vilog2_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vilog2_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vilog2_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vilog2_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vneg_qf16_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vneg_qf16_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vneg_qf16_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vneg_qf16_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vneg_qf32_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vneg_qf32_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vneg_qf32_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vneg_qf32_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vsub_hf_mix : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_hf_mix_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_sf_mix : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_sf_mix_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; +} diff --git a/clang/include/clang/Basic/BuiltinsLoongArchLASX.def b/clang/include/clang/Basic/BuiltinsLoongArchLASX.def index c4ea46a..a5eee61 100644 --- a/clang/include/clang/Basic/BuiltinsLoongArchLASX.def +++ b/clang/include/clang/Basic/BuiltinsLoongArchLASX.def @@ -986,3 +986,22 @@ TARGET_BUILTIN(__builtin_lasx_xbnz_b, "iV32Uc", "nc", "lasx") TARGET_BUILTIN(__builtin_lasx_xbnz_h, "iV16Us", "nc", "lasx") TARGET_BUILTIN(__builtin_lasx_xbnz_w, "iV8Ui", "nc", "lasx") TARGET_BUILTIN(__builtin_lasx_xbnz_d, "iV4ULLi", "nc", "lasx") + +TARGET_BUILTIN(__builtin_lasx_cast_128_s, "V8fV4f", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_cast_128_d, "V4dV2d", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_cast_128, "V4LLiV2LLi", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_concat_128_s, "V8fV4fV4f", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_concat_128_d, "V4dV2dV2d", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_concat_128, "V4LLiV2LLiV2LLi", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_extract_128_lo_s, "V4fV8f", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_extract_128_lo_d, "V2dV4d", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_extract_128_lo, "V2LLiV4LLi", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_extract_128_hi_s, "V4fV8f", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_extract_128_hi_d, "V2dV4d", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_extract_128_hi, "V2LLiV4LLi", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_insert_128_lo_s, "V8fV8fV4f", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_insert_128_lo_d, "V4dV4dV2d", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_insert_128_lo, "V4LLiV4LLiV2LLi", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_insert_128_hi_s, "V8fV8fV4f", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_insert_128_hi_d, "V4dV4dV2d", "nc", "lasx") +TARGET_BUILTIN(__builtin_lasx_insert_128_hi, "V4LLiV4LLiV2LLi", "nc", "lasx") diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.td b/clang/include/clang/Basic/BuiltinsNVPTX.td index d923d2a..96b6f75 100644 --- a/clang/include/clang/Basic/BuiltinsNVPTX.td +++ b/clang/include/clang/Basic/BuiltinsNVPTX.td @@ -23,6 +23,7 @@ class SM<string version, list<SMFeatures> newer_list> : SMFeatures { let Features = "sm_121a" in def SM_121a : SMFeatures; let Features = "sm_120a" in def SM_120a : SMFeatures; +let Features = "sm_110a" in def SM_110a : SMFeatures; let Features = "sm_103a" in def SM_103a : SMFeatures; let Features = "sm_101a" in def SM_101a : SMFeatures; let Features = "sm_100a" in def SM_100a : SMFeatures; @@ -30,12 +31,14 @@ let Features = "sm_90a" in def SM_90a : SMFeatures; def SM_121 : SM<"121", [SM_121a]>; def SM_120 : SM<"120", [SM_120a, SM_121]>; -def SM_103 : SM<"103", [SM_103a, SM_120]>; +def SM_110 : SM<"110", [SM_110a, SM_120]>; +def SM_103 : SM<"103", [SM_103a, SM_110]>; def SM_101 : SM<"101", [SM_101a, SM_103]>; def SM_100 : SM<"100", [SM_100a, SM_101]>; def SM_90 : SM<"90", [SM_90a, SM_100]>; def SM_89 : SM<"89", [SM_90]>; -def SM_87 : SM<"87", [SM_89]>; +def SM_88 : SM<"88", [SM_89]>; +def SM_87 : SM<"87", [SM_88]>; def SM_86 : SM<"86", [SM_87]>; def SM_80 : SM<"80", [SM_86]>; def SM_75 : SM<"75", [SM_80]>; @@ -54,8 +57,9 @@ class PTX<string version, PTXFeatures newer> : PTXFeatures { let Features = !strconcat("ptx", version, "|", newer.Features); } -let Features = "ptx88" in def PTX88 : PTXFeatures; +let Features = "ptx90" in def PTX90 : PTXFeatures; +def PTX88 : PTX<"88", PTX90>; def PTX87 : PTX<"87", PTX88>; def PTX86 : PTX<"86", PTX87>; def PTX85 : PTX<"85", PTX86>; @@ -579,6 +583,10 @@ def __nvvm_ff2bf16x2_rn : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float) def __nvvm_ff2bf16x2_rn_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX70>; def __nvvm_ff2bf16x2_rz : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX70>; def __nvvm_ff2bf16x2_rz_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX70>; +def __nvvm_ff2bf16x2_rn_satfinite : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX81>; +def __nvvm_ff2bf16x2_rn_relu_satfinite : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX81>; +def __nvvm_ff2bf16x2_rz_satfinite : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX81>; +def __nvvm_ff2bf16x2_rz_relu_satfinite : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX81>; def __nvvm_ff2bf16x2_rs : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float, uint32_t)", SM<"100a", [SM_103a]>, PTX87>; @@ -596,6 +604,10 @@ def __nvvm_ff2f16x2_rn : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)" def __nvvm_ff2f16x2_rn_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX70>; def __nvvm_ff2f16x2_rz : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX70>; def __nvvm_ff2f16x2_rz_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX70>; +def __nvvm_ff2f16x2_rn_satfinite : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX81>; +def __nvvm_ff2f16x2_rn_relu_satfinite : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX81>; +def __nvvm_ff2f16x2_rz_satfinite : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX81>; +def __nvvm_ff2f16x2_rz_relu_satfinite : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX81>; def __nvvm_ff2f16x2_rs : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float, uint32_t)", SM<"100a", [SM_103a]>, PTX87>; @@ -613,9 +625,22 @@ def __nvvm_f2bf16_rn : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX70>; def __nvvm_f2bf16_rn_relu : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX70>; def __nvvm_f2bf16_rz : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX70>; def __nvvm_f2bf16_rz_relu : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX70>; +def __nvvm_f2bf16_rn_satfinite : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX81>; +def __nvvm_f2bf16_rn_relu_satfinite : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX81>; +def __nvvm_f2bf16_rz_satfinite : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX81>; +def __nvvm_f2bf16_rz_relu_satfinite : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX81>; + +def __nvvm_f2f16_rn : NVPTXBuiltinSMAndPTX<"__fp16(float)", SM_80, PTX70>; +def __nvvm_f2f16_rn_relu : NVPTXBuiltinSMAndPTX<"__fp16(float)", SM_80, PTX70>; +def __nvvm_f2f16_rz : NVPTXBuiltinSMAndPTX<"__fp16(float)", SM_80, PTX70>; +def __nvvm_f2f16_rz_relu : NVPTXBuiltinSMAndPTX<"__fp16(float)", SM_80, PTX70>; +def __nvvm_f2f16_rn_satfinite : NVPTXBuiltinSMAndPTX<"__fp16(float)", SM_80, PTX81>; +def __nvvm_f2f16_rn_relu_satfinite : NVPTXBuiltinSMAndPTX<"__fp16(float)", SM_80, PTX81>; +def __nvvm_f2f16_rz_satfinite : NVPTXBuiltinSMAndPTX<"__fp16(float)", SM_80, PTX81>; +def __nvvm_f2f16_rz_relu_satfinite : NVPTXBuiltinSMAndPTX<"__fp16(float)", SM_80, PTX81>; def __nvvm_f2tf32_rna : NVPTXBuiltinSMAndPTX<"int32_t(float)", SM_80, PTX70>; -def __nvvm_f2tf32_rna_satfinite : NVPTXBuiltinSMAndPTX<"int32_t(float)", SM_89, PTX81>; +def __nvvm_f2tf32_rna_satfinite : NVPTXBuiltinSMAndPTX<"int32_t(float)", SM_80, PTX81>; def __nvvm_f2tf32_rn : NVPTXBuiltinSMAndPTX<"int32_t(float)", SM_90, PTX78>; def __nvvm_f2tf32_rn_relu : NVPTXBuiltinSMAndPTX<"int32_t(float)", SM_90, PTX78>; def __nvvm_f2tf32_rn_satfinite : NVPTXBuiltinSMAndPTX<"int32_t(float)", SM_100, PTX86>; diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index cf8bdd2..216b5fd 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -1001,6 +1001,10 @@ TARGET_BUILTIN(__builtin_darn_32, "i", "", "isa-v30-instructions") TARGET_BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "", "vsx") TARGET_BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "", "vsx") +// AMO builtins +TARGET_BUILTIN(__builtin_amo_lwat, "UiUi*UiIi", "", "isa-v30-instructions") +TARGET_BUILTIN(__builtin_amo_ldat, "ULiULi*ULiIi", "", "isa-v30-instructions") + // Set the floating point rounding mode BUILTIN(__builtin_setrnd, "di", "") diff --git a/clang/include/clang/Basic/BuiltinsSPIRVVK.td b/clang/include/clang/Basic/BuiltinsSPIRVVK.td index 5dc3c75..a077a76 100644 --- a/clang/include/clang/Basic/BuiltinsSPIRVVK.td +++ b/clang/include/clang/Basic/BuiltinsSPIRVVK.td @@ -12,3 +12,4 @@ include "clang/Basic/BuiltinsSPIRVBase.td" def reflect : SPIRVBuiltin<"void(...)", [NoThrow, Const]>; def faceforward : SPIRVBuiltin<"void(...)", [NoThrow, Const, CustomTypeChecking]>; def refract : SPIRVBuiltin<"void(...)", [NoThrow, Const, CustomTypeChecking]>; +def fwidth : SPIRVBuiltin<"void(...)", [NoThrow, Const, CustomTypeChecking]>; diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td index 9e877b9..71aee503 100644 --- a/clang/include/clang/Basic/BuiltinsX86.td +++ b/clang/include/clang/Basic/BuiltinsX86.td @@ -91,57 +91,6 @@ let Attributes = [Const, NoThrow, RequiredVectorWidth<128>] in { def cmppd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant char)">; def cmpsd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant char)">; } - - - let Features = "sse2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { - def pavgb128 : X86Builtin<"_Vector<16, unsigned char>(_Vector<16, unsigned char>, _Vector<16, unsigned char>)">; - def pavgw128 : X86Builtin<"_Vector<8, unsigned short>(_Vector<8, unsigned short>, _Vector<8, unsigned short>)">; - def pmulhw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; - def pmulhuw128 : X86Builtin<"_Vector<8, unsigned short>(_Vector<8, unsigned short>, _Vector<8, unsigned short>)">; - def packsswb128 : X86Builtin<"_Vector<16, char>(_Vector<8, short>, _Vector<8, short>)">; - def packssdw128 : X86Builtin<"_Vector<8, short>(_Vector<4, int>, _Vector<4, int>)">; - def packuswb128 : X86Builtin<"_Vector<16, char>(_Vector<8, short>, _Vector<8, short>)">; - - def vec_ext_v2di : X86Builtin<"long long int(_Vector<2, long long int>, _Constant int)">; - def vec_ext_v4si : X86Builtin<"int(_Vector<4, int>, _Constant int)">; - def vec_ext_v4sf : X86Builtin<"float(_Vector<4, float>, _Constant int)">; - def vec_ext_v8hi : X86Builtin<"short(_Vector<8, short>, _Constant int)">; - def vec_set_v8hi : X86Builtin<"_Vector<8, short>(_Vector<8, short>, short, _Constant int)">; - } - - let Features = "sse3" in { - foreach Op = ["addsub"] in { - def Op#ps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>)">; - def Op#pd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>)">; - } - } - - let Features = "sse3", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { - foreach Op = ["hadd", "hsub"] in { - def Op#ps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>)">; - def Op#pd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>)">; - } - } - - let Features = "ssse3", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { - def psignb128 - : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">; - def psignw128 - : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; - def psignd128 - : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">; - def pmulhrsw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; - def pmaddubsw128 : X86Builtin<"_Vector<8, short>(_Vector<16, char>, _Vector<16, char>)">; - def pshufb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">; - } -} - -// AVX -let Attributes = [Const, NoThrow, RequiredVectorWidth<256>], Features = "avx" in { - foreach Op = ["addsub", "max", "min"] in { - def Op#pd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, double>)">; - def Op#ps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>)">; - } } let Features = "mmx", Header = "mmintrin.h", Attributes = [NoThrow, Const] in { @@ -207,8 +156,6 @@ let Features = "sse", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in def rcpss : X86Builtin<"_Vector<4, float>(_Vector<4, float>)">; def rsqrtps : X86Builtin<"_Vector<4, float>(_Vector<4, float>)">; def rsqrtss : X86Builtin<"_Vector<4, float>(_Vector<4, float>)">; - def sqrtps : X86Builtin<"_Vector<4, float>(_Vector<4, float>)">; - def sqrtss : X86Builtin<"_Vector<4, float>(_Vector<4, float>)">; } let Features = "sse2", Attributes = [NoThrow, RequiredVectorWidth<128>] in { @@ -220,24 +167,19 @@ let Features = "sse2", Attributes = [NoThrow] in { } let Features = "sse2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { - def pshuflw : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Constant int)">; - def pshufd : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Constant int)">; - def pshufhw : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Constant int)">; - def movmskpd : X86Builtin<"int(_Vector<2, double>)">; - def pmovmskb128 : X86Builtin<"int(_Vector<16, char>)">; - def shufpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant int)">; + def cvtpd2ps : X86Builtin<"_Vector<4, float>(_Vector<2, double>)">; + def cvtsd2ss : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<2, double>)">; +} +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { + def cvtsd2ss_round_mask : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<2, double>, _Vector<4, float>, unsigned char, _Constant int)">; } let Features = "sse2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { def psadbw128 : X86Builtin<"_Vector<2, long long int>(_Vector<16, char>, _Vector<16, char>)">; - def sqrtpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>)">; - def sqrtsd : X86Builtin<"_Vector<2, double>(_Vector<2, double>)">; def cvtpd2dq : X86Builtin<"_Vector<2, long long int>(_Vector<2, double>)">; - def cvtpd2ps : X86Builtin<"_Vector<4, float>(_Vector<2, double>)">; def cvttpd2dq : X86Builtin<"_Vector<4, int>(_Vector<2, double>)">; def cvtsd2si : X86Builtin<"int(_Vector<2, double>)">; def cvttsd2si : X86Builtin<"int(_Vector<2, double>)">; - def cvtsd2ss : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<2, double>)">; def cvtps2dq : X86Builtin<"_Vector<4, int>(_Vector<4, float>)">; def cvttps2dq : X86Builtin<"_Vector<4, int>(_Vector<4, float>)">; } @@ -274,23 +216,27 @@ let Header = "emmintrin.h", Attributes = [NoThrow, RequireDeclaration] in { def _mm_pause : X86LibBuiltin<"void()">; } -let Features = "sse2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def psraw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; - def psrad128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">; - def psrlw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; - def psrld128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">; - def psrlq128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">; - def psllw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; - def pslld128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">; - def psllq128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">; -} +let Features = "sse2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { + def movmskpd : X86Builtin<"int(_Vector<2, double>)">; + def pmovmskb128 : X86Builtin<"int(_Vector<16, char>)">; + + def pavgb128 : X86Builtin<"_Vector<16, unsigned char>(_Vector<16, unsigned char>, _Vector<16, unsigned char>)">; + def pavgw128 : X86Builtin<"_Vector<8, unsigned short>(_Vector<8, unsigned short>, _Vector<8, unsigned short>)">; -let Features = "sse2", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def pmaddwd128 : X86Builtin<"_Vector<4, int>(_Vector<8, short>, _Vector<8, short>)">; - + def pmulhw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; + def pmulhuw128 : X86Builtin<"_Vector<8, unsigned short>(_Vector<8, unsigned short>, _Vector<8, unsigned short>)">; def pmuludq128 : X86Builtin<"_Vector<2, long long int>(_Vector<4, int>, _Vector<4, int>)">; + def packsswb128 : X86Builtin<"_Vector<16, char>(_Vector<8, short>, _Vector<8, short>)">; + def packssdw128 : X86Builtin<"_Vector<8, short>(_Vector<4, int>, _Vector<4, int>)">; + def packuswb128 : X86Builtin<"_Vector<16, char>(_Vector<8, short>, _Vector<8, short>)">; + + def pshuflw : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Constant int)">; + def pshufd : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Constant int)">; + def pshufhw : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Constant int)">; + def shufpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant int)">; + def psllwi128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, int)">; def pslldi128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, int)">; def psllqi128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, int)">; @@ -304,6 +250,21 @@ let Features = "sse2", def pslldqi128_byteshift : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Constant int)">; def psrldqi128_byteshift : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Constant int)">; + + def vec_ext_v2di : X86Builtin<"long long int(_Vector<2, long long int>, _Constant int)">; + def vec_ext_v4si : X86Builtin<"int(_Vector<4, int>, _Constant int)">; + def vec_ext_v4sf : X86Builtin<"float(_Vector<4, float>, _Constant int)">; + def vec_ext_v8hi : X86Builtin<"short(_Vector<8, short>, _Constant int)">; + def vec_set_v8hi : X86Builtin<"_Vector<8, short>(_Vector<8, short>, short, _Constant int)">; + + def psraw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; + def psrad128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">; + def psrlw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; + def psrld128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">; + def psrlq128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">; + def psllw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; + def pslld128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">; + def psllq128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">; } let Features = "sse3", Attributes = [NoThrow] in { @@ -315,11 +276,22 @@ let Features = "sse3", Attributes = [NoThrow, RequiredVectorWidth<128>] in { def lddqu : X86Builtin<"_Vector<16, char>(char const *)">; } -let Features = "ssse3", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def palignr128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>, _Constant int)">; +let Features = "sse3", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { + foreach Op = ["addsub", "hadd", "hsub"] in { + def Op#ps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>)">; + def Op#pd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>)">; + } } let Features = "ssse3", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { + def palignr128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>, _Constant int)">; + def pmulhrsw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; + def pmaddubsw128 : X86Builtin<"_Vector<8, short>(_Vector<16, char>, _Vector<16, char>)">; + def pshufb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">; + def psignb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">; + def psignw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; + def psignd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">; + foreach Op = ["phadd", "phsub"] in { def Op#w128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; def Op#sw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; @@ -333,25 +305,13 @@ let Features = "sse4.1", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] def roundsd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant int)">; def roundpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Constant int)">; def dpps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Constant char)">; - def dppd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, " - "_Vector<2,double>, _Constant char)">; - def mpsadbw128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, " - "_Vector<16, char>, _Constant char)">; -} - -let Features = "sse4.1", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { - def insertps128 : X86Builtin<"_Vector<4, float>(_Vector<4, float>, " - "_Vector<4, float>, _Constant char)">; - def ptestz128 - : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; - def ptestc128 - : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; - def ptestnzc128 - : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; + def dppd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2,double>, _Constant char)">; + def mpsadbw128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>, _Constant char)">; } let Features = "sse4.1", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { + def insertps128 : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Constant char)">; + def pblendw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>, _Constant int)">; def blendpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant int)">; def blendps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Constant int)">; @@ -363,6 +323,10 @@ let Features = "sse4.1", Attributes = [NoThrow, Const, Constexpr, RequiredVector def packusdw128 : X86Builtin<"_Vector<8, short>(_Vector<4, int>, _Vector<4, int>)">; def phminposuw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>)">; + def ptestz128 : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; + def ptestc128 : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; + def ptestnzc128 : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">; + def vec_ext_v16qi : X86Builtin<"char(_Vector<16, char>, _Constant int)">; def vec_set_v16qi : X86Builtin<"_Vector<16, char>(_Vector<16, char>, char, _Constant int)">; def vec_set_v4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, int, _Constant int)">; @@ -444,39 +408,21 @@ let Features = "avx512f,vaes", Attributes = [NoThrow, Const, RequiredVectorWidth def aesdeclast512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<8, long long int>)">; } -let Features = "gfni", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "gfni", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def vgf2p8affineinvqb_v16qi : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>, _Constant char)">; -} - -let Features = "avx,gfni", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def vgf2p8affineinvqb_v32qi : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Constant char)">; -} - -let Features = "avx512f,gfni", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def vgf2p8affineinvqb_v64qi : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>, _Constant char)">; -} - -let Features = "gfni", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { def vgf2p8affineqb_v16qi : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>, _Constant char)">; -} - -let Features = "avx,gfni", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def vgf2p8affineqb_v32qi : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Constant char)">; -} - -let Features = "avx512f,gfni", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def vgf2p8affineqb_v64qi : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>, _Constant char)">; -} - -let Features = "gfni", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { def vgf2p8mulb_v16qi : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">; } -let Features = "avx,gfni", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx,gfni", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { + def vgf2p8affineinvqb_v32qi : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Constant char)">; + def vgf2p8affineqb_v32qi : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Constant char)">; def vgf2p8mulb_v32qi : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>)">; } -let Features = "avx512f,gfni", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512f,gfni", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { + def vgf2p8affineinvqb_v64qi : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>, _Constant char)">; + def vgf2p8affineqb_v64qi : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>, _Constant char)">; def vgf2p8mulb_v64qi : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>)">; } @@ -497,15 +443,21 @@ let Features = "avx", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWid def shufps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, _Constant int)">; } -let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def vpermilvarpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, long long int>)">; def vpermilvarps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, int>)">; def vpermilvarpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, long long int>)">; def vpermilvarps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, int>)">; +} + +let Features = "avx", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { + def cvtpd2ps256 : X86Builtin<"_Vector<4, float>(_Vector<4, double>)">; +} + +let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { def dpps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, _Constant char)">; def cmppd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, double>, _Constant char)">; def cmpps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, _Constant char)">; - def cvtpd2ps256 : X86Builtin<"_Vector<4, float>(_Vector<4, double>)">; def cvtps2dq256 : X86Builtin<"_Vector<8, int>(_Vector<8, float>)">; def cvttpd2dq256 : X86Builtin<"_Vector<4, int>(_Vector<4, double>)">; def cvtpd2dq256 : X86Builtin<"_Vector<4, int>(_Vector<4, double>)">; @@ -513,9 +465,13 @@ let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in def vperm2f128_pd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, double>, _Constant int)">; def vperm2f128_ps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, _Constant int)">; def vperm2f128_si256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Constant int)">; + foreach Op = ["max", "min"] in { + def Op#pd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, double>)">; + def Op#ps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>)">; + } } -let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def vpermilpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Constant int)">; def vpermilps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Constant int)">; } @@ -531,18 +487,16 @@ let Features = "avx", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWid def vinsertf128_pd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<2, double>, _Constant int)">; def vinsertf128_ps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<4, float>, _Constant int)">; def vinsertf128_si256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<4, int>, _Constant int)">; + def vpermilpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Constant int)">; + def vpermilps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Constant int)">; - foreach Op = ["hadd", "hsub"] in { + foreach Op = ["addsub", "hadd", "hsub"] in { def Op#pd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, double>)">; def Op#ps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>)">; } } let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def vpermilpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Constant int)">; - def vpermilps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Constant int)">; - def sqrtpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>)">; - def sqrtps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>)">; def rsqrtps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>)">; def rcpps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>)">; def roundpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Constant int)">; @@ -609,31 +563,22 @@ let Features = "avx", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWid let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { def mpsadbw256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Constant char)">; - def palignr256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, " - "_Vector<32, char>, _Constant int)">; + def psadbw256 : X86Builtin< "_Vector<4, long long int>(_Vector<32, char>, _Vector<32, char>)">; - def psllw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<8, short>)">; - def pslld256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<4, int>)">; - def psllq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<2, long long int>)">; - def psraw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<8, short>)">; - def psrad256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<4, int>)">; - def psrlw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<8, short>)">; - def psrld256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<4, int>)">; - def psrlq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<2, long long int>)">; - def permvarsi256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">; - def permdf256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Constant int)">; - def permvarsf256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, int>)">; def permti256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>, _Constant int)">; - def permdi256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Constant int)">; } - let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { + def permdf256 + : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Constant int)">; + def permdi256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long " + "int>, _Constant int)">; def pmovmskb256 : X86Builtin<"int(_Vector<32, char>)">; def pavgb256 : X86Builtin<"_Vector<32, unsigned char>(_Vector<32, unsigned char>, _Vector<32, unsigned char>)">; def pavgw256 : X86Builtin<"_Vector<16, unsigned short>(_Vector<16, unsigned short>, _Vector<16, unsigned short>)">; + def palignr256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Constant int)">; def pblendd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Constant int)">; def pblendd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Constant int)">; @@ -696,6 +641,18 @@ let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWi def pshuflw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Constant int)">; def pshufhw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Constant int)">; def pshufd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Constant int)">; + + def permvarsi256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">; + def permvarsf256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, int>)">; + + def psllw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<8, short>)">; + def pslld256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<4, int>)">; + def psllq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<2, long long int>)">; + def psraw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<8, short>)">; + def psrad256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<4, int>)">; + def psrlw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<8, short>)">; + def psrld256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<4, int>)">; + def psrlq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<2, long long int>)">; } let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { @@ -743,11 +700,13 @@ let Features = "avx2", Attributes = [NoThrow, RequiredVectorWidth<128>] in { def gatherq_d : X86Builtin<"_Vector<4, int>(_Vector<4, int>, int const *, _Vector<2, long long int>, _Vector<4, int>, _Constant char)">; } -let Features = "f16c", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "f16c", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def vcvtps2ph : X86Builtin<"_Vector<8, short>(_Vector<4, float>, _Constant int)">; } -let Features = "f16c", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "f16c", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def vcvtps2ph256 : X86Builtin<"_Vector<8, short>(_Vector<8, float>, _Constant int)">; } @@ -870,16 +829,6 @@ let Features = "sha", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in def sha256msg2 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">; } -let Features = "fma", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def vfmaddss3 : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Vector<4, float>)">; - def vfmaddsd3 : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Vector<2, double>)">; -} - -let Features = "fma4", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def vfmaddss : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Vector<4, float>)">; - def vfmaddsd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Vector<2, double>)">; -} - let Features = "fma|fma4", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { def vfmaddsubps : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Vector<4, float>)">; def vfmaddsubpd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Vector<2, double>)">; @@ -1046,6 +995,10 @@ let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128 def cmppd128_mask : X86Builtin<"unsigned char(_Vector<2, double>, _Vector<2, double>, _Constant int, unsigned char)">; } +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { + def cvtpd2ps512_mask : X86Builtin<"_Vector<8, float>(_Vector<8, double>, _Vector<8, float>, unsigned char, _Constant int)">; +} + let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { def rndscaleps_mask : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Constant int, _Vector<16, float>, unsigned short, _Constant int)">; def rndscalepd_mask : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Constant int, _Vector<8, double>, unsigned char, _Constant int)">; @@ -1059,7 +1012,6 @@ let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512> def maxpd512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Vector<8, double>, _Constant int)">; def cvtdq2ps512_mask : X86Builtin<"_Vector<16, float>(_Vector<16, int>, _Vector<16, float>, unsigned short, _Constant int)">; def cvtudq2ps512_mask : X86Builtin<"_Vector<16, float>(_Vector<16, int>, _Vector<16, float>, unsigned short, _Constant int)">; - def cvtpd2ps512_mask : X86Builtin<"_Vector<8, float>(_Vector<8, double>, _Vector<8, float>, unsigned char, _Constant int)">; def vcvtps2ph512_mask : X86Builtin<"_Vector<16, short>(_Vector<16, float>, _Constant int, _Vector<16, short>, unsigned short)">; def vcvtph2ps512_mask : X86Builtin<"_Vector<16, float>(_Vector<16, short>, _Vector<16, float>, unsigned short, _Constant int)">; } @@ -1085,24 +1037,24 @@ let Features = "avx512f", Attributes = [NoThrow, RequiredVectorWidth<512>] in { def storeaps512_mask : X86Builtin<"void(_Vector<16, float *>, _Vector<16, float>, unsigned short)">; } -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def alignq512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<8, long long int>, _Constant int)">; def alignd512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Constant int)">; } -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def alignd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Constant int)">; } -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def alignd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Constant int)">; } -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def alignq128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>, _Constant int)">; } -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def alignq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>, _Constant int)">; } @@ -1136,27 +1088,27 @@ let Features = "avx512vnni", Attributes = [NoThrow, Const, RequiredVectorWidth<5 } let Features = "avx512vl,avx512vnni|avxvnni", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def vpdpwssd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">; + def vpdpwssd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<8, short>, _Vector<8, short>)">; } let Features = "avx512vl,avx512vnni|avxvnni", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def vpdpwssd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; + def vpdpwssd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<16, short>, _Vector<16, short>)">; } let Features = "avx512vnni", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def vpdpwssd512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def vpdpwssd512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, short>, _Vector<32, short>)">; } let Features = "avx512vl,avx512vnni|avxvnni", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def vpdpwssds128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">; + def vpdpwssds128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<8, short>, _Vector<8, short>)">; } let Features = "avx512vl,avx512vnni|avxvnni", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def vpdpwssds256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; + def vpdpwssds256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<16, short>, _Vector<16, short>)">; } let Features = "avx512vnni", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def vpdpwssds512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def vpdpwssds512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, short>, _Vector<32, short>)">; } let Features = "avxvnniint8|avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { @@ -1283,102 +1235,46 @@ let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in { def knotdi : X86Builtin<"unsigned long long int(unsigned long long int)">; } -let Features = "avx512vl,avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { - def cmpb128_mask : X86Builtin<"unsigned short(_Vector<16, char>, _Vector<16, char>, _Constant int, unsigned short)">; -} - -let Features = "avx512vl", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def cmpd128_mask : X86Builtin<"unsigned char(_Vector<4, int>, _Vector<4, int>, _Constant int, unsigned char)">; def cmpq128_mask : X86Builtin<"unsigned char(_Vector<2, long long int>, _Vector<2, long long int>, _Constant int, unsigned char)">; -} - -let Features = "avx512vl,avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { - def cmpw128_mask : X86Builtin<"unsigned char(_Vector<8, short>, _Vector<8, short>, _Constant int, unsigned char)">; -} -let Features = "avx512vl,avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { - def cmpb256_mask : X86Builtin<"unsigned int(_Vector<32, char>, _Vector<32, char>, _Constant int, unsigned int)">; -} - -let Features = "avx512vl", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { - def cmpd256_mask : X86Builtin<"unsigned char(_Vector<8, int>, _Vector<8, int>, _Constant int, unsigned char)">; - def cmpq256_mask : X86Builtin<"unsigned char(_Vector<4, long long int>, _Vector<4, long long int>, _Constant int, unsigned char)">; -} - -let Features = "avx512vl,avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { - def cmpw256_mask : X86Builtin<"unsigned short(_Vector<16, short>, _Vector<16, short>, _Constant int, unsigned short)">; -} - -let Features = "avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { - def cmpb512_mask : X86Builtin<"unsigned long long int(_Vector<64, char>, _Vector<64, char>, _Constant int, unsigned long long int)">; -} - -let Features = "avx512f", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { - def cmpd512_mask : X86Builtin<"unsigned short(_Vector<16, int>, _Vector<16, int>, _Constant int, unsigned short)">; - def cmpq512_mask : X86Builtin<"unsigned char(_Vector<8, long long int>, _Vector<8, long long int>, _Constant int, unsigned char)">; -} - -let Features = "avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { - def cmpw512_mask : X86Builtin<"unsigned int(_Vector<32, short>, _Vector<32, short>, _Constant int, unsigned int)">; -} - -let Features = "avx512vl,avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { - def ucmpb128_mask : X86Builtin<"unsigned short(_Vector<16, char>, _Vector<16, char>, _Constant int, unsigned short)">; -} - -let Features = "avx512vl", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def ucmpd128_mask : X86Builtin<"unsigned char(_Vector<4, int>, _Vector<4, int>, _Constant int, unsigned char)">; def ucmpq128_mask : X86Builtin<"unsigned char(_Vector<2, long long int>, _Vector<2, long long int>, _Constant int, unsigned char)">; } -let Features = "avx512vl,avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { +let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { + def cmpb128_mask : X86Builtin<"unsigned short(_Vector<16, char>, _Vector<16, char>, _Constant int, unsigned short)">; + def cmpw128_mask : X86Builtin<"unsigned char(_Vector<8, short>, _Vector<8, short>, _Constant int, unsigned char)">; + + def ucmpb128_mask : X86Builtin<"unsigned short(_Vector<16, char>, _Vector<16, char>, _Constant int, unsigned short)">; def ucmpw128_mask : X86Builtin<"unsigned char(_Vector<8, short>, _Vector<8, short>, _Constant int, unsigned char)">; } -let Features = "avx512vl,avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { - def ucmpb256_mask : X86Builtin<"unsigned int(_Vector<32, char>, _Vector<32, char>, _Constant int, unsigned int)">; -} +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { + def cmpd256_mask : X86Builtin<"unsigned char(_Vector<8, int>, _Vector<8, int>, _Constant int, unsigned char)">; + def cmpq256_mask : X86Builtin<"unsigned char(_Vector<4, long long int>, _Vector<4, long long int>, _Constant int, unsigned char)">; -let Features = "avx512vl", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def ucmpd256_mask : X86Builtin<"unsigned char(_Vector<8, int>, _Vector<8, int>, _Constant int, unsigned char)">; def ucmpq256_mask : X86Builtin<"unsigned char(_Vector<4, long long int>, _Vector<4, long long int>, _Constant int, unsigned char)">; } -let Features = "avx512vl,avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { +let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { + def cmpb256_mask : X86Builtin<"unsigned int(_Vector<32, char>, _Vector<32, char>, _Constant int, unsigned int)">; + def cmpw256_mask : X86Builtin<"unsigned short(_Vector<16, short>, _Vector<16, short>, _Constant int, unsigned short)">; + + def ucmpb256_mask : X86Builtin<"unsigned int(_Vector<32, char>, _Vector<32, char>, _Constant int, unsigned int)">; def ucmpw256_mask : X86Builtin<"unsigned short(_Vector<16, short>, _Vector<16, short>, _Constant int, unsigned short)">; } -let Features = "avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { - def ucmpb512_mask : X86Builtin<"unsigned long long int(_Vector<64, char>, _Vector<64, char>, _Constant int, unsigned long long int)">; -} +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { + def cmpd512_mask : X86Builtin<"unsigned short(_Vector<16, int>, _Vector<16, int>, _Constant int, unsigned short)">; + def cmpq512_mask : X86Builtin<"unsigned char(_Vector<8, long long int>, _Vector<8, long long int>, _Constant int, unsigned char)">; -let Features = "avx512f", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def ucmpd512_mask : X86Builtin<"unsigned short(_Vector<16, int>, _Vector<16, int>, _Constant int, unsigned short)">; def ucmpq512_mask : X86Builtin<"unsigned char(_Vector<8, long long int>, _Vector<8, long long int>, _Constant int, unsigned char)">; } -let Features = "avx512bw", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { - def ucmpw512_mask : X86Builtin<"unsigned int(_Vector<32, short>, _Vector<32, short>, _Constant int, unsigned int)">; -} - let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def packsswb512 : X86Builtin<"_Vector<64, char>(_Vector<32, short>, _Vector<32, short>)">; def packssdw512 : X86Builtin<"_Vector<32, short>(_Vector<16, int>, _Vector<16, int>)">; @@ -1386,6 +1282,11 @@ let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVect def packusdw512 : X86Builtin<"_Vector<32, short>(_Vector<16, int>, _Vector<16, int>)">; def pshufb512 : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>)">; + + def cmpb512_mask : X86Builtin<"unsigned long long int(_Vector<64, char>, _Vector<64, char>, _Constant int, unsigned long long int)">; + def cmpw512_mask : X86Builtin<"unsigned int(_Vector<32, short>, _Vector<32, short>, _Constant int, unsigned int)">; + def ucmpb512_mask : X86Builtin<"unsigned long long int(_Vector<64, char>, _Vector<64, char>, _Constant int, unsigned long long int)">; + def ucmpw512_mask : X86Builtin<"unsigned int(_Vector<32, short>, _Vector<32, short>, _Constant int, unsigned int)">; } let Features = "avx512cd,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { @@ -1403,15 +1304,15 @@ let Features = "avx512cd", Attributes = [NoThrow, Const, Constexpr, RequiredVect def vpconflictsi_512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>)">; } -let Features = "avx512vl,avx512bitalg", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512vl,avx512bitalg", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def vpshufbitqmb128_mask : X86Builtin<"unsigned short(_Vector<16, char>, _Vector<16, char>, unsigned short)">; } -let Features = "avx512vl,avx512bitalg", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vl,avx512bitalg", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def vpshufbitqmb256_mask : X86Builtin<"unsigned int(_Vector<32, char>, _Vector<32, char>, unsigned int)">; } -let Features = "avx512bitalg", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512bitalg", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def vpshufbitqmb512_mask : X86Builtin<"unsigned long long int(_Vector<64, char>, _Vector<64, char>, unsigned long long int)">; } @@ -1434,7 +1335,6 @@ let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512> def subps512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, float>, _Constant int)">; } - let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { def addss_round_mask : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Vector<4, float>, unsigned char, _Constant int)">; def divss_round_mask : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Vector<4, float>, unsigned char, _Constant int)">; @@ -1546,9 +1446,12 @@ let Features = "avx512vl", Attributes = [NoThrow, RequiredVectorWidth<256>] in { def compressstoresi256_mask : X86Builtin<"void(_Vector<8, int *>, _Vector<8, int>, unsigned char)">; } +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { + def cvtpd2ps_mask : X86Builtin<"_Vector<4, float>(_Vector<2, double>, _Vector<4, float>, unsigned char)">; +} + let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { def cvtpd2dq128_mask : X86Builtin<"_Vector<4, int>(_Vector<2, double>, _Vector<4, int>, unsigned char)">; - def cvtpd2ps_mask : X86Builtin<"_Vector<4, float>(_Vector<2, double>, _Vector<4, float>, unsigned char)">; def cvtpd2udq128_mask : X86Builtin<"_Vector<4, int>(_Vector<2, double>, _Vector<4, int>, unsigned char)">; } @@ -1765,75 +1668,48 @@ let Features = "avx512vl", Attributes = [NoThrow, RequiredVectorWidth<256>] in { def scattersiv8si : X86Builtin<"void(void *, unsigned char, _Vector<8, int>, _Vector<8, int>, _Constant int)">; } -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def vpermi2vard128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">; -} - -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def vpermi2vard256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; -} - -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def vpermi2vard512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; -} - -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def vpermi2varpd128 : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, long long int>, _Vector<2, double>)">; -} - -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def vpermi2varpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, long long int>, _Vector<4, double>)">; -} - -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def vpermi2varpd512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Vector<8, long long int>, _Vector<8, double>)">; -} - -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def vpermi2varps128 : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, int>, _Vector<4, float>)">; -} - -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def vpermi2varps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, int>, _Vector<8, float>)">; -} - -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def vpermi2varps512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, int>, _Vector<16, float>)">; -} - -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { def vpermi2varq128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>, _Vector<2, long long int>)">; + def vpermi2varps128 : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, int>, _Vector<4, float>)">; + def vpermi2varpd128 : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, long long int>, _Vector<2, double>)">; } -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { + def vpermi2vard256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; def vpermi2varq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>, _Vector<4, long long int>)">; + def vpermi2varps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, int>, _Vector<8, float>)">; + def vpermi2varpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, long long int>, _Vector<4, double>)">; } -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { + def vpermi2vard512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; def vpermi2varq512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<8, long long int>, _Vector<8, long long int>)">; + def vpermi2varps512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, int>, _Vector<16, float>)">; + def vpermi2varpd512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Vector<8, long long int>, _Vector<8, double>)">; } -let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def vpermi2varqi128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>, _Vector<16, char>)">; } -let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def vpermi2varqi256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Vector<32, char>)">; } -let Features = "avx512vbmi", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512vbmi", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def vpermi2varqi512 : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>, _Vector<64, char>)">; } -let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def vpermi2varhi128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>, _Vector<8, short>)">; } -let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def vpermi2varhi256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>, _Vector<16, short>)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def vpermi2varhi512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Vector<32, short>, _Vector<32, short>)">; } @@ -2046,16 +1922,13 @@ let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVect def prorq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Constant int)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def psllw512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Vector<8, short>)">; -} - let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def pmaddubsw512 : X86Builtin<"_Vector<32, short>(_Vector<64, char>, _Vector<64, char>)">; def pmaddwd512 : X86Builtin<"_Vector<16, int>(_Vector<32, short>, _Vector<32, short>)">; def psllv32hi : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Vector<32, short>)">; def pshufhw512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Constant int)">; def pshuflw512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Constant int)">; + def psllw512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Vector<8, short>)">; } let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { @@ -2111,7 +1984,7 @@ let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVect def psravq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def psraw512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Vector<8, short>)">; def psrlw512 @@ -2182,7 +2055,7 @@ let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<128> def vcomiss : X86Builtin<"int(_Vector<4, float>, _Vector<4, float>, _Constant int, _Constant int)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in { def kunpckdi : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">; def kunpcksi : X86Builtin<"unsigned int(unsigned int, unsigned int)">; } @@ -2406,13 +2279,6 @@ let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<128> def vcvttss2usi32 : X86Builtin<"unsigned int(_Vector<4, float>, _Constant int)">; } -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def vpermilpd512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Constant int)">; - def vpermilps512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Constant int)">; - def vpermilvarpd512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Vector<8, long long int>)">; - def vpermilvarps512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, int>)">; -} - let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { def rndscalesd_round_mask : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Vector<2, double>, unsigned char, _Constant int, _Constant int)">; def rndscaless_round_mask : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Vector<4, float>, unsigned char, _Constant int, _Constant int)">; @@ -2435,25 +2301,17 @@ let Features = "avx512f", def psraqi512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, int)">; } -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def psraq128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">; -} - -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def psraq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<2, long long int>)">; -} - -let Features = "avx512vl", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def psraqi128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, int)">; } -let Features = "avx512vl", - Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { + def psraq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<2, long long int>)">; def psraqi256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, int)">; } -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def pslld512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<4, int>)">; def psllq512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<2, long long int>)">; def psrad512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<4, int>)">; @@ -2494,7 +2352,8 @@ let Features = "avx512vl", def pternlogq256_maskz : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>, _Vector<4, long long int>, _Constant int, unsigned char)">; } -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512f", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def shuf_f32x4 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, float>, _Constant int)">; def shuf_f64x2 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Vector<8, double>, _Constant int)">; def shuf_i32x4 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Constant int)">; @@ -2504,9 +2363,18 @@ let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512> let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def shufpd512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Vector<8, double>, _Constant int)">; def shufps512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, float>, _Constant int)">; + def vpermilpd512 + : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Constant int)">; + def vpermilps512 + : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Constant int)">; + def vpermilvarpd512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, " + "_Vector<8, long long int>)">; + def vpermilvarps512 + : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, int>)">; } -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vl", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def shuf_f32x4_256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, _Constant int)">; def shuf_f64x2_256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, double>, _Constant int)">; def shuf_i32x4_256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Constant int)">; @@ -2534,24 +2402,28 @@ let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256 def rsqrt14ps256_mask : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, unsigned char)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512bw", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def cvtb2mask512 : X86Builtin<"unsigned long long int(_Vector<64, char>)">; def cvtmask2b512 : X86Builtin<"_Vector<64, char>(unsigned long long int)">; def cvtmask2w512 : X86Builtin<"_Vector<32, short>(unsigned int)">; } -let Features = "avx512dq", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512dq", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def cvtd2mask512 : X86Builtin<"unsigned short(_Vector<16, int>)">; def cvtmask2d512 : X86Builtin<"_Vector<16, int>(unsigned short)">; def cvtmask2q512 : X86Builtin<"_Vector<8, long long int>(unsigned char)">; def cvtq2mask512 : X86Builtin<"unsigned char(_Vector<8, long long int>)">; } -let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512bw,avx512vl", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def cvtb2mask128 : X86Builtin<"unsigned short(_Vector<16, char>)">; } -let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512bw,avx512vl", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def cvtb2mask256 : X86Builtin<"unsigned int(_Vector<32, char>)">; } @@ -2571,11 +2443,13 @@ let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, RequiredVector def cvtmask2w256 : X86Builtin<"_Vector<16, short>(unsigned short)">; } -let Features = "avx512dq,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512dq,avx512vl", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def cvtd2mask128 : X86Builtin<"unsigned char(_Vector<4, int>)">; } -let Features = "avx512dq,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512dq,avx512vl", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def cvtd2mask256 : X86Builtin<"unsigned char(_Vector<8, int>)">; } @@ -2595,11 +2469,13 @@ let Features = "avx512dq,avx512vl", Attributes = [NoThrow, Const, RequiredVector def cvtmask2q256 : X86Builtin<"_Vector<4, long long int>(unsigned char)">; } -let Features = "avx512dq,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512dq,avx512vl", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def cvtq2mask128 : X86Builtin<"unsigned char(_Vector<2, long long int>)">; } -let Features = "avx512dq,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512dq,avx512vl", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def cvtq2mask256 : X86Builtin<"unsigned char(_Vector<4, long long int>)">; } @@ -3083,38 +2959,38 @@ let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512> def permdi512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Constant int)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def permvarhi512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Vector<32, short>)">; } -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def permvardf512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Vector<8, long long int>)">; def permvardi512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<8, long long int>)">; def permvarsf512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, int>)">; def permvarsi512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; } -let Features = "avx512vbmi", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512vbmi", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def permvarqi512 : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>)">; } -let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def permvarqi128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">; } -let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def permvarqi256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>)">; } -let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def permvarhi128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">; } -let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def permvarhi256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">; } -let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def permvardf256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, long long int>)">; def permvardi256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>)">; } @@ -3194,38 +3070,38 @@ let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in { def kordi : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">; } -let Features = "avx512dq", Attributes = [NoThrow, Const] in { +let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in { def kortestcqi : X86Builtin<"int(unsigned char, unsigned char)">; def kortestzqi : X86Builtin<"int(unsigned char, unsigned char)">; } -let Features = "avx512f", Attributes = [NoThrow, Const] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in { def kortestchi : X86Builtin<"int(unsigned short, unsigned short)">; def kortestzhi : X86Builtin<"int(unsigned short, unsigned short)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in { def kortestcsi : X86Builtin<"int(unsigned int, unsigned int)">; def kortestzsi : X86Builtin<"int(unsigned int, unsigned int)">; def kortestcdi : X86Builtin<"int(unsigned long long int, unsigned long long int)">; def kortestzdi : X86Builtin<"int(unsigned long long int, unsigned long long int)">; } -let Features = "avx512dq", Attributes = [NoThrow, Const] in { +let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in { def ktestcqi : X86Builtin<"int(unsigned char, unsigned char)">; def ktestzqi : X86Builtin<"int(unsigned char, unsigned char)">; def ktestchi : X86Builtin<"int(unsigned short, unsigned short)">; def ktestzhi : X86Builtin<"int(unsigned short, unsigned short)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in { def ktestcsi : X86Builtin<"int(unsigned int, unsigned int)">; def ktestzsi : X86Builtin<"int(unsigned int, unsigned int)">; def ktestcdi : X86Builtin<"int(unsigned long long int, unsigned long long int)">; def ktestzdi : X86Builtin<"int(unsigned long long int, unsigned long long int)">; } -let Features = "avx512f", Attributes = [NoThrow, Const] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in { def kunpckhi : X86Builtin<"unsigned short(unsigned short, unsigned short)">; } @@ -3255,46 +3131,46 @@ let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in { def kxordi : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">; } -let Features = "avx512dq", Attributes = [NoThrow, Const] in { +let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in { def kshiftliqi : X86Builtin<"unsigned char(unsigned char, _Constant unsigned int)">; } -let Features = "avx512f", Attributes = [NoThrow, Const] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in { def kshiftlihi : X86Builtin<"unsigned short(unsigned short, _Constant unsigned int)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in { def kshiftlisi : X86Builtin<"unsigned int(unsigned int, _Constant unsigned int)">; def kshiftlidi : X86Builtin<"unsigned long long int(unsigned long long int, _Constant unsigned int)">; } -let Features = "avx512dq", Attributes = [NoThrow, Const] in { +let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in { def kshiftriqi : X86Builtin<"unsigned char(unsigned char, _Constant unsigned int)">; } -let Features = "avx512f", Attributes = [NoThrow, Const] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in { def kshiftrihi : X86Builtin<"unsigned short(unsigned short, _Constant unsigned int)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in { def kshiftrisi : X86Builtin<"unsigned int(unsigned int, _Constant unsigned int)">; def kshiftridi : X86Builtin<"unsigned long long int(unsigned long long int, _Constant unsigned int)">; } -let Features = "avx512dq", Attributes = [NoThrow, Const] in { +let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in { def kmovb : X86Builtin<"unsigned char(unsigned char)">; } -let Features = "avx512f", Attributes = [NoThrow, Const] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in { def kmovw : X86Builtin<"unsigned short(unsigned short)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in { def kmovd : X86Builtin<"unsigned int(unsigned int)">; def kmovq : X86Builtin<"unsigned long long int(unsigned long long int)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def palignr512 : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>, _Constant int)">; } @@ -3393,34 +3269,36 @@ let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256 def vcvtps2ph256_mask : X86Builtin<"_Vector<8, short>(_Vector<8, float>, _Constant int, _Vector<8, short>, unsigned char)">; } -let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512bw", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def cvtw2mask512 : X86Builtin<"unsigned int(_Vector<32, short>)">; } -let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512bw,avx512vl", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def cvtw2mask128 : X86Builtin<"unsigned char(_Vector<8, short>)">; } -let Features = "avx512bw,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512bw,avx512vl", + Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def cvtw2mask256 : X86Builtin<"unsigned short(_Vector<16, short>)">; } let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def cvtsd2ss_round_mask : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<2, double>, _Vector<4, float>, unsigned char, _Constant int)">; def cvtsi2ss32 : X86Builtin<"_Vector<4, float>(_Vector<4, float>, int, _Constant int)">; def cvtss2sd_round_mask : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<4, float>, _Vector<2, double>, unsigned char, _Constant int)">; def cvtusi2ss32 : X86Builtin<"_Vector<4, float>(_Vector<4, float>, unsigned int, _Constant int)">; } -let Features = "avx512vbmi", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { +let Features = "avx512vbmi", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in { def vpmultishiftqb512 : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>)">; } -let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def vpmultishiftqb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">; } -let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { +let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in { def vpmultishiftqb256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>)">; } @@ -3460,10 +3338,6 @@ let Features = "avx512bf16", Attributes = [NoThrow, Const, RequiredVectorWidth<5 def dpbf16ps_512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<32, __bf16>, _Vector<32, __bf16>)">; } -let Features = "avx512bf16", Attributes = [NoThrow, Const] in { - def cvtsbf162ss_32 : X86Builtin<"float(__bf16)">; -} - let Features = "avx512vp2intersect", Attributes = [NoThrow, RequiredVectorWidth<512>] in { def vp2intersect_q_512 : X86Builtin<"void(_Vector<8, long long int>, _Vector<8, long long int>, unsigned char *, unsigned char *)">; } @@ -3641,14 +3515,6 @@ let Features = "avx512fp16", Attributes = [NoThrow, Const, RequiredVectorWidth<1 def reducesh_mask : X86Builtin<"_Vector<8, _Float16>(_Vector<8, _Float16>, _Vector<8, _Float16>, _Vector<8, _Float16>, unsigned char, _Constant int, _Constant int)">; } -let Features = "avx512fp16,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def sqrtph : X86Builtin<"_Vector<8, _Float16>(_Vector<8, _Float16>)">; -} - -let Features = "avx512fp16,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def sqrtph256 : X86Builtin<"_Vector<16, _Float16>(_Vector<16, _Float16>)">; -} - let Features = "avx512fp16", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { def sqrtph512 : X86Builtin<"_Vector<32, _Float16>(_Vector<32, _Float16>, _Constant int)">; } @@ -4147,15 +4013,15 @@ let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVecto def selectpd_512 : X86Builtin<"_Vector<8, double>(unsigned char, _Vector<8, double>, _Vector<8, double>)">; } -let Features = "avx512fp16", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512fp16", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def selectsh_128 : X86Builtin<"_Vector<8, _Float16>(unsigned char, _Vector<8, _Float16>, _Vector<8, _Float16>)">; } -let Features = "avx512bf16", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512bf16", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def selectsbf_128 : X86Builtin<"_Vector<8, __bf16>(unsigned char, _Vector<8, __bf16>, _Vector<8, __bf16>)">; } -let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { +let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in { def selectss_128 : X86Builtin<"_Vector<4, float>(unsigned char, _Vector<4, float>, _Vector<4, float>)">; def selectsd_128 : X86Builtin<"_Vector<2, double>(unsigned char, _Vector<2, double>, _Vector<2, double>)">; } @@ -4356,12 +4222,12 @@ let Features = "avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<512> } let Features = "avx10.2", Attributes = [NoThrow, RequiredVectorWidth<512>] in { - def vpdpwsud512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; - def vpdpwsuds512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; - def vpdpwusd512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; - def vpdpwusds512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; - def vpdpwuud512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; - def vpdpwuuds512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def vpdpwsud512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, short>, _Vector<32, unsigned short>)">; + def vpdpwsuds512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, short>, _Vector<32, unsigned short>)">; + def vpdpwusd512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, unsigned short>, _Vector<32, short>)">; + def vpdpwusds512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, unsigned short>, _Vector<32, short>)">; + def vpdpwuud512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, unsigned short>, _Vector<32, unsigned short>)">; + def vpdpwuuds512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, unsigned short>, _Vector<32, unsigned short>)">; } let Features = "avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { @@ -4369,51 +4235,51 @@ let Features = "avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<512> } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<128>] in { - def vpdpwsud128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">; + def vpdpwsud128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<8, short>, _Vector<8, unsigned short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<256>] in { - def vpdpwsud256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; + def vpdpwsud256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<16, short>, _Vector<16, unsigned short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<128>] in { - def vpdpwsuds128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">; + def vpdpwsuds128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<8, short>, _Vector<8, unsigned short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<256>] in { - def vpdpwsuds256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; + def vpdpwsuds256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<16, short>, _Vector<16, unsigned short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<128>] in { - def vpdpwusd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">; + def vpdpwusd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<8, unsigned short>, _Vector<8, short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<256>] in { - def vpdpwusd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; + def vpdpwusd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<16, unsigned short>, _Vector<16, short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<128>] in { - def vpdpwusds128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">; + def vpdpwusds128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<8, unsigned short>, _Vector<8, short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<256>] in { - def vpdpwusds256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; + def vpdpwusds256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<16, unsigned short>, _Vector<16, short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<128>] in { - def vpdpwuud128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">; + def vpdpwuud128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<8, unsigned short>, _Vector<8, unsigned short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<256>] in { - def vpdpwuud256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; + def vpdpwuud256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<16, unsigned short>, _Vector<16, unsigned short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<128>] in { - def vpdpwuuds128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">; + def vpdpwuuds128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<8, unsigned short>, _Vector<8, unsigned short>)">; } let Features = "avxvnniint16|avx10.2", Attributes = [NoThrow, RequiredVectorWidth<256>] in { - def vpdpwuuds256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">; + def vpdpwuuds256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<16, unsigned short>, _Vector<16, unsigned short>)">; } let Features = "avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { @@ -5167,15 +5033,3 @@ let Features = "avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<256> let Features = "avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { def vgetmantbf16512_mask : X86Builtin<"_Vector<32, __bf16>(_Vector<32, __bf16>, _Constant int, _Vector<32, __bf16>, unsigned int)">; } - -let Features = "avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in { - def vsqrtbf16 : X86Builtin<"_Vector<8, __bf16>(_Vector<8, __bf16>)">; -} - -let Features = "avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in { - def vsqrtbf16256 : X86Builtin<"_Vector<16, __bf16>(_Vector<16, __bf16>)">; -} - -let Features = "avx10.2", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in { - def vsqrtbf16512 : X86Builtin<"_Vector<32, __bf16>(_Vector<32, __bf16>)">; -} diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 90e1f8d..a059803 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -54,7 +54,7 @@ CODEGENOPT(SeparateNamedSections, 1, 0, Benign) ///< Set for -fseparate-named-se CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0, Benign) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX. CODEGENOPT(XCOFFReadOnlyPointers, 1, 0, Benign) ///< Set for -mxcoff-roptr. CODEGENOPT(AllTocData, 1, 0, Benign) ///< AIX -mtocdata -ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,reserved,none +ENUM_CODEGENOPT(FramePointer, FramePointerKind, 3, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,non-leaf-no-reserve,reserved,none ENUM_CODEGENOPT(ExceptionHandling, ExceptionHandlingKind, 3, ExceptionHandlingKind::None, NotCompatible) @@ -270,6 +270,8 @@ CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0, Benign) ///< Enable use-after-delet CODEGENOPT(SanitizeCfiCrossDso, 1, 0, Benign) ///< Enable cross-dso support in CFI. CODEGENOPT(SanitizeMinimalRuntime, 1, 0, Benign) ///< Use "_minimal" sanitizer runtime for ///< diagnostics. +CODEGENOPT(SanitizeHandlerPreserveAllRegs, 1, 0, Benign) ///< Use "_preserve" sanitizer runtime for + ///< diagnostics. CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0, Benign) ///< Generalize pointer types in ///< CFI icall function signatures CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0, Benign) ///< Normalize integer types in @@ -362,6 +364,8 @@ VALUE_CODEGENOPT(WarnStackSize , 32, UINT_MAX, Benign) ///< Set via -fwarn-s CODEGENOPT(NoStackArgProbe, 1, 0, Benign) ///< Set when -mno-stack-arg-probe is used CODEGENOPT(EmitLLVMUseLists, 1, 0, Benign) ///< Control whether to serialize use-lists. +CODEGENOPT(DevirtualizeSpeculatively, 1, 0, Benign) ///< Whether to apply the speculative + /// devirtualization optimization. CODEGENOPT(WholeProgramVTables, 1, 0, Benign) ///< Whether to apply whole-program /// vtable optimization. diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 5d5cf25..c60ca50 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -21,6 +21,7 @@ #include "llvm/Frontend/Debug/Options.h" #include "llvm/Frontend/Driver/CodeGenOptions.h" #include "llvm/Support/CodeGen.h" +#include "llvm/Support/Hash.h" #include "llvm/Support/Regex.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" @@ -155,10 +156,13 @@ public: std::string BinutilsVersion; enum class FramePointerKind { - None, // Omit all frame pointers. - Reserved, // Maintain valid frame pointer chain. - NonLeaf, // Keep non-leaf frame pointers. - All, // Keep all frame pointers. + NonLeafNoReserve, // Keep non-leaf frame pointers, allow the FP to be used + // as a GPR in leaf functions. + None, // Omit all frame pointers. + Reserved, // Maintain valid frame pointer chain. + NonLeaf, // Keep non-leaf frame pointers, don't allow the FP to be used as a + // GPR in leaf functions. + All, // Keep all frame pointers. }; static StringRef getFramePointerKindName(FramePointerKind Kind) { @@ -167,6 +171,8 @@ public: return "none"; case FramePointerKind::Reserved: return "reserved"; + case FramePointerKind::NonLeafNoReserve: + return "non-leaf-no-reserve"; case FramePointerKind::NonLeaf: return "non-leaf"; case FramePointerKind::All: @@ -509,6 +515,9 @@ public: /// binary metadata pass should not be instrumented. std::vector<std::string> SanitizeMetadataIgnorelistFiles; + /// Hash algorithm to use for KCFI type IDs. + llvm::KCFIHashAlgorithm SanitizeKcfiHash; + /// Name of the stack usage file (i.e., .su file) if user passes /// -fstack-usage. If empty, it can be implied that -fstack-usage is not /// passed on the command line. diff --git a/clang/include/clang/Basic/Cuda.h b/clang/include/clang/Basic/Cuda.h index 81a792d..5639710 100644 --- a/clang/include/clang/Basic/Cuda.h +++ b/clang/include/clang/Basic/Cuda.h @@ -48,6 +48,7 @@ enum class CudaVersion { CUDA_126, CUDA_128, CUDA_129, + CUDA_130, FULLY_SUPPORTED = CUDA_128, PARTIALLY_SUPPORTED = CUDA_129, // Partially supported. Proceed with a warning. diff --git a/clang/include/clang/Basic/DebugOptions.def b/clang/include/clang/Basic/DebugOptions.def index ea3636f..34f5a313 100644 --- a/clang/include/clang/Basic/DebugOptions.def +++ b/clang/include/clang/Basic/DebugOptions.def @@ -65,6 +65,9 @@ DEBUGOPT(DebugKeyInstructions, 1, 0, Benign) DEBUGOPT(DebugColumnInfo, 1, 0, Compatible) ///< Whether or not to use column information ///< in debug info. +/// Whether or not to include call site information in debug info. +DEBUGOPT(DebugCallSiteInfo, 1, 1, Benign) + DEBUGOPT(DebugTypeExtRefs, 1, 0, Compatible) ///< Whether or not debug info should contain ///< external references to a PCH or module. diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index e540040..c6e931d 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -971,7 +971,7 @@ public: /// diagnostics in specific files. /// Mapping file is expected to be a special case list with sections denoting /// diagnostic groups and `src` entries for globs to suppress. `emit` category - /// can be used to disable suppression. Longest glob that matches a filepath + /// can be used to disable suppression. The last glob that matches a filepath /// takes precedence. For example: /// [unused] /// src:clang/* diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 83980e3..aeffe96 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -126,6 +126,9 @@ def err_drv_bad_offload_arch_combo : Error< "invalid offload arch combinations: '%0' and '%1' (for a specific processor, " "a feature should either exist in all offload archs, or not exist in any " "offload archs)">; +def err_drv_unsupported_option_for_offload_arch_req_feature : Error< + "'%0' option for offload arch '%1' is not currently supported " + "there. Use it with an offload arch containing '%2' instead">; def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning< "ignoring '%0' option for offload arch '%1' as it is not currently supported " "there. Use it with an offload arch containing '%2' instead">, @@ -133,6 +136,13 @@ def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning< def warn_drv_unsupported_option_for_target : Warning< "ignoring '%0' option as it is not currently supported for target '%1'">, InGroup<OptionIgnored>; +def err_drv_unsupported_option_for_target : Error< + "'%0' option is not currently supported for target '%1'">; +def warn_drv_unsupported_option_part_for_target : Warning< + "ignoring '%0' in '%1' option as it is not currently supported for target '%2'">, + InGroup<OptionIgnored>; +def err_drv_unsupported_option_part_for_target : Error< + "'%0' in '%1' option is not currently supported for target '%2'">; def warn_drv_invalid_argument_for_flang : Warning< "'%0' is not valid for Fortran">, InGroup<OptionIgnored>; @@ -207,6 +217,9 @@ def err_drv_amdgpu_ieee_without_no_honor_nans : Error< "invalid argument '-mno-amdgpu-ieee' only allowed with relaxed NaN handling">; def err_drv_argument_not_allowed_with : Error< "invalid argument '%0' not allowed with '%1'">; +def warn_drv_argument_not_allowed_with : Warning< + "invalid argument '%0' not allowed with '%1'">, + InGroup<OptionIgnored>; def err_drv_cannot_open_randomize_layout_seed_file : Error< "cannot read randomize layout seed file '%0'">; def err_drv_invalid_version_number : Error< @@ -312,6 +325,8 @@ def warn_drv_yc_multiple_inputs_clang_cl : Warning< def warn_drv_potentially_misspelled_joined_argument : Warning< "joined argument treated as '%0'; did you mean '%1'?">, InGroup<UnknownArgument>; +def err_drv_too_many_actions: Error< + "only one action option is allowed. Got %0">; def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">; def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">; def err_drv_invalid_value_with_suggestion : Error< @@ -836,9 +851,6 @@ def warn_drv_sarif_format_unstable : Warning< "diagnostic formatting in SARIF mode is currently unstable">, InGroup<DiagGroup<"sarif-format-unstable">>; -def err_drv_riscv_unsupported_with_linker_relaxation : Error< - "%0 is unsupported with RISC-V linker relaxation (-mrelax)">; - def warn_drv_loongarch_conflicting_implied_val : Warning< "ignoring '%0' as it conflicts with that implied by '%1' (%2)">, InGroup<OptionIgnored>; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 1e0321d..e9ba362 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -541,6 +541,8 @@ def LifetimeSafety : DiagGroup<"experimental-lifetime-safety", Experimental warnings to detect use-after-free and related temporal safety bugs based on lifetime safety analysis. }]; } +def LifetimeSafetySuggestions + : DiagGroup<"experimental-lifetime-safety-suggestions">; def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">; def DllexportExplicitInstantiationDecl : DiagGroup<"dllexport-explicit-instantiation-decl">; @@ -607,7 +609,6 @@ def MainReturnType : DiagGroup<"main-return-type">; def MaxUnsignedZero : DiagGroup<"max-unsigned-zero">; def MissingBraces : DiagGroup<"missing-braces">; def MissingDeclarations: DiagGroup<"missing-declarations">; -def : DiagGroup<"missing-format-attribute">; def MissingIncludeDirs : DiagGroup<"missing-include-dirs">; def MissingNoreturn : DiagGroup<"missing-noreturn">; def MultiChar : DiagGroup<"multichar">; @@ -790,6 +791,8 @@ def ShadowFieldInConstructor : DiagGroup<"shadow-field-in-constructor", def ShadowIvar : DiagGroup<"shadow-ivar">; def ShadowUncapturedLocal : DiagGroup<"shadow-uncaptured-local">; +def ShadowHeader : DiagGroup<"shadow-header">; + // -Wshadow-all is a catch-all for all shadowing. -Wshadow is just the // shadowing that we think is unsafe. def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified, @@ -1061,6 +1064,7 @@ def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">; def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">; def VariadicMacros : DiagGroup<"variadic-macros">; def VectorConversion : DiagGroup<"vector-conversion">; // clang specific +def MatrixConversion : DiagGroup<"matrix-conversion">; // clang specific def VexingParse : DiagGroup<"vexing-parse">; def VLAUseStaticAssert : DiagGroup<"vla-extension-static-assert">; def VLACxxExtension : DiagGroup<"vla-cxx-extension", [VLAUseStaticAssert]>; @@ -1183,6 +1187,7 @@ def FormatY2K : DiagGroup<"format-y2k">; def FormatPedantic : DiagGroup<"format-pedantic">; def FormatSignedness : DiagGroup<"format-signedness">; def FormatTypeConfusion : DiagGroup<"format-type-confusion">; +def MissingFormatAttribute : DiagGroup<"missing-format-attribute">; def FormatOverflowNonKprintf: DiagGroup<"format-overflow-non-kprintf">; def FormatOverflow: DiagGroup<"format-overflow", [FormatOverflowNonKprintf]>; @@ -1194,7 +1199,7 @@ def Format : DiagGroup<"format", FormatSecurity, FormatY2K, FormatInvalidSpecifier, FormatInsufficientArgs, FormatOverflow, FormatTruncation]>, DiagCategory<"Format String Issue">; -def FormatNonLiteral : DiagGroup<"format-nonliteral">; +def FormatNonLiteral : DiagGroup<"format-nonliteral", [MissingFormatAttribute]>; def Format2 : DiagGroup<"format=2", [FormatNonLiteral, FormatSecurity, FormatY2K]>; @@ -1314,7 +1319,7 @@ def Consumed : DiagGroup<"consumed">; // DefaultIgnore in addition to putting it here. def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool, MisleadingIndentation, PackedNonPod, - VLACxxExtension, PerfConstraintImpliesNoexcept]>; + VLACxxExtension]>; // Warnings that should be in clang-cl /w4. def : DiagGroup<"CL4", [All, Extra]>; @@ -1335,6 +1340,8 @@ def : DiagGroup<"int-conversions", [IntConversion]>; // -Wint-conversions = -Wint-conversion def : DiagGroup<"vector-conversions", [VectorConversion]>; // -Wvector-conversions = -Wvector-conversion +def : DiagGroup<"matrix-conversions", + [MatrixConversion]>; // -Wmatrix-conversions = -Wmatrix-conversion def : DiagGroup<"unused-local-typedefs", [UnusedLocalTypedef]>; // -Wunused-local-typedefs = -Wunused-local-typedef diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 4171872..a72d3f3 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -959,6 +959,10 @@ def warn_quoted_include_in_framework_header : Warning< def warn_framework_include_private_from_public : Warning< "public framework header includes private framework header '%0'" >, InGroup<FrameworkIncludePrivateFromPublic>; +def warn_header_shadowing : Warning< + "multiple candidates for header '%0' found; " + "directory '%1' chosen, ignoring others including '%2'">, + InGroup<ShadowHeader>, DefaultIgnore; def warn_deprecated_module_dot_map : Warning< "'%0' as a module map name is deprecated, rename it to %select{module.modulemap|module.private.modulemap}1%select{| in the 'Modules' directory of the framework}2">, InGroup<DeprecatedModuleDotMap>; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index aa0ccb0..9401377 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1724,6 +1724,10 @@ def warn_omp_invalid_attribute_for_ompx_attributes : Warning<"'ompx_attribute' c "%0 is ignored">, InGroup<OpenMPExtensions>; def err_omp_duplicate_modifier : Error<"duplicate modifier '%0' in '%1' clause">; def err_omp_expected_modifier : Error<"expected modifier in '%0' clause">; +def err_omp_unknown_need_device_ptr_kind + : Error< + "invalid argument for 'need_device_ptr' kind in 'adjust_args' clause; " + "expected 'fp_nullify' or 'fb_preserve'">; // Pragma loop support. def err_pragma_loop_missing_argument : Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fa50953..fec278c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2769,6 +2769,14 @@ def err_deduction_guide_name_not_class_template : Error< "cannot specify deduction guide for " "%select{<error>|function template|variable template|alias template|" "template template parameter|concept|dependent template name}0 %1">; +def err_deduction_guide_target_attr : Error< + "in CUDA/HIP, deduction guides may only be annotated with " + "'__host__ __device__'; '__host__'-only, '__device__'-only, or " + "'__global__' deduction guides are not allowed">; +def warn_deduction_guide_target_attr_deprecated : Warning< + "use of CUDA/HIP target attributes on deduction guides is deprecated; " + "they will be rejected in a future version of Clang">, + InGroup<DeprecatedAttributes>; def err_deduction_guide_wrong_scope : Error< "deduction guide must be declared in the same scope as template %q0">; def err_deduction_guide_defines_function : Error< @@ -3449,6 +3457,24 @@ def err_attribute_integers_only : Error< def warn_attribute_return_pointers_only : Warning< "%0 attribute only applies to return values that are pointers">, InGroup<IgnoredAttributes>; +def warn_attribute_return_span_only + : Warning<"%0 attribute only applies to functions that return span-like " + "structures">, + InGroup<IgnoredAttributes>; +def note_returned_not_struct : Note<"returned type is not a struct type">; +def note_returned_incomplete_type : Note<"returned type is incomplete">; +def note_returned_not_two_field_struct + : Note<"returned struct has %0 fields, expected 2">; +def note_returned_not_span_struct + : Note<"returned struct fields are not a supported combination for a " + "span-like type (expected pointer/integer or pointer/pointer)">; +def note_returned_not_integer_field + : Note<"%ordinal0 field is expected to be an integer">; +def note_returned_not_wide_enough_field + : Note<"%ordinal0 field of span-like type is not a wide enough integer " + "(minimum width: %1)">; +def note_type_inherits_from_base + : Note<"returned type inherits from a base class">; def warn_attribute_return_pointers_refs_only : Warning< "%0 attribute only applies to return values that are pointers or references">, InGroup<IgnoredAttributes>; @@ -3478,6 +3504,10 @@ def err_format_attribute_result_not : Error<"function does not return %0">; def err_format_attribute_implicit_this_format_string : Error< "format attribute cannot specify the implicit this argument as the format " "string">; +def warn_missing_format_attribute : Warning< + "diagnostic behavior may be improved by adding the '%0' attribute to the " + "declaration of %1">, + InGroup<MissingFormatAttribute>, DefaultIgnore; def err_callback_attribute_no_callee : Error< "'callback' attribute specifies no callback callee">; def err_callback_attribute_invalid_callee : Error< @@ -4338,6 +4368,9 @@ def warn_param_typestate_mismatch : Warning< def warn_unknown_sanitizer_ignored : Warning< "unknown sanitizer '%0' ignored">, InGroup<UnknownSanitizers>; +def warn_impcast_matrix_scalar : Warning< + "implicit conversion turns matrix to scalar: %0 to %1">, + InGroup<MatrixConversion>; def warn_impcast_vector_scalar : Warning< "implicit conversion turns vector to scalar: %0 to %1">, InGroup<Conversion>, DefaultIgnore; @@ -7000,8 +7033,9 @@ def warn_counted_by_attr_elt_type_unknown_size : InGroup<BoundsSafetyCountedByEltTyUnknownSize>; // __builtin_counted_by_ref diagnostics: -def err_builtin_counted_by_ref_must_be_flex_array_member : Error< - "'__builtin_counted_by_ref' argument must reference a flexible array member">; +def err_builtin_counted_by_ref_invalid_arg + : Error<"'__builtin_counted_by_ref' argument must reference a member with " + "the 'counted_by' attribute">; def err_builtin_counted_by_ref_has_side_effects : Error< "'__builtin_counted_by_ref' argument cannot have side-effects">; @@ -8116,6 +8150,17 @@ def ext_gnu_ptr_func_arith : Extension< "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 function " "type%select{|s}2 %1%select{| and %3}2 is a GNU extension">, InGroup<GNUPointerArith>; +def ext_gnu_counted_by_void_ptr + : Extension< + "'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' " + "on a pointer to void is a GNU extension, treated as " + "'%select{sized_by|sized_by|sized_by_or_null|sized_by_or_null}0'">, + InGroup<GNUPointerArith>; +def note_gnu_counted_by_void_ptr_use_sized_by + : Note<"use " + "'%select{__sized_by|__sized_by|__sized_by_or_null|__sized_by_or_" + "null}0' " + "to suppress this warning">; def err_readonly_message_assignment : Error< "assigning to 'readonly' return result of an Objective-C message not allowed">; def ext_c2y_increment_complex : Extension< @@ -8632,12 +8677,14 @@ def err_conditional_vector_size : Error< def err_conditional_vector_element_size : Error< "vector condition type %0 and result type %1 do not have elements of the " "same size">; +def err_conditional_vector_scalar_type_unsupported : Error< + "scalar type %0 not supported with vector condition type %1">; def err_conditional_vector_has_void : Error< "GNU vector conditional operand cannot be %select{void|a throw expression}0">; def err_conditional_vector_operand_type : Error<"enumeration type %0 is not allowed in a vector conditional">; def err_conditional_vector_cond_result_mismatch - : Error<"cannot mix vectors and extended vectors in a vector conditional">; + : Error<"cannot mix vectors and %select{sizeless|extended}0 vectors in a vector conditional">; def err_conditional_vector_mismatched : Error<"vector operands to the vector conditional must be the same type " "%diff{($ and $)|}0,1}">; @@ -9501,6 +9548,8 @@ def err_kern_is_nonstatic_method : Error< "kernel function %0 must be a free function or static member function">; def err_config_scalar_return : Error< "CUDA special function '%0' must have scalar return type">; +def err_config_pointer_return + : Error<"CUDA special function '%0' must have pointer return type">; def err_kern_call_not_global_function : Error< "kernel call to non-global function %0">; def err_global_call_not_config : Error< @@ -10733,8 +10782,26 @@ def warn_lifetime_safety_loan_expires_permissive : Warning< def warn_lifetime_safety_loan_expires_strict : Warning< "object whose reference is captured may not live long enough">, InGroup<LifetimeSafetyStrict>, DefaultIgnore; + +def warn_lifetime_safety_return_stack_addr_permissive + : Warning<"address of stack memory is returned later">, + InGroup<LifetimeSafetyPermissive>, + DefaultIgnore; +def warn_lifetime_safety_return_stack_addr_strict + : Warning<"address of stack memory may be returned later">, + InGroup<LifetimeSafetyStrict>, + DefaultIgnore; + def note_lifetime_safety_used_here : Note<"later used here">; def note_lifetime_safety_destroyed_here : Note<"destroyed here">; +def note_lifetime_safety_returned_here : Note<"returned here">; + +def warn_lifetime_safety_suggest_lifetimebound + : Warning<"param should be marked [[clang::lifetimebound]]">, + InGroup<LifetimeSafetySuggestions>, + DefaultIgnore; + +def note_lifetime_safety_suggestion_returned_here : Note<"param returned here">; // For non-floating point, expressions of the form x == x or x != x // should result in a warning, since these always evaluate to a constant. @@ -11230,6 +11297,8 @@ def warn_duplicate_attribute_exact : Warning< def warn_duplicate_attribute : Warning< "attribute %0 is already applied with different arguments">, InGroup<IgnoredAttributes>; +def err_duplicate_attribute + : Error<"attribute %0 is already applied with different arguments">; def err_disallowed_duplicate_attribute : Error< "attribute %0 cannot appear more than once on a declaration">; @@ -12126,6 +12195,9 @@ def err_omp_unexpected_schedule_modifier : Error< "modifier '%0' cannot be used along with modifier '%1'">; def err_omp_schedule_nonmonotonic_static : Error< "'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind">; +def err_omp_incompatible_dyn_groupprivate_modifier + : Error<"modifier '%0' cannot be used along with modifier '%1' in " + "dyn_groupprivate">; def err_omp_simple_clause_incompatible_with_ordered : Error< "'%0' clause with '%1' modifier cannot be specified if an 'ordered' clause is specified">; def err_omp_ordered_simd : Error< @@ -12873,6 +12945,12 @@ def warn_target_clone_duplicate_options def warn_target_clone_no_impact_options : Warning<"version list contains entries that don't impact code generation">, InGroup<FunctionMultiVersioning>; +def warn_version_priority_out_of_range + : Warning<"version priority '%0' is outside the allowed range [1-255]; ignoring priority">, + InGroup<FunctionMultiVersioning>; +def warn_invalid_default_version_priority + : Warning<"priority of default version cannot be overridden; ignoring priority">, + InGroup<FunctionMultiVersioning>; // three-way comparison operator diagnostics def err_implied_comparison_category_type_not_found : Error< @@ -12953,6 +13031,9 @@ def err_builtin_invalid_arg_type: Error< "%plural{0:|: }3" "%plural{[0,3]:type|:types}1 (was %4)">; +def err_bswapg_invalid_bit_width : Error< + "_BitInt type %0 (%1 bits) must be a multiple of 16 bits for byte swapping">; + def err_builtin_trivially_relocate_invalid_arg_type: Error < "first%select{||| and second}0 argument%select{|||s}0 to " "'__builtin_trivially_relocate' must be" @@ -13017,6 +13098,12 @@ def err_get_vtable_pointer_requires_complete_type : Error<"__builtin_get_vtable_pointer requires an argument with a complete " "type, but %0 is incomplete">; +def err_modular_format_attribute_no_format + : Error<"'modular_format' attribute requires 'format' attribute">; + +def err_modular_format_duplicate_aspect + : Error<"duplicate aspect '%0' in 'modular_format' attribute">; + // SYCL-specific diagnostics def warn_sycl_kernel_num_of_template_params : Warning< "'sycl_kernel' attribute only applies to a function template with at least" @@ -13184,6 +13271,13 @@ def err_hlsl_semantic_indexing_not_supported : Error<"semantic %0 does not allow indexing">; def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; +def err_hlsl_semantic_index_overlap : Error<"semantic index overlap %0">; +def err_hlsl_semantic_unsupported_iotype_for_stage + : Error<"semantic %0 is unsupported in %2 shaders as %1, requires one of " + "the following: %3">; +def err_hlsl_semantic_partial_explicit_indexing + : Error<"partial explicit stage input location assignment via " + "vk::location(X) unsupported">; def warn_hlsl_user_defined_type_missing_member: Warning<"binding type '%select{t|u|b|s|c}0' only applies to types containing %select{SRV resources|UAV resources|constant buffer resources|sampler state|numeric types}0">, InGroup<LegacyConstantRegisterBinding>; def err_hlsl_binding_type_mismatch: Error<"binding type '%select{t|u|b|s|c}0' only applies to %select{SRV resources|UAV resources|constant buffer resources|sampler state|numeric variables in the global scope}0">; @@ -13225,7 +13319,10 @@ def err_hlsl_builtin_scalar_vector_mismatch "vector type with matching scalar element type%diff{: $ vs $|}2,3">; def warn_hlsl_impcast_vector_truncation : Warning< - "implicit conversion truncates vector: %0 to %1">, InGroup<Conversion>; + "implicit conversion truncates vector: %0 to %1">, InGroup<VectorConversion>; + +def warn_hlsl_impcast_matrix_truncation : Warning< + "implicit conversion truncates matrix: %0 to %1">, InGroup<MatrixConversion>; def warn_hlsl_availability : Warning< "%0 is only available %select{|in %4 environment }3on %1 %2 or newer">, @@ -13466,21 +13563,19 @@ def err_acc_clause_after_device_type def err_acc_clause_cannot_combine : Error<"OpenACC clause '%0' may not appear on the same construct as a " "'%1' clause on a '%2' construct">; -def err_acc_clause_routine_cannot_combine_before_device_type - : Error<"OpenACC clause '%0' after 'device_type' clause on a 'routine' " - "conflicts with the '%1' clause before the first 'device_type'">; -def err_acc_clause_routine_cannot_combine_same_device_type - : Error<"OpenACC clause '%0' on a 'routine' directive conflicts with the " - "'%1' clause applying to the same 'device_type'">; +def err_acc_clause_cannot_combine_before_device_type + : Error< + "OpenACC clause '%1' after 'device_type' clause on a '%0' construct " + "conflicts with the '%2' clause before the first 'device_type'">; +def err_acc_clause_cannot_combine_same_device_type + : Error<"OpenACC clause '%1' cannot combine with previous '%2' clause" + "%select{| in the same 'device_type' region}3 on a '%0' directive">; +def err_acc_clause_conflicts_prev_dev_type + : Error<"OpenACC '%0' clause applies to 'device_type' '%1', which " + "conflicts with previous '%2' clause">; def err_acc_clause_routine_one_of_in_region : Error<"OpenACC 'routine' construct must have at least one 'gang', 'seq', " "'vector', or 'worker' clause that applies to each 'device_type'">; -def err_acc_clause_since_last_device_type - : Error<"OpenACC '%0' clause cannot appear more than once%select{| in a " - "'device_type' region}2 on a '%1' directive">; -def err_acc_clause_conflicts_prev_dev_type - : Error<"OpenACC '%0' clause applies to 'device_type' '%1', which " - "conflicts with previous '%0' clause">; def err_acc_reduction_num_gangs_conflict : Error<"OpenACC '%1' clause %select{|with more than 1 argument }0may not " @@ -13692,4 +13787,17 @@ def err_amdgcn_load_lds_size_invalid_value : Error<"invalid size value">; def note_amdgcn_load_lds_size_valid_value : Note<"size must be %select{1, 2, or 4|1, 2, 4, 12 or 16}0">; def err_amdgcn_coop_atomic_invalid_as : Error<"cooperative atomic requires a global or generic pointer">; + +def warn_comparison_in_enum_initializer : Warning< + "comparison operator '%0' is potentially a typo for a shift operator '%1'">, + InGroup<DiagGroup<"enum-compare-typo">>; + +def note_enum_compare_typo_suggest : Note< + "use '%0' to perform a bitwise shift">; + +def err_cuda_device_kernel_launch_not_supported + : Error<"device-side kernel call/launch is not supported">; +def err_cuda_device_kernel_launch_require_rdc + : Error<"kernel launch from __device__ or __global__ function requires " + "relocatable device code (i.e. requires -fgpu-rdc)">; } // end of sema component. diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index e4044bc..b27492d 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -46,6 +46,57 @@ class LangOptions; class MultiKeywordSelector; class SourceLocation; +/// Constants for TokenKinds.def +enum TokenKey : unsigned { + KEYC99 = 0x1, + KEYCXX = 0x2, + KEYCXX11 = 0x4, + KEYGNU = 0x8, + KEYMS = 0x10, + BOOLSUPPORT = 0x20, + KEYALTIVEC = 0x40, + KEYNOCXX = 0x80, + KEYBORLAND = 0x100, + KEYOPENCLC = 0x200, + KEYC23 = 0x400, + KEYNOMS18 = 0x800, + KEYNOOPENCL = 0x1000, + WCHARSUPPORT = 0x2000, + HALFSUPPORT = 0x4000, + CHAR8SUPPORT = 0x8000, + KEYOBJC = 0x10000, + KEYZVECTOR = 0x20000, + KEYCOROUTINES = 0x40000, + KEYMODULES = 0x80000, + KEYCXX20 = 0x100000, + KEYOPENCLCXX = 0x200000, + KEYMSCOMPAT = 0x400000, + KEYSYCL = 0x800000, + KEYCUDA = 0x1000000, + KEYZOS = 0x2000000, + KEYNOZOS = 0x4000000, + KEYHLSL = 0x8000000, + KEYFIXEDPOINT = 0x10000000, + KEYMAX = KEYFIXEDPOINT, // The maximum key + KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20, + KEYALL = (KEYMAX | (KEYMAX - 1)) & ~KEYNOMS18 & ~KEYNOOPENCL & + ~KEYNOZOS // KEYNOMS18, KEYNOOPENCL, KEYNOZOS are excluded. +}; + +/// How a keyword is treated in the selected standard. This enum is ordered +/// intentionally so that the value that 'wins' is the most 'permissive'. +enum KeywordStatus { + KS_Unknown, // Not yet calculated. Used when figuring out the status. + KS_Disabled, // Disabled + KS_Future, // Is a keyword in future standard + KS_Extension, // Is an extension + KS_Enabled, // Enabled +}; + +/// Translates flags as specified in TokenKinds.def into keyword status +/// in the given language standard. +KeywordStatus getKeywordStatus(const LangOptions &LangOpts, unsigned Flags); + enum class ReservedIdentifierStatus { NotReserved = 0, StartsWithUnderscoreAtGlobalScope, diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index d3cca82..40fc66e 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -454,7 +454,7 @@ LANGOPT(BranchTargetEnforcement, 1, 0, NotCompatible, "Branch-target enforcement LANGOPT(BranchProtectionPAuthLR, 1, 0, NotCompatible, "Use PC as a diversifier using PAuthLR NOP instructions.") LANGOPT(GuardedControlStack, 1, 0, NotCompatible, "Guarded control stack enabled") -LANGOPT(SpeculativeLoadHardening, 1, 0, NotCompatible, "Speculative load hardening enabled") +LANGOPT(SpeculativeLoadHardening, 1, 0, Benign, "Speculative load hardening enabled") LANGOPT(RelativeCXXABIVTables, 1, 0, NotCompatible, "Use an ABI-incompatible v-table layout that uses relative references") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 8aa89d8..61ee027 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -566,8 +566,8 @@ public: bool AtomicFineGrainedMemory = false; bool AtomicIgnoreDenormalMode = false; - /// Maximum number of allocation tokens (0 = no max), nullopt if none set (use - /// target default). + /// Maximum number of allocation tokens (0 = target SIZE_MAX), nullopt if none + /// set (use target SIZE_MAX). std::optional<uint64_t> AllocTokenMax; /// The allocation token mode. @@ -623,6 +623,8 @@ public: !ObjCSubscriptingLegacyRuntime; } + bool isCompatibleWithMSVC() const { return MSCompatibilityVersion > 0; } + bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const { return MSCompatibilityVersion >= MajorVersion * 100000U; } diff --git a/clang/include/clang/Basic/OffloadArch.h b/clang/include/clang/Basic/OffloadArch.h index befb69f..ea665b1 100644 --- a/clang/include/clang/Basic/OffloadArch.h +++ b/clang/include/clang/Basic/OffloadArch.h @@ -38,6 +38,7 @@ enum class OffloadArch { SM_80, SM_86, SM_87, + SM_88, SM_89, SM_90, SM_90a, @@ -47,6 +48,8 @@ enum class OffloadArch { SM_101a, SM_103, SM_103a, + SM_110, + SM_110a, SM_120, SM_120a, SM_121, diff --git a/clang/include/clang/Basic/OpenCLExtensions.def b/clang/include/clang/Basic/OpenCLExtensions.def index 6f73b26..b0c08b7 100644 --- a/clang/include/clang/Basic/OpenCLExtensions.def +++ b/clang/include/clang/Basic/OpenCLExtensions.def @@ -78,10 +78,55 @@ OPENCL_EXTENSION(cl_khr_depth_images, true, 120) OPENCL_EXTENSION(cl_khr_gl_msaa_sharing,true, 120) // OpenCL 2.0. +OPENCL_EXTENSION(cl_ext_float_atomics, false, 200) +OPENCL_EXTENSION(cl_khr_extended_bit_ops, false, 200) +OPENCL_EXTENSION(cl_khr_integer_dot_product, false, 200) +OPENCL_EXTENSION(cl_khr_kernel_clock, false, 200) OPENCL_EXTENSION(cl_khr_mipmap_image, true, 200) OPENCL_EXTENSION(cl_khr_mipmap_image_writes, true, 200) OPENCL_EXTENSION(cl_khr_srgb_image_writes, true, 200) +OPENCL_EXTENSION(cl_khr_subgroup_ballot, false, 200) +OPENCL_EXTENSION(cl_khr_subgroup_clustered_reduce, false, 200) +OPENCL_EXTENSION(cl_khr_subgroup_extended_types, false, 200) +OPENCL_EXTENSION(cl_khr_subgroup_non_uniform_arithmetic, false, 200) +OPENCL_EXTENSION(cl_khr_subgroup_non_uniform_vote, false, 200) +OPENCL_EXTENSION(cl_khr_subgroup_rotate, false, 200) +OPENCL_EXTENSION(cl_khr_subgroup_shuffle_relative, false, 200) +OPENCL_EXTENSION(cl_khr_subgroup_shuffle, false, 200) OPENCL_EXTENSION(cl_khr_subgroups, true, 200) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_order_acq_rel, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_order_seq_cst, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_scope_all_devices, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_scope_device, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_device_enqueue, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp16_global_atomic_add, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp16_global_atomic_load_store, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp16_global_atomic_min_max, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp16_local_atomic_add, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp16_local_atomic_load_store, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp16_local_atomic_min_max, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp32_global_atomic_add, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp32_global_atomic_min_max, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp32_local_atomic_add, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp32_local_atomic_min_max, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp64_global_atomic_add, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp64_global_atomic_min_max, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp64_local_atomic_add, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_fp64_local_atomic_min_max, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_image_raw10_raw12, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_image_unorm_int_2_101010, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_image_unsigned_10x6_12x4_14x2, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_generic_address_space, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_images, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_integer_dot_product_input_4x8bit, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_integer_dot_product_input_4x8bit_packed, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_kernel_clock_scope_device, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_kernel_clock_scope_sub_group, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_kernel_clock_scope_work_group, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_pipes, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_program_scope_global_variables, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_read_write_images, false, 200, OCL_C_20) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_work_group_collective_functions, false, 200, OCL_C_20) // Clang Extensions. OPENCL_EXTENSION(cl_clang_storage_class_specifiers, true, 100) @@ -95,22 +140,19 @@ OPENCL_EXTENSION(cl_amd_media_ops, true, 100) OPENCL_EXTENSION(cl_amd_media_ops2, true, 100) // Intel OpenCL extensions +OPENCL_EXTENSION(cl_intel_bfloat16_conversion, false, 100) OPENCL_EXTENSION(cl_intel_subgroups, true, 120) +OPENCL_EXTENSION(cl_intel_subgroups_char, true, 120) +OPENCL_EXTENSION(cl_intel_subgroups_long, true, 120) OPENCL_EXTENSION(cl_intel_subgroups_short, true, 120) +OPENCL_EXTENSION(cl_intel_subgroup_buffer_prefetch, false, 120) +OPENCL_EXTENSION(cl_intel_subgroup_local_block_io, false, 120) OPENCL_EXTENSION(cl_intel_device_side_avc_motion_estimation, true, 120) // OpenCL C 3.0 features (6.2.1. Features) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_pipes, false, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_generic_address_space, false, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_order_acq_rel, false, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_order_seq_cst, false, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_subgroups, false, 300, OCL_C_30) OPENCL_OPTIONALCOREFEATURE(__opencl_c_3d_image_writes, false, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_device_enqueue, false, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_read_write_images, false, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_program_scope_global_variables, false, 300, OCL_C_30) OPENCL_OPTIONALCOREFEATURE(__opencl_c_fp64, false, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_images, false, 300, OCL_C_30) +OPENCL_OPTIONALCOREFEATURE(__opencl_c_subgroups, false, 300, OCL_C_30) #undef OPENCL_OPTIONALCOREFEATURE #undef OPENCL_COREFEATURE diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 328a0747..ceac89d 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -86,6 +86,12 @@ #ifndef OPENMP_GRAINSIZE_MODIFIER #define OPENMP_GRAINSIZE_MODIFIER(Name) #endif +#ifndef OPENMP_DYN_GROUPPRIVATE_MODIFIER +#define OPENMP_DYN_GROUPPRIVATE_MODIFIER(Name) +#endif +#ifndef OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER +#define OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER(Name) +#endif #ifndef OPENMP_NUMTASKS_MODIFIER #define OPENMP_NUMTASKS_MODIFIER(Name) #endif @@ -101,6 +107,9 @@ #ifndef OPENMP_THREADSET_KIND #define OPENMP_THREADSET_KIND(Name) #endif +#ifndef OPENMP_NEED_DEVICE_PTR_KIND +#define OPENMP_NEED_DEVICE_PTR_KIND(Name) +#endif // Static attributes for 'schedule' clause. OPENMP_SCHEDULE_KIND(static) @@ -121,7 +130,6 @@ OPENMP_DEVICE_MODIFIER(device_num) // Variable-category attributes for 'default' clause. OPENMP_DEFAULT_VARIABLE_CATEGORY(aggregate) OPENMP_DEFAULT_VARIABLE_CATEGORY(all) -OPENMP_DEFAULT_VARIABLE_CATEGORY(allocatable) OPENMP_DEFAULT_VARIABLE_CATEGORY(pointer) OPENMP_DEFAULT_VARIABLE_CATEGORY(scalar) @@ -199,6 +207,7 @@ OPENMP_MAP_MODIFIER_KIND(ompx_hold) // Modifiers for 'to' or 'from' clause. OPENMP_MOTION_MODIFIER_KIND(mapper) +OPENMP_MOTION_MODIFIER_KIND(iterator) OPENMP_MOTION_MODIFIER_KIND(present) // Static attributes for 'dist_schedule' clause. @@ -242,6 +251,14 @@ OPENMP_BIND_KIND(thread) // Modifiers for the 'grainsize' clause. OPENMP_GRAINSIZE_MODIFIER(strict) +// Modifiers for the 'dyn_groupprivate' clause. +OPENMP_DYN_GROUPPRIVATE_MODIFIER(cgroup) + +// Fallback modifiers for the 'dyn_groupprivate' clause. +OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER(abort) +OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER(null) +OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER(default_mem) + // Modifiers for the 'num_tasks' clause. OPENMP_NUMTASKS_MODIFIER(strict) @@ -261,8 +278,14 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration) OPENMP_THREADSET_KIND(omp_pool) OPENMP_THREADSET_KIND(omp_team) +// OpenMP 6.1 modifiers for 'adjust_args' clause. +OPENMP_NEED_DEVICE_PTR_KIND(fb_nullify) +OPENMP_NEED_DEVICE_PTR_KIND(fb_preserve) + #undef OPENMP_NUMTASKS_MODIFIER #undef OPENMP_NUMTHREADS_MODIFIER +#undef OPENMP_DYN_GROUPPRIVATE_MODIFIER +#undef OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER #undef OPENMP_GRAINSIZE_MODIFIER #undef OPENMP_BIND_KIND #undef OPENMP_ADJUST_ARGS_KIND @@ -291,3 +314,4 @@ OPENMP_THREADSET_KIND(omp_team) #undef OPENMP_DOACROSS_MODIFIER #undef OPENMP_ALLOCATE_MODIFIER #undef OPENMP_THREADSET_KIND +#undef OPENMP_NEED_DEVICE_PTR_KIND diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index c9ddbcd..3b088b3 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -211,6 +211,13 @@ enum OpenMPAdjustArgsOpKind { OMPC_ADJUST_ARGS_unknown, }; +/// OpenMP 6.1 need_device modifier +enum OpenMPNeedDevicePtrModifier { +#define OPENMP_NEED_DEVICE_PTR_KIND(Name) OMPC_NEED_DEVICE_PTR_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_NEED_DEVICE_PTR_unknown, +}; + /// OpenMP bindings for the 'bind' clause. enum OpenMPBindClauseKind { #define OPENMP_BIND_KIND(Name) OMPC_BIND_##Name, @@ -224,6 +231,20 @@ enum OpenMPGrainsizeClauseModifier { OMPC_GRAINSIZE_unknown }; +enum OpenMPDynGroupprivateClauseModifier { +#define OPENMP_DYN_GROUPPRIVATE_MODIFIER(Name) OMPC_DYN_GROUPPRIVATE_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_DYN_GROUPPRIVATE_unknown +}; + +enum OpenMPDynGroupprivateClauseFallbackModifier { + OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown = OMPC_DYN_GROUPPRIVATE_unknown, +#define OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER(Name) \ + OMPC_DYN_GROUPPRIVATE_FALLBACK_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_DYN_GROUPPRIVATE_FALLBACK_last +}; + enum OpenMPNumTasksClauseModifier { #define OPENMP_NUMTASKS_MODIFIER(Name) OMPC_NUMTASKS_##Name, #include "clang/Basic/OpenMPKinds.def" diff --git a/clang/include/clang/Basic/Sarif.h b/clang/include/clang/Basic/Sarif.h index a88d1ee..6f82d25 100644 --- a/clang/include/clang/Basic/Sarif.h +++ b/clang/include/clang/Basic/Sarif.h @@ -325,6 +325,7 @@ class SarifResult { std::string HostedViewerURI; llvm::SmallDenseMap<StringRef, std::string, 4> PartialFingerprints; llvm::SmallVector<CharSourceRange, 8> Locations; + llvm::SmallVector<CharSourceRange, 8> RelatedLocations; llvm::SmallVector<ThreadFlow, 8> ThreadFlows; std::optional<SarifResultLevel> LevelOverride; @@ -354,16 +355,29 @@ public: return *this; } - SarifResult setLocations(llvm::ArrayRef<CharSourceRange> DiagLocs) { + SarifResult addLocations(llvm::ArrayRef<CharSourceRange> DiagLocs) { #ifndef NDEBUG for (const auto &Loc : DiagLocs) { assert(Loc.isCharRange() && "SARIF Results require character granular source ranges!"); } #endif - Locations.assign(DiagLocs.begin(), DiagLocs.end()); + Locations.append(DiagLocs.begin(), DiagLocs.end()); return *this; } + + SarifResult addRelatedLocations(llvm::ArrayRef<CharSourceRange> DiagLocs) { +#ifndef NDEBUG + for (const auto &Loc : DiagLocs) { + assert( + Loc.isCharRange() && + "SARIF RelatedLocations require character granular source ranges!"); + } +#endif + RelatedLocations.append(DiagLocs.begin(), DiagLocs.end()); + return *this; + } + SarifResult setThreadFlows(llvm::ArrayRef<ThreadFlow> ThreadFlowResults) { ThreadFlows.assign(ThreadFlowResults.begin(), ThreadFlowResults.end()); return *this; diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index ed967fd..bc9e978 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -1286,16 +1286,7 @@ public: /// If the location is an expansion record, walk through it until we find /// the final location expanded. FileIDAndOffset getDecomposedExpansionLoc(SourceLocation Loc) const { - FileID FID = getFileID(Loc); - auto *E = getSLocEntryOrNull(FID); - if (!E) - return std::make_pair(FileID(), 0); - - unsigned Offset = Loc.getOffset()-E->getOffset(); - if (Loc.isFileID()) - return std::make_pair(FID, Offset); - - return getDecomposedExpansionLocSlowCase(E); + return getDecomposedLoc(getExpansionLoc(Loc)); } /// Decompose the specified location into a raw FileID + Offset pair. @@ -1303,15 +1294,7 @@ public: /// If the location is an expansion record, walk through it until we find /// its spelling record. FileIDAndOffset getDecomposedSpellingLoc(SourceLocation Loc) const { - FileID FID = getFileID(Loc); - auto *E = getSLocEntryOrNull(FID); - if (!E) - return std::make_pair(FileID(), 0); - - unsigned Offset = Loc.getOffset()-E->getOffset(); - if (Loc.isFileID()) - return std::make_pair(FID, Offset); - return getDecomposedSpellingLocSlowCase(E, Offset); + return getDecomposedLoc(getSpellingLoc(Loc)); } /// Returns the "included/expanded in" decomposed location of the given @@ -1426,10 +1409,15 @@ public: /// before calling this method. unsigned getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid = nullptr) const; + unsigned getColumnNumber(SourceLocation Loc, bool *Invalid = nullptr) const; unsigned getSpellingColumnNumber(SourceLocation Loc, - bool *Invalid = nullptr) const; + bool *Invalid = nullptr) const { + return getColumnNumber(getSpellingLoc(Loc), Invalid); + } unsigned getExpansionColumnNumber(SourceLocation Loc, - bool *Invalid = nullptr) const; + bool *Invalid = nullptr) const { + return getColumnNumber(getExpansionLoc(Loc), Invalid); + } unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid = nullptr) const; @@ -1440,8 +1428,15 @@ public: /// MemoryBuffer, so this is not cheap: use only when about to emit a /// diagnostic. unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = nullptr) const; - unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const; - unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const; + unsigned getLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const; + unsigned getSpellingLineNumber(SourceLocation Loc, + bool *Invalid = nullptr) const { + return getLineNumber(getSpellingLoc(Loc), Invalid); + } + unsigned getExpansionLineNumber(SourceLocation Loc, + bool *Invalid = nullptr) const { + return getLineNumber(getExpansionLoc(Loc), Invalid); + } unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const; /// Return the filename or buffer identifier of the buffer the @@ -1979,10 +1974,6 @@ private: SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const; SourceLocation getFileLocSlowCase(SourceLocation Loc) const; - FileIDAndOffset - getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const; - FileIDAndOffset getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, - unsigned Offset) const; void computeMacroArgsCache(MacroArgsMap &MacroArgsCache, FileID FID) const; void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache, FileID FID, diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 9bd5143..d5e8299f 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -397,7 +397,9 @@ namespace clang { } bool isOverloadDefault() const { return !(Flags & OverloadKindMask); } bool isOverloadWhileRW() const { return Flags & IsOverloadWhileRW; } - bool isOverloadCvt() const { return Flags & IsOverloadCvt; } + bool isOverloadFirstandLast() const { + return Flags & IsOverloadFirstandLast; + } bool isPrefetch() const { return Flags & IsPrefetch; } bool isReverseCompare() const { return Flags & ReverseCompare; } bool isAppendSVALL() const { return Flags & IsAppendSVALL; } diff --git a/clang/include/clang/Basic/TargetID.h b/clang/include/clang/Basic/TargetID.h index cef9cb5f..902151d 100644 --- a/clang/include/clang/Basic/TargetID.h +++ b/clang/include/clang/Basic/TargetID.h @@ -56,6 +56,11 @@ getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs); /// Check whether the provided target ID is compatible with the requested /// target ID. bool isCompatibleTargetID(llvm::StringRef Provided, llvm::StringRef Requested); + +/// Sanitize a target ID string for use in a file name. +/// Replaces invalid characters (like ':') with safe characters (like '@'). +/// Currently only replaces ':' with '@' on Windows. +std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID); } // namespace clang #endif diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index ea73ed9..885325c 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -229,6 +229,7 @@ class TargetInfo : public TransferrableTargetInfo, protected: // Target values set by the ctor of the actual target implementation. Default // values are specified by the TargetInfo constructor. + bool HasMustTail; bool BigEndian; bool TLSSupported; bool VLASupported; @@ -295,9 +296,11 @@ protected: // TargetInfo Constructor. Default initializes all fields. TargetInfo(const llvm::Triple &T); - // UserLabelPrefix must match DL's getGlobalPrefix() when interpreted - // as a DataLayout object. - void resetDataLayout(StringRef DL, const char *UserLabelPrefix = ""); + /// Set the data layout to the given string. + void resetDataLayout(StringRef DL); + + /// Set the data layout based on current triple and ABI. + void resetDataLayout(); // Target features that are read-only and should not be disabled/enabled // by command line options. Such features are for emitting predefined @@ -669,6 +672,8 @@ public: : getLongFractScale() + 1; } + virtual bool hasMustTail() const { return HasMustTail; } + /// Determine whether the __int128 type is supported on this target. virtual bool hasInt128Type() const { return (getPointerWidth(LangAS::Default) >= 64) || @@ -1845,6 +1850,9 @@ public: } } + /// Set features that depend on other features. + virtual void setDependentOpenCLOpts(); + /// Get supported OpenCL extensions and optional core features. llvm::StringMap<bool> &getSupportedOpenCLOpts() { return getTargetOpts().OpenCLFeaturesMap; diff --git a/clang/include/clang/Basic/TokenKinds.h b/clang/include/clang/Basic/TokenKinds.h index d84f359..a801113 100644 --- a/clang/include/clang/Basic/TokenKinds.h +++ b/clang/include/clang/Basic/TokenKinds.h @@ -98,7 +98,7 @@ inline bool isLiteral(TokenKind K) { const bool isInLiteralRange = K >= tok::numeric_constant && K <= tok::utf32_string_literal; -#if !NDEBUG +#ifndef NDEBUG const bool isLiteralExplicit = K == tok::numeric_constant || K == tok::char_constant || K == tok::wide_char_constant || K == tok::utf8_char_constant || diff --git a/clang/include/clang/Basic/arm_mve.td b/clang/include/clang/Basic/arm_mve.td index 2e5e1d9..77531c3 100644 --- a/clang/include/clang/Basic/arm_mve.td +++ b/clang/include/clang/Basic/arm_mve.td @@ -167,7 +167,9 @@ multiclass FMA<bit add> { // second multiply input. defvar m2_cg = !if(add, (id $m2), (fneg $m2)); - defvar unpred_cg = (IRIntBase<"fma", [Vector]> $m1, m2_cg, $addend); + defvar fma = strictFPAlt<IRIntBase<"fma", [Vector]>, + IRInt<"fma", [Vector]>>; + defvar unpred_cg = (fma $m1, m2_cg, $addend); defvar pred_cg = (IRInt<"fma_predicated", [Vector, Predicate]> $m1, m2_cg, $addend, $pred); @@ -723,7 +725,7 @@ multiclass compare_with_pred<string condname, dag arguments, NameOverride<"vcmp" # condname # "q_m" # suffix>; } -multiclass compare<string condname, IRBuilder cmpop> { +multiclass compare<string condname, Builder cmpop> { // Make all four variants of a comparison: the vector/vector and // vector/scalar forms, each using compare_with_pred to make a // predicated and unpredicated version. @@ -781,15 +783,15 @@ let params = T.Unsigned in { } let params = T.Float in { def vminnmq: Intrinsic<Vector, (args Vector:$a, Vector:$b), - (IRIntBase<"minnum", [Vector]> $a, $b)>; + (fminnm $a, $b)>; def vmaxnmq: Intrinsic<Vector, (args Vector:$a, Vector:$b), - (IRIntBase<"maxnum", [Vector]> $a, $b)>; + (fmaxnm $a, $b)>; def vminnmaq: Intrinsic<Vector, (args Vector:$a, Vector:$b), - (IRIntBase<"minnum", [Vector]> + (fminnm (IRIntBase<"fabs", [Vector]> $a), (IRIntBase<"fabs", [Vector]> $b))>; def vmaxnmaq: Intrinsic<Vector, (args Vector:$a, Vector:$b), - (IRIntBase<"maxnum", [Vector]> + (fmaxnm (IRIntBase<"fabs", [Vector]> $a), (IRIntBase<"fabs", [Vector]> $b))>; } diff --git a/clang/include/clang/Basic/arm_mve_defs.td b/clang/include/clang/Basic/arm_mve_defs.td index c1562a0..3210549 100644 --- a/clang/include/clang/Basic/arm_mve_defs.td +++ b/clang/include/clang/Basic/arm_mve_defs.td @@ -34,7 +34,8 @@ class IRBuilderAddrParam<int index_> : IRBuilderParam<index_>; class IRBuilderIntParam<int index_, string type_> : IRBuilderParam<index_> { string type = type_; } -class IRBuilderBase { +class Builder {} +class IRBuilderBase : Builder { // The prefix of the function call, including an open parenthesis. string prefix; @@ -74,9 +75,9 @@ def immshr: CGHelperFn<"MVEImmediateShr"> { let special_params = [IRBuilderIntParam<1, "unsigned">, IRBuilderIntParam<2, "bool">]; } -def fadd: IRBuilder<"CreateFAdd">; -def fmul: IRBuilder<"CreateFMul">; -def fsub: IRBuilder<"CreateFSub">; +def fadd_node: IRBuilder<"CreateFAdd">; +def fmul_node: IRBuilder<"CreateFMul">; +def fsub_node: IRBuilder<"CreateFSub">; def load: IRBuilder<"CreateLoad"> { let special_params = [IRBuilderAddrParam<0>]; } @@ -166,7 +167,7 @@ def address; // Another node class you can use in the codegen dag. This one corresponds to // an IR intrinsic function, which has to be specialized to a particular list // of types. -class IRIntBase<string name_, list<Type> params_ = [], bit appendKind_ = 0> { +class IRIntBase<string name_, list<Type> params_ = [], bit appendKind_ = 0> : Builder { string intname = name_; // base name of the intrinsic list<Type> params = params_; // list of parameter types @@ -212,6 +213,13 @@ def unsignedflag; // constant giving its size in bits. def bitsize; +// strictFPAlt allows a node to have different code generation under strict-fp. +// TODO: The standard node can be IRBuilderBase or IRIntBase. +class strictFPAlt<Builder standard_, IRIntBase strictfp_> : Builder { + Builder standard = standard_; + IRIntBase strictfp = strictfp_; +} + // If you put CustomCodegen<"foo"> in an intrinsic's codegen field, it // indicates that the IR generation for that intrinsic is done by handwritten // C++ and not autogenerated at all. The effect in the MVE builtin codegen @@ -573,6 +581,18 @@ multiclass IntrinsicMXNameOverride<Type rettype, dag arguments, dag cg, } } +// StrictFP nodes that choose between standard fadd and llvm.arm.mve.fadd nodes +// depending on whether we are using strict-fp. +def fadd: strictFPAlt<fadd_node, + IRInt<"vadd", [Vector]>>; +def fsub: strictFPAlt<fsub_node, + IRInt<"vsub", [Vector]>>; +def fmul: strictFPAlt<fmul_node, + IRInt<"vmul", [Vector]>>; +def fminnm : strictFPAlt<IRIntBase<"minnum", [Vector]>, + IRInt<"vminnm", [Vector]>>; +def fmaxnm : strictFPAlt<IRIntBase<"maxnum", [Vector]>, + IRInt<"vmaxnm", [Vector]>>; // ----------------------------------------------------------------------------- // Convenience lists of parameter types. 'T' is just a container record, so you diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td index ef19610..e91d7ce 100644 --- a/clang/include/clang/Basic/arm_neon.td +++ b/clang/include/clang/Basic/arm_neon.td @@ -1466,26 +1466,51 @@ def SCALAR_UCVTFD : SInst<"vcvt_f64", "(1F)(1!)", "SUl">; //////////////////////////////////////////////////////////////////////////////// // Scalar Floating-point Converts def SCALAR_FCVTXN : IInst<"vcvtx_f32", "(1F<)(1!)", "Sd">; -def SCALAR_FCVTNSS : SInst<"vcvtn_s32", "(1S)1", "Sf">; -def SCALAR_FCVTNUS : SInst<"vcvtn_u32", "(1U)1", "Sf">; -def SCALAR_FCVTNSD : SInst<"vcvtn_s64", "(1S)1", "Sd">; -def SCALAR_FCVTNUD : SInst<"vcvtn_u64", "(1U)1", "Sd">; -def SCALAR_FCVTMSS : SInst<"vcvtm_s32", "(1S)1", "Sf">; -def SCALAR_FCVTMUS : SInst<"vcvtm_u32", "(1U)1", "Sf">; -def SCALAR_FCVTMSD : SInst<"vcvtm_s64", "(1S)1", "Sd">; -def SCALAR_FCVTMUD : SInst<"vcvtm_u64", "(1U)1", "Sd">; -def SCALAR_FCVTASS : SInst<"vcvta_s32", "(1S)1", "Sf">; -def SCALAR_FCVTAUS : SInst<"vcvta_u32", "(1U)1", "Sf">; -def SCALAR_FCVTASD : SInst<"vcvta_s64", "(1S)1", "Sd">; -def SCALAR_FCVTAUD : SInst<"vcvta_u64", "(1U)1", "Sd">; -def SCALAR_FCVTPSS : SInst<"vcvtp_s32", "(1S)1", "Sf">; -def SCALAR_FCVTPUS : SInst<"vcvtp_u32", "(1U)1", "Sf">; -def SCALAR_FCVTPSD : SInst<"vcvtp_s64", "(1S)1", "Sd">; -def SCALAR_FCVTPUD : SInst<"vcvtp_u64", "(1U)1", "Sd">; -def SCALAR_FCVTZSS : SInst<"vcvt_s32", "(1S)1", "Sf">; -def SCALAR_FCVTZUS : SInst<"vcvt_u32", "(1U)1", "Sf">; -def SCALAR_FCVTZSD : SInst<"vcvt_s64", "(1S)1", "Sd">; -def SCALAR_FCVTZUD : SInst<"vcvt_u64", "(1U)1", "Sd">; + +def SCALAR_FCVTN_F32toSS : SInst<"vcvtn_s32", "(1S)1", "Sf">; +def SCALAR_FCVTN_F32toUS : SInst<"vcvtn_u32", "(1U)1", "Sf">; +def SCALAR_FCVTN_F64toSS : SInst<"vcvtn_s32", "(1S<)1", "Sd">; +def SCALAR_FCVTN_F64toUS : SInst<"vcvtn_u32", "(1U<)1", "Sd">; +def SCALAR_FCVTN_F32toSD : SInst<"vcvtn_s64", "(1S>)1", "Sf">; +def SCALAR_FCVTN_F32toUD : SInst<"vcvtn_u64", "(1U>)1", "Sf">; +def SCALAR_FCVTN_F64toSD : SInst<"vcvtn_s64", "(1S)1", "Sd">; +def SCALAR_FCVTN_F64toUD : SInst<"vcvtn_u64", "(1U)1", "Sd">; + +def SCALAR_FCVTM_F32toSS : SInst<"vcvtm_s32", "(1S)1", "Sf">; +def SCALAR_FCVTM_F32toUS : SInst<"vcvtm_u32", "(1U)1", "Sf">; +def SCALAR_FCVTM_F64toSS : SInst<"vcvtm_s32", "(1S<)1", "Sd">; +def SCALAR_FCVTM_F64toUS : SInst<"vcvtm_u32", "(1U<)1", "Sd">; +def SCALAR_FCVTM_F32toSD : SInst<"vcvtm_s64", "(1S>)1", "Sf">; +def SCALAR_FCVTM_F32toUD : SInst<"vcvtm_u64", "(1U>)1", "Sf">; +def SCALAR_FCVTM_F64toSD : SInst<"vcvtm_s64", "(1S)1", "Sd">; +def SCALAR_FCVTM_F64toUD : SInst<"vcvtm_u64", "(1U)1", "Sd">; + +def SCALAR_FCVTA_F32toSS : SInst<"vcvta_s32", "(1S)1", "Sf">; +def SCALAR_FCVTA_F32toUS : SInst<"vcvta_u32", "(1U)1", "Sf">; +def SCALAR_FCVTA_F64toSS : SInst<"vcvta_s32", "(1S<)1", "Sd">; +def SCALAR_FCVTA_F64toUS : SInst<"vcvta_u32", "(1U<)1", "Sd">; +def SCALAR_FCVTA_F32toSD : SInst<"vcvta_s64", "(1S>)1", "Sf">; +def SCALAR_FCVTA_F32toUD : SInst<"vcvta_u64", "(1U>)1", "Sf">; +def SCALAR_FCVTA_F64toSD : SInst<"vcvta_s64", "(1S)1", "Sd">; +def SCALAR_FCVTA_F64toUD : SInst<"vcvta_u64", "(1U)1", "Sd">; + +def SCALAR_FCVTP_F32toSS : SInst<"vcvtp_s32", "(1S)1", "Sf">; +def SCALAR_FCVTP_F32toUS : SInst<"vcvtp_u32", "(1U)1", "Sf">; +def SCALAR_FCVTP_F64toSS : SInst<"vcvtp_s32", "(1S<)1", "Sd">; +def SCALAR_FCVTP_F64toUS : SInst<"vcvtp_u32", "(1U<)1", "Sd">; +def SCALAR_FCVTP_F32toSD : SInst<"vcvtp_s64", "(1S>)1", "Sf">; +def SCALAR_FCVTP_F32toUD : SInst<"vcvtp_u64", "(1U>)1", "Sf">; +def SCALAR_FCVTP_F64toSD : SInst<"vcvtp_s64", "(1S)1", "Sd">; +def SCALAR_FCVTP_F64toUD : SInst<"vcvtp_u64", "(1U)1", "Sd">; + +def SCALAR_FCVTZ_F32toSS : SInst<"vcvt_s32", "(1S)1", "Sf">; +def SCALAR_FCVTZ_F32toUS : SInst<"vcvt_u32", "(1U)1", "Sf">; +def SCALAR_FCVTZ_F64toSS : SInst<"vcvt_s32", "(1S<)1", "Sd">; +def SCALAR_FCVTZ_F64toUS : SInst<"vcvt_u32", "(1U<)1", "Sd">; +def SCALAR_FCVTZ_F32toSD : SInst<"vcvt_s64", "(1S>)1", "Sf">; +def SCALAR_FCVTZ_F32toUD : SInst<"vcvt_u64", "(1U>)1", "Sf">; +def SCALAR_FCVTZ_F64toSD : SInst<"vcvt_s64", "(1S)1", "Sd">; +def SCALAR_FCVTZ_F64toUD : SInst<"vcvt_u64", "(1U)1", "Sd">; //////////////////////////////////////////////////////////////////////////////// // Scalar Floating-point Reciprocal Estimate @@ -1896,6 +1921,14 @@ let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "f def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "(F>)(F>)F(FQ)I", "hQh", OP_FMLSL_LN_Hi>; } +let ArchGuard = "defined(__aarch64__)", TargetGuard = "f8f16mm,neon" in { + def VMMLA_F16_MF8 : VInst<"vmmla_f16_mf8_fpm", "(>F)(>F)..V", "Qm">; +} + +let ArchGuard = "defined(__aarch64__)", TargetGuard = "f8f32mm,neon" in { + def VMMLA_F32_MF8 : VInst<"vmmla_f32_mf8_fpm", "(>>F)(>>F)..V", "Qm">; +} + let TargetGuard = "i8mm,neon" in { def VMMLA : SInst<"vmmla", "..(<<)(<<)", "QUiQi">; def VUSMMLA : SInst<"vusmmla", "..(<<U)(<<)", "Qi">; diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index d2b7b78b..ed41b43 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -883,56 +883,56 @@ multiclass SInstCvtMX<string name, string m_types, string xz_types, } // svcvt_s##_f16 -defm SVFCVTZS_S16_F16 : SInstCvtMXZ<"svcvt_s16[_f16]", "ddPO", "dPO", "s", "aarch64_sve_fcvtzs", [IsOverloadCvt]>; +defm SVFCVTZS_S16_F16 : SInstCvtMXZ<"svcvt_s16[_f16]", "ddPO", "dPO", "s", "aarch64_sve_fcvtzs", [IsOverloadFirstandLast]>; defm SVFCVTZS_S32_F16 : SInstCvtMXZ<"svcvt_s32[_f16]", "ddPO", "dPO", "i", "aarch64_sve_fcvtzs_i32f16">; defm SVFCVTZS_S64_F16 : SInstCvtMXZ<"svcvt_s64[_f16]", "ddPO", "dPO", "l", "aarch64_sve_fcvtzs_i64f16">; // svcvt_s##_f32 -defm SVFCVTZS_S32_F32 : SInstCvtMXZ<"svcvt_s32[_f32]", "ddPM", "dPM", "i", "aarch64_sve_fcvtzs", [IsOverloadCvt]>; +defm SVFCVTZS_S32_F32 : SInstCvtMXZ<"svcvt_s32[_f32]", "ddPM", "dPM", "i", "aarch64_sve_fcvtzs", [IsOverloadFirstandLast]>; defm SVFCVTZS_S64_F32 : SInstCvtMXZ<"svcvt_s64[_f32]", "ddPM", "dPM", "l", "aarch64_sve_fcvtzs_i64f32">; // svcvt_s##_f64 defm SVFCVTZS_S32_F64 : SInstCvtMXZ<"svcvt_s32[_f64]", "ttPd", "tPd", "d", "aarch64_sve_fcvtzs_i32f64">; -defm SVFCVTZS_S64_F64 : SInstCvtMXZ<"svcvt_s64[_f64]", "ddPN", "dPN", "l", "aarch64_sve_fcvtzs", [IsOverloadCvt]>; +defm SVFCVTZS_S64_F64 : SInstCvtMXZ<"svcvt_s64[_f64]", "ddPN", "dPN", "l", "aarch64_sve_fcvtzs", [IsOverloadFirstandLast]>; // svcvt_u##_f16 -defm SVFCVTZU_U16_F16 : SInstCvtMXZ<"svcvt_u16[_f16]", "ddPO", "dPO", "Us", "aarch64_sve_fcvtzu", [IsOverloadCvt]>; +defm SVFCVTZU_U16_F16 : SInstCvtMXZ<"svcvt_u16[_f16]", "ddPO", "dPO", "Us", "aarch64_sve_fcvtzu", [IsOverloadFirstandLast]>; defm SVFCVTZU_U32_F16 : SInstCvtMXZ<"svcvt_u32[_f16]", "ddPO", "dPO", "Ui", "aarch64_sve_fcvtzu_i32f16">; defm SVFCVTZU_U64_F16 : SInstCvtMXZ<"svcvt_u64[_f16]", "ddPO", "dPO", "Ul", "aarch64_sve_fcvtzu_i64f16">; // svcvt_u##_f32 -defm SVFCVTZU_U32_F32 : SInstCvtMXZ<"svcvt_u32[_f32]", "ddPM", "dPM", "Ui", "aarch64_sve_fcvtzu", [IsOverloadCvt]>; +defm SVFCVTZU_U32_F32 : SInstCvtMXZ<"svcvt_u32[_f32]", "ddPM", "dPM", "Ui", "aarch64_sve_fcvtzu", [IsOverloadFirstandLast]>; defm SVFCVTZU_U64_F32 : SInstCvtMXZ<"svcvt_u64[_f32]", "ddPM", "dPM", "Ul", "aarch64_sve_fcvtzu_i64f32">; // svcvt_u##_f64 defm SVFCVTZU_U32_F64 : SInstCvtMXZ<"svcvt_u32[_f64]", "zzPd", "zPd", "d", "aarch64_sve_fcvtzu_i32f64">; -defm SVFCVTZU_U64_F64 : SInstCvtMXZ<"svcvt_u64[_f64]", "ddPN", "dPN", "Ul", "aarch64_sve_fcvtzu", [IsOverloadCvt]>; +defm SVFCVTZU_U64_F64 : SInstCvtMXZ<"svcvt_u64[_f64]", "ddPN", "dPN", "Ul", "aarch64_sve_fcvtzu", [IsOverloadFirstandLast]>; // svcvt_f16_s## -defm SVFCVTZS_F16_S16 : SInstCvtMXZ<"svcvt_f16[_s16]", "OOPd", "OPd", "s", "aarch64_sve_scvtf", [IsOverloadCvt]>; +defm SVFCVTZS_F16_S16 : SInstCvtMXZ<"svcvt_f16[_s16]", "OOPd", "OPd", "s", "aarch64_sve_scvtf", [IsOverloadFirstandLast]>; defm SVFCVTZS_F16_S32 : SInstCvtMXZ<"svcvt_f16[_s32]", "OOPd", "OPd", "i", "aarch64_sve_scvtf_f16i32">; defm SVFCVTZS_F16_S64 : SInstCvtMXZ<"svcvt_f16[_s64]", "OOPd", "OPd", "l", "aarch64_sve_scvtf_f16i64">; // svcvt_f32_s## -defm SVFCVTZS_F32_S32 : SInstCvtMXZ<"svcvt_f32[_s32]", "MMPd", "MPd", "i", "aarch64_sve_scvtf", [IsOverloadCvt]>; +defm SVFCVTZS_F32_S32 : SInstCvtMXZ<"svcvt_f32[_s32]", "MMPd", "MPd", "i", "aarch64_sve_scvtf", [IsOverloadFirstandLast]>; defm SVFCVTZS_F32_S64 : SInstCvtMXZ<"svcvt_f32[_s64]", "MMPd", "MPd", "l", "aarch64_sve_scvtf_f32i64">; // svcvt_f64_s## defm SVFCVTZS_F64_S32 : SInstCvtMXZ<"svcvt_f64[_s32]", "ddPt", "dPt", "d", "aarch64_sve_scvtf_f64i32">; -defm SVFCVTZS_F64_S64 : SInstCvtMXZ<"svcvt_f64[_s64]", "NNPd", "NPd", "l", "aarch64_sve_scvtf", [IsOverloadCvt]>; +defm SVFCVTZS_F64_S64 : SInstCvtMXZ<"svcvt_f64[_s64]", "NNPd", "NPd", "l", "aarch64_sve_scvtf", [IsOverloadFirstandLast]>; // svcvt_f16_u## -defm SVFCVTZU_F16_U16 : SInstCvtMXZ<"svcvt_f16[_u16]", "OOPd", "OPd", "Us", "aarch64_sve_ucvtf", [IsOverloadCvt]>; +defm SVFCVTZU_F16_U16 : SInstCvtMXZ<"svcvt_f16[_u16]", "OOPd", "OPd", "Us", "aarch64_sve_ucvtf", [IsOverloadFirstandLast]>; defm SVFCVTZU_F16_U32 : SInstCvtMXZ<"svcvt_f16[_u32]", "OOPd", "OPd", "Ui", "aarch64_sve_ucvtf_f16i32">; defm SVFCVTZU_F16_U64 : SInstCvtMXZ<"svcvt_f16[_u64]", "OOPd", "OPd", "Ul", "aarch64_sve_ucvtf_f16i64">; // svcvt_f32_u## -defm SVFCVTZU_F32_U32 : SInstCvtMXZ<"svcvt_f32[_u32]", "MMPd", "MPd", "Ui", "aarch64_sve_ucvtf", [IsOverloadCvt]>; +defm SVFCVTZU_F32_U32 : SInstCvtMXZ<"svcvt_f32[_u32]", "MMPd", "MPd", "Ui", "aarch64_sve_ucvtf", [IsOverloadFirstandLast]>; defm SVFCVTZU_F32_U64 : SInstCvtMXZ<"svcvt_f32[_u64]", "MMPd", "MPd", "Ul", "aarch64_sve_ucvtf_f32i64">; // svcvt_f64_u## defm SVFCVTZU_F64_U32 : SInstCvtMXZ<"svcvt_f64[_u32]", "ddPz", "dPz", "d", "aarch64_sve_ucvtf_f64i32">; -defm SVFCVTZU_F64_U64 : SInstCvtMXZ<"svcvt_f64[_u64]", "NNPd", "NPd", "Ul", "aarch64_sve_ucvtf", [IsOverloadCvt]>; +defm SVFCVTZU_F64_U64 : SInstCvtMXZ<"svcvt_f64[_u64]", "NNPd", "NPd", "Ul", "aarch64_sve_ucvtf", [IsOverloadFirstandLast]>; // svcvt_f16_f## defm SVFCVT_F16_F32 : SInstCvtMXZ<"svcvt_f16[_f32]", "OOPd", "OPd", "f", "aarch64_sve_fcvt_f16f32">; @@ -993,7 +993,7 @@ def SVDUPQ_LANE : SInst<"svdupq_lane[_{d}]", "ddn", "csilUcUsUiUlhfdb", MergeNo def SVEXT : SInst<"svext[_{d}]", "dddi", "csilUcUsUiUlhfdb", MergeNone, "aarch64_sve_ext", [VerifyRuntimeMode], [ImmCheck<2, ImmCheckExtract, 1>]>; defm SVLASTA : SVEPerm<"svlasta[_{d}]", "sPd", "aarch64_sve_lasta">; defm SVLASTB : SVEPerm<"svlastb[_{d}]", "sPd", "aarch64_sve_lastb">; -def SVREV : SInst<"svrev[_{d}]", "dd", "csilUcUsUiUlhfdb", MergeNone, "aarch64_sve_rev", [VerifyRuntimeMode]>; +def SVREV : SInst<"svrev[_{d}]", "dd", "csilUcUsUiUlhfdb", MergeNone, "vector_reverse", [VerifyRuntimeMode]>; def SVSEL : SInst<"svsel[_{d}]", "dPdd", "csilUcUsUiUlhfdb", MergeNone, "aarch64_sve_sel", [VerifyRuntimeMode]>; def SVSPLICE : SInst<"svsplice[_{d}]", "dPdd", "csilUcUsUiUlhfdb", MergeNone, "aarch64_sve_splice", [VerifyRuntimeMode]>; def SVTBL : SInst<"svtbl[_{d}]", "ddu", "csilUcUsUiUlhfdb", MergeNone, "aarch64_sve_tbl", [VerifyRuntimeMode]>; @@ -1009,7 +1009,7 @@ def SVUZP2 : SInst<"svuzp2[_{d}]", "ddd", "csilUcUsUiUlhfdb", MergeNon def SVZIP1 : SInst<"svzip1[_{d}]", "ddd", "csilUcUsUiUlhfdb", MergeNone, "aarch64_sve_zip1", [VerifyRuntimeMode]>; def SVZIP2 : SInst<"svzip2[_{d}]", "ddd", "csilUcUsUiUlhfdb", MergeNone, "aarch64_sve_zip2", [VerifyRuntimeMode]>; -def SVREV_B8 : SInst<"svrev_b8", "PP", "Pc", MergeNone, "aarch64_sve_rev", [VerifyRuntimeMode]>; +def SVREV_B8 : SInst<"svrev_b8", "PP", "Pc", MergeNone, "vector_reverse", [VerifyRuntimeMode]>; def SVREV_B16 : SInst<"svrev_b16", "PP", "Pc", MergeNone, "aarch64_sve_rev_b16", [IsOverloadNone, VerifyRuntimeMode]>; def SVREV_B32 : SInst<"svrev_b32", "PP", "Pc", MergeNone, "aarch64_sve_rev_b32", [IsOverloadNone, VerifyRuntimeMode]>; def SVREV_B64 : SInst<"svrev_b64", "PP", "Pc", MergeNone, "aarch64_sve_rev_b64", [IsOverloadNone, VerifyRuntimeMode]>; @@ -1190,11 +1190,23 @@ def SVSUDOT_LANE_S : SInst<"svsudot_lane[_s32]", "ddqbi", "i", MergeNone, "aarc } let SVETargetGuard = "f32mm", SMETargetGuard = InvalidMode in { -def SVMLLA_F32 : SInst<"svmmla[_f32]", "dddd","f", MergeNone, "aarch64_sve_fmmla">; +def SVMLLA_F32 : SInst<"svmmla[_f32]", "dddd","f", MergeNone, "aarch64_sve_fmmla", [IsOverloadFirstandLast]>; } let SVETargetGuard = "f64mm", SMETargetGuard = InvalidMode in { -def SVMLLA_F64 : SInst<"svmmla[_f64]", "dddd", "d", MergeNone, "aarch64_sve_fmmla">; +def SVMLLA_F64 : SInst<"svmmla[_f64]", "dddd", "d", MergeNone, "aarch64_sve_fmmla", [IsOverloadFirstandLast]>; + +let SVETargetGuard = "sve-f16f32mm", SMETargetGuard = InvalidMode in { + def SVMLLA_F32_F16 : SInst<"svmmla[_f32_f16]", "ddhh", "f", MergeNone, "aarch64_sve_fmmla", [IsOverloadFirstandLast]>; +} + +let SVETargetGuard = "sve2,f8f32mm", SMETargetGuard = InvalidMode in { + def SVMLLA_F32_MF8 : SInst<"svmmla[_f32_mf8]", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmmla">; +} + +let SVETargetGuard = "sve2,f8f16mm", SMETargetGuard = InvalidMode in { + def SVMLLA_F16_MF8 : SInst<"svmmla[_f16_mf8]", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fmmla">; +} def SVTRN1Q : SInst<"svtrn1q[_{d}]", "ddd", "csilUcUsUiUlhfdb", MergeNone, "aarch64_sve_trn1q">; def SVTRN2Q : SInst<"svtrn2q[_{d}]", "ddd", "csilUcUsUiUlhfdb", MergeNone, "aarch64_sve_trn2q">; @@ -1293,25 +1305,25 @@ defm SVRSQRTE : SInstZPZ<"svrsqrte", "Ui", "aarch64_sve_ursqrte">; //------------------------------------------------------------------------------ -multiclass SInstZPZxZ<string name, string types, string pat_v, string pat_n, string intrinsic, list<FlagType> flags=[]> { - def _M : SInst<name # "[_{d}]", pat_v, types, MergeOp1, intrinsic, flags>; - def _X : SInst<name # "[_{d}]", pat_v, types, MergeAny, intrinsic, flags>; - def _Z : SInst<name # "[_{d}]", pat_v, types, MergeZero, intrinsic, flags>; +multiclass SInstZPZxZ<string name, string types, string pat_v, string pat_n, string m_intrinsic, string x_intrinsic, list<FlagType> flags=[]> { + def _M : SInst<name # "[_{d}]", pat_v, types, MergeOp1, m_intrinsic, flags>; + def _X : SInst<name # "[_{d}]", pat_v, types, MergeAny, x_intrinsic, flags>; + def _Z : SInst<name # "[_{d}]", pat_v, types, MergeZero, m_intrinsic, flags>; - def _N_M : SInst<name # "[_n_{d}]", pat_n, types, MergeOp1, intrinsic, flags>; - def _N_X : SInst<name # "[_n_{d}]", pat_n, types, MergeAny, intrinsic, flags>; - def _N_Z : SInst<name # "[_n_{d}]", pat_n, types, MergeZero, intrinsic, flags>; + def _N_M : SInst<name # "[_n_{d}]", pat_n, types, MergeOp1, m_intrinsic, flags>; + def _N_X : SInst<name # "[_n_{d}]", pat_n, types, MergeAny, x_intrinsic, flags>; + def _N_Z : SInst<name # "[_n_{d}]", pat_n, types, MergeZero, m_intrinsic, flags>; } let SVETargetGuard = "sve2|sme" in { -defm SVQRSHL_S : SInstZPZxZ<"svqrshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqrshl", [VerifyRuntimeMode]>; -defm SVQRSHL_U : SInstZPZxZ<"svqrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqrshl", [VerifyRuntimeMode]>; -defm SVQSHL_S : SInstZPZxZ<"svqshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqshl", [VerifyRuntimeMode]>; -defm SVQSHL_U : SInstZPZxZ<"svqshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqshl", [VerifyRuntimeMode]>; -defm SVRSHL_S : SInstZPZxZ<"svrshl", "csil", "dPdx", "dPdK", "aarch64_sve_srshl", [VerifyRuntimeMode]>; -defm SVRSHL_U : SInstZPZxZ<"svrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_urshl", [VerifyRuntimeMode]>; -defm SVSQADD : SInstZPZxZ<"svsqadd", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_usqadd", [VerifyRuntimeMode]>; -defm SVUQADD : SInstZPZxZ<"svuqadd", "csil", "dPdu", "dPdL", "aarch64_sve_suqadd", [VerifyRuntimeMode]>; +defm SVQRSHL_S : SInstZPZxZ<"svqrshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqrshl", "aarch64_sve_sqrshl_u", [VerifyRuntimeMode]>; +defm SVQRSHL_U : SInstZPZxZ<"svqrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqrshl", "aarch64_sve_uqrshl_u", [VerifyRuntimeMode]>; +defm SVQSHL_S : SInstZPZxZ<"svqshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqshl", "aarch64_sve_sqshl_u", [VerifyRuntimeMode]>; +defm SVQSHL_U : SInstZPZxZ<"svqshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqshl", "aarch64_sve_uqshl_u", [VerifyRuntimeMode]>; +defm SVRSHL_S : SInstZPZxZ<"svrshl", "csil", "dPdx", "dPdK", "aarch64_sve_srshl", "aarch64_sve_srshl_u", [VerifyRuntimeMode]>; +defm SVRSHL_U : SInstZPZxZ<"svrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_urshl", "aarch64_sve_urshl_u", [VerifyRuntimeMode]>; +defm SVSQADD : SInstZPZxZ<"svsqadd", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_usqadd", "aarch64_sve_usqadd", [VerifyRuntimeMode]>; +defm SVUQADD : SInstZPZxZ<"svuqadd", "csil", "dPdu", "dPdL", "aarch64_sve_suqadd", "aarch64_sve_suqadd", [VerifyRuntimeMode]>; def SVABA_S : SInst<"svaba[_{d}]", "dddd", "csil" , MergeNone, "aarch64_sve_saba", [VerifyRuntimeMode]>; def SVABA_U : SInst<"svaba[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uaba", [VerifyRuntimeMode]>; @@ -2082,6 +2094,17 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2,sve-b16b16"in { defm SVBFMAXNM : BfSingleMultiVector<"maxnm">; } +let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2,sve-bfscale" in { + // BFMUL + defm SVBFMUL : BfSingleMultiVector<"mul">; + // BFSCALE + def SVBFSCALE_SINGLE_X2 : SInst<"svscale[_single_{d}_x2]", "22x", "b", MergeNone, "aarch64_sve_fscale_single_x2", [IsStreaming], []>; + def SVBFSCALE_SINGLE_X4 : SInst<"svscale[_single_{d}_x4]", "44x", "b", MergeNone, "aarch64_sve_fscale_single_x4", [IsStreaming], []>; + + def SVBFSCALE_X2 : SInst<"svscale[_{d}_x2]", "222.x", "b", MergeNone, "aarch64_sve_fscale_x2", [IsStreaming], []>; + def SVBFSCALE_X4 : SInst<"svscale[_{d}_x4]", "444.x", "b", MergeNone, "aarch64_sve_fscale_x4", [IsStreaming], []>; +} + let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in { // == ADD (vectors) == def SVADD_SINGLE_X2 : SInst<"svadd[_single_{d}_x2]", "22d", "cUcsUsiUilUl", MergeNone, "aarch64_sve_add_single_x2", [IsStreaming], []>; @@ -2389,3 +2412,11 @@ let SVETargetGuard = "sve2,fp8fma", SMETargetGuard = "ssve-fp8fma" in { def SVFMLALLTB_LANE : SInst<"svmlalltb_lane[_f32_mf8]", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; def SVFMLALLTT_LANE : SInst<"svmlalltt_lane[_f32_mf8]", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; } + +let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2p2" in { + def FMUL_SINGLE_X2 : SInst<"svmul[_single_{d}_x2]", "22d", "hfd", MergeNone, "aarch64_sve_fmul_single_x2", [IsStreaming], []>; + def FMUL_SINGLE_X4 : SInst<"svmul[_single_{d}_x4]", "44d", "hfd", MergeNone, "aarch64_sve_fmul_single_x4", [IsStreaming], []>; + + def FMUL_X2 : SInst<"svmul[_{d}_x2]", "222", "hfd", MergeNone, "aarch64_sve_fmul_x2", [IsStreaming], []>; + def FMUL_X4 : SInst<"svmul[_{d}_x4]", "444", "hfd", MergeNone, "aarch64_sve_fmul_x4", [IsStreaming], []>; +} diff --git a/clang/include/clang/Basic/arm_sve_sme_incl.td b/clang/include/clang/Basic/arm_sve_sme_incl.td index 13e7cf45..7e60e87 100644 --- a/clang/include/clang/Basic/arm_sve_sme_incl.td +++ b/clang/include/clang/Basic/arm_sve_sme_incl.td @@ -214,7 +214,7 @@ def IsZExtReturn : FlagType<0x00080000>; // Return value is s def IsOverloadNone : FlagType<0x00100000>; // Intrinsic does not take any overloaded types. def IsOverloadWhileOrMultiVecCvt : FlagType<0x00200000>; // Use {default type, typeof(operand1)} as overloaded types. def IsOverloadWhileRW : FlagType<0x00400000>; // Use {pred(default type), typeof(operand0)} as overloaded types. -def IsOverloadCvt : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types. +def IsOverloadFirstandLast : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types. def OverloadKindMask : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type. def IsByteIndexed : FlagType<0x01000000>; def IsAppendSVALL : FlagType<0x02000000>; // Appends SV_ALL as the last operand. diff --git a/clang/include/clang/CIR/CIRGenerator.h b/clang/include/clang/CIR/CIRGenerator.h index 5ea1146..31dead2 100644 --- a/clang/include/clang/CIR/CIRGenerator.h +++ b/clang/include/clang/CIR/CIRGenerator.h @@ -81,6 +81,9 @@ public: void HandleTagDeclDefinition(clang::TagDecl *d) override; void HandleTagDeclRequiredDefinition(const clang::TagDecl *D) override; void HandleCXXStaticMemberVarInstantiation(clang::VarDecl *D) override; + void + HandleOpenACCRoutineReference(const clang::FunctionDecl *FD, + const clang::OpenACCRoutineDecl *RD) override; void CompleteTentativeDefinition(clang::VarDecl *d) override; void HandleVTable(clang::CXXRecordDecl *rd) override; diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 3288f5b..7ee3785 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -131,6 +131,14 @@ public: return cir::IntType::get(getContext(), n, false); } + static unsigned getCIRIntOrFloatBitWidth(mlir::Type eltTy) { + if (auto intType = mlir::dyn_cast<cir::IntTypeInterface>(eltTy)) + return intType.getWidth(); + if (auto floatType = mlir::dyn_cast<cir::FPTypeInterface>(eltTy)) + return floatType.getWidth(); + + llvm_unreachable("Unsupported type in getCIRIntOrFloatBitWidth"); + } cir::IntType getSIntNTy(int n) { return cir::IntType::get(getContext(), n, true); } @@ -300,14 +308,16 @@ public: return cir::GlobalViewAttr::get(type, symbol, indices); } - mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global) { + mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global, + bool threadLocal = false) { assert(!cir::MissingFeatures::addressSpace()); - return cir::GetGlobalOp::create( - *this, loc, getPointerTo(global.getSymType()), global.getSymName()); + return cir::GetGlobalOp::create(*this, loc, + getPointerTo(global.getSymType()), + global.getSymNameAttr(), threadLocal); } - mlir::Value createGetGlobal(cir::GlobalOp global) { - return createGetGlobal(global.getLoc(), global); + mlir::Value createGetGlobal(cir::GlobalOp global, bool threadLocal = false) { + return createGetGlobal(global.getLoc(), global, threadLocal); } /// Create a copy with inferred length. @@ -323,6 +333,19 @@ public: return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order); } + /// Emit a load from an boolean flag variable. + cir::LoadOp createFlagLoad(mlir::Location loc, mlir::Value addr) { + mlir::Type boolTy = getBoolTy(); + if (boolTy != mlir::cast<cir::PointerType>(addr.getType()).getPointee()) + addr = createPtrBitcast(addr, boolTy); + return createLoad(loc, addr, /*isVolatile=*/false, /*alignment=*/1); + } + + cir::StoreOp createFlagStore(mlir::Location loc, bool val, mlir::Value dst) { + mlir::Value flag = getBool(val, loc); + return CIRBaseBuilderTy::createStore(loc, flag, dst); + } + [[nodiscard]] cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule, mlir::Location loc, mlir::StringRef name, @@ -389,25 +412,6 @@ public: return createCallOp(loc, callee, cir::VoidType(), operands, attrs); } - cir::CallOp createTryCallOp( - mlir::Location loc, mlir::SymbolRefAttr callee = mlir::SymbolRefAttr(), - mlir::Type returnType = cir::VoidType(), - mlir::ValueRange operands = mlir::ValueRange(), - [[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) { - assert(!cir::MissingFeatures::opCallCallConv()); - assert(!cir::MissingFeatures::opCallSideEffect()); - return createCallOp(loc, callee, returnType, operands); - } - - cir::CallOp createTryCallOp( - mlir::Location loc, cir::FuncOp callee, mlir::ValueRange operands, - [[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) { - assert(!cir::MissingFeatures::opCallCallConv()); - assert(!cir::MissingFeatures::opCallSideEffect()); - return createTryCallOp(loc, mlir::SymbolRefAttr::get(callee), - callee.getFunctionType().getReturnType(), operands); - } - //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// @@ -465,6 +469,15 @@ public: return createCompare(ptr.getLoc(), cir::CmpOpKind::eq, ptr, nullPtr); } + mlir::Value createAddrSpaceCast(mlir::Location loc, mlir::Value src, + mlir::Type newTy) { + return createCast(loc, cir::CastKind::address_space, src, newTy); + } + + mlir::Value createAddrSpaceCast(mlir::Value src, mlir::Type newTy) { + return createAddrSpaceCast(src.getLoc(), src, newTy); + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -575,6 +588,16 @@ public: return cir::CmpOp::create(*this, loc, getBoolTy(), kind, lhs, rhs); } + cir::VecCmpOp createVecCompare(mlir::Location loc, cir::CmpOpKind kind, + mlir::Value lhs, mlir::Value rhs) { + VectorType vecCast = mlir::cast<VectorType>(lhs.getType()); + IntType integralTy = + getSIntNTy(getCIRIntOrFloatBitWidth(vecCast.getElementType())); + VectorType integralVecTy = + VectorType::get(context, integralTy, vecCast.getSize()); + return cir::VecCmpOp::create(*this, loc, integralVecTy, kind, lhs, rhs); + } + mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand) { return createCompare(loc, cir::CmpOpKind::ne, operand, operand); } diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h index 03a6a97..858d4d63 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h @@ -35,6 +35,7 @@ namespace cir { class ArrayType; class BoolType; class ComplexType; +class DataMemberType; class IntType; class MethodType; class PointerType; diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 1e0fb03..c0279a0 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -448,6 +448,57 @@ def CIR_ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> { } //===----------------------------------------------------------------------===// +// DataMemberAttr +//===----------------------------------------------------------------------===// + +def CIR_DataMemberAttr : CIR_Attr<"DataMember", "data_member", [ + TypedAttrInterface +]> { + let summary = "Holds a constant data member pointer value"; + let parameters = (ins AttributeSelfTypeParameter< + "", "cir::DataMemberType">:$type, + OptionalParameter< + "std::optional<unsigned>">:$member_index); + let description = [{ + A data member attribute is a literal attribute that represents a constant + pointer-to-data-member value. + + The `member_index` parameter represents the index of the pointed-to member + within its containing record. It is an optional parameter; lack of this + parameter indicates a null pointer-to-data-member value. + + Example: + ``` + #ptr = #cir.data_member<1> : !cir.data_member<!s32i in !rec_22Point22> + + #null = #cir.data_member<null> : !cir.data_member<!s32i in !rec_22Point22> + ``` + }]; + + let builders = [ + AttrBuilderWithInferredContext<(ins "cir::DataMemberType":$type), [{ + return $_get(type.getContext(), type, std::nullopt); + }]>, + AttrBuilderWithInferredContext<(ins "cir::DataMemberType":$type, + "unsigned":$member_index), [{ + return $_get(type.getContext(), type, member_index); + }]>, + ]; + + let genVerifyDecl = 1; + + let assemblyFormat = [{ + `<` ($member_index^):(`null`)? `>` + }]; + + let extraClassDeclaration = [{ + bool isNullPtr() const { + return !getMemberIndex().has_value(); + } + }]; +} + +//===----------------------------------------------------------------------===// // GlobalViewAttr //===----------------------------------------------------------------------===// @@ -823,6 +874,119 @@ def CIR_GlobalDtorAttr : CIR_GlobalCtorDtor<"Dtor", "dtor"> { } //===----------------------------------------------------------------------===// +// CXX SpecialMemberAttr +//===----------------------------------------------------------------------===// + +def CIR_CtorKind : CIR_I32EnumAttr<"CtorKind", "CXX Constructor Kind", [ + I32EnumAttrCase<"Custom", 0, "custom">, + I32EnumAttrCase<"Default", 1, "default">, + I32EnumAttrCase<"Copy", 2, "copy">, + I32EnumAttrCase<"Move", 3, "move">, +]> { + let genSpecializedAttr = 0; +} + +def CIR_CXXCtorAttr : CIR_Attr<"CXXCtor", "cxx_ctor"> { + let summary = "Marks a function as a C++ constructor"; + let description = [{ + This attribute identifies a C++ constructor and classifies its kind: + + - `custom`: a user-defined constructor + - `default`: a default constructor + - `copy`: a copy constructor + - `move`: a move constructor + + Example: + ```mlir + #cir.cxx_ctor<!rec_a, copy> + #cir.cxx_ctor<!rec_b, default, trivial> + ``` + }]; + + let parameters = (ins + "mlir::Type":$type, + EnumParameter<CIR_CtorKind>:$ctor_kind, + DefaultValuedParameter<"bool", "false">:$is_trivial + ); + + let builders = [ + AttrBuilderWithInferredContext<(ins "mlir::Type":$type, + CArg<"CtorKind", "cir::CtorKind::Custom">:$ctorKind, + CArg<"bool", "false">:$isTrivial), [{ + return $_get(type.getContext(), type, ctorKind, isTrivial); + }]>, + ]; + + let assemblyFormat = [{ + `<` $type `,` $ctor_kind (`,` `trivial` $is_trivial^)? `>` + }]; +} + +def CIR_CXXDtorAttr : CIR_Attr<"CXXDtor", "cxx_dtor"> { + let summary = "Marks a function as a CXX destructor"; + let description = [{ + This attribute identifies a C++ destructor. + }]; + + let parameters = (ins + "mlir::Type":$type, + DefaultValuedParameter<"bool", "false">:$is_trivial + ); + + let builders = [ + AttrBuilderWithInferredContext<(ins "mlir::Type":$type, + CArg<"bool", "false">:$isTrivial), [{ + return $_get(type.getContext(), type, isTrivial); + }]> + ]; + + let assemblyFormat = [{ + `<` $type (`,` `trivial` $is_trivial^)? `>` + }]; +} + +def CIR_AssignKind : CIR_I32EnumAttr<"AssignKind", "CXX Assignment Operator Kind", [ + I32EnumAttrCase<"Copy", 0, "copy">, + I32EnumAttrCase<"Move", 1, "move">, +]> { + let genSpecializedAttr = 0; +} + +def CIR_CXXAssignAttr : CIR_Attr<"CXXAssign", "cxx_assign"> { + let summary = "Marks a function as a CXX assignment operator"; + let description = [{ + This attribute identifies a C++ assignment operator and classifies its kind: + + - `copy`: a copy assignment + - `move`: a move assignment + }]; + + let parameters = (ins + "mlir::Type":$type, + EnumParameter<CIR_AssignKind>:$assign_kind, + DefaultValuedParameter<"bool", "false">:$is_trivial + ); + + let builders = [ + AttrBuilderWithInferredContext<(ins "mlir::Type":$type, + CArg<"AssignKind">:$assignKind, + CArg<"bool", "false">:$isTrivial), [{ + return $_get(type.getContext(), type, assignKind, isTrivial); + }]> + ]; + + let assemblyFormat = [{ + `<` $type `,` $assign_kind (`,` `trivial` $is_trivial^)? `>` + }]; +} + +def CIR_CXXSpecialMemberAttr : AnyAttrOf<[ + CIR_CXXCtorAttr, + CIR_CXXDtorAttr, + CIR_CXXAssignAttr +]>; + +//===----------------------------------------------------------------------===// // BitfieldInfoAttr //===----------------------------------------------------------------------===// @@ -972,44 +1136,10 @@ def CIR_TypeInfoAttr : CIR_Attr<"TypeInfo", "typeinfo", [TypedAttrInterface]> { //===----------------------------------------------------------------------===// def CIR_InlineKind : CIR_I32EnumAttr<"InlineKind", "inlineKind", [ - I32EnumAttrCase<"NoInline", 1, "never">, - I32EnumAttrCase<"AlwaysInline", 2, "always">, - I32EnumAttrCase<"InlineHint", 3, "hint"> -]> { - let genSpecializedAttr = 0; -} - -def CIR_InlineAttr : CIR_EnumAttr<CIR_InlineKind, "inline"> { - let summary = "Inline attribute"; - let description = [{ - Inline attribute represents user directives for inlining behavior. - This attribute is only used by `cir.func` operations. - - Values: - - `never`: Prevents the function from being inlined (__attribute__((noinline))) - - `always`: Forces the function to be inlined (__attribute__((always_inline))) - - `hint`: Suggests the function should be inlined (inline keyword) - - Example: - ``` - cir.func @noinline_func(%arg0: !s32i) -> !s32i inline(never) { - cir.return %arg0 : !s32i - } - cir.func @always_inline_func() -> !s32i inline(always) { - %0 = cir.const #cir.int<42> : !s32i - cir.return %0 : !s32i - } - ``` - }]; - - let cppClassName = "InlineAttr"; - - let extraClassDeclaration = [{ - bool isNoInline() const { return getValue() == InlineKind::NoInline; }; - bool isAlwaysInline() const { return getValue() == InlineKind::AlwaysInline; }; - bool isInlineHint() const { return getValue() == InlineKind::InlineHint; }; - }]; -} + I32EnumAttrCase<"NoInline", 1, "no_inline">, + I32EnumAttrCase<"AlwaysInline", 2, "always_inline">, + I32EnumAttrCase<"InlineHint", 3, "inline_hint"> +]>; //===----------------------------------------------------------------------===// // CatchAllAttr & UnwindAttr @@ -1026,4 +1156,29 @@ def CIR_UnwindAttr : CIR_UnitAttr<"Unwind", "unwind"> { let storageType = [{ CatchUnwind }]; } +//===----------------------------------------------------------------------===// +// CIR_BlockAddrInfoAttr +//===----------------------------------------------------------------------===// + +def CIR_BlockAddrInfoAttr : CIR_Attr<"BlockAddrInfo", "block_addr_info"> { + let summary = "Block Addres attribute"; + let description = [{ + This attribute is used to represent the address of a basic block + within a function. It combines the symbol reference to a function + with the name of a label inside that function. + }]; + let parameters = (ins "mlir::FlatSymbolRefAttr":$func, + "mlir::StringAttr":$label); + + let assemblyFormat = "`<` $func `,` $label `>`"; + let builders = [ + AttrBuilder<(ins "llvm::StringRef":$func_name, + "llvm::StringRef":$label_name + ), [{ + return $_get($_ctxt, mlir::FlatSymbolRefAttr::get($_ctxt, func_name), + mlir::StringAttr::get($_ctxt, label_name)); + }]> + ]; +} + #endif // CLANG_CIR_DIALECT_IR_CIRATTRS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td index e915371..7c38492 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td @@ -24,8 +24,7 @@ def CIR_Dialect : Dialect { let cppNamespace = "::cir"; - let useDefaultAttributePrinterParser = 0; - let useDefaultTypePrinterParser = 0; + let useDefaultAttributePrinterParser = 1; // Enable constant materialization for the CIR dialect. This generates a // declaration for the cir::CIRDialect::materializeConstant function. This @@ -44,6 +43,7 @@ def CIR_Dialect : Dialect { static llvm::StringRef getModuleLevelAsmAttrName() { return "cir.module_asm"; } static llvm::StringRef getGlobalCtorsAttrName() { return "cir.global_ctors"; } static llvm::StringRef getGlobalDtorsAttrName() { return "cir.global_dtors"; } + static llvm::StringRef getOperandSegmentSizesAttrName() { return "operandSegmentSizes"; } void registerAttributes(); void registerTypes(); @@ -51,12 +51,6 @@ def CIR_Dialect : Dialect { mlir::Type parseType(mlir::DialectAsmParser &parser) const override; void printType(mlir::Type type, mlir::DialectAsmPrinter &printer) const override; - - mlir::Attribute parseAttribute(mlir::DialectAsmParser &parser, - mlir::Type type) const override; - - void printAttribute(mlir::Attribute attr, - mlir::DialectAsmPrinter &os) const override; }]; } diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 6f9a69e..04648bee 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -413,6 +413,18 @@ def CIR_ConstantOp : CIR_Op<"const", [ template <typename T> T getValueAttr() { return mlir::dyn_cast<T>(getValue()); } + + llvm::APInt getIntValue() { + if (const auto intAttr = getValueAttr<cir::IntAttr>()) + return intAttr.getValue(); + llvm_unreachable("Expected an IntAttr in ConstantOp"); + } + + bool getBoolValue() { + if (const auto boolAttr = getValueAttr<cir::BoolAttr>()) + return boolAttr.getValue(); + llvm_unreachable("Expected a BoolAttr in ConstantOp"); + } }]; let hasFolder = 1; @@ -790,8 +802,8 @@ def CIR_ConditionOp : CIR_Op<"condition", [ //===----------------------------------------------------------------------===// defvar CIR_YieldableScopes = [ - "ArrayCtor", "ArrayDtor", "CaseOp", "DoWhileOp", "ForOp", "GlobalOp", "IfOp", - "ScopeOp", "SwitchOp", "TernaryOp", "WhileOp", "TryOp" + "ArrayCtor", "ArrayDtor", "AwaitOp", "CaseOp", "DoWhileOp", "ForOp", + "GlobalOp", "IfOp", "ScopeOp", "SwitchOp", "TernaryOp", "WhileOp", "TryOp" ]; def CIR_YieldOp : CIR_Op<"yield", [ @@ -887,6 +899,36 @@ def CIR_ContinueOp : CIR_Op<"continue", [Terminator]> { } //===----------------------------------------------------------------------===// +// Resume +//===----------------------------------------------------------------------===// + +def CIR_ResumeOp : CIR_Op<"resume", [ + ReturnLike, Terminator, HasParent<"cir::TryOp"> +]> { + let summary = "Resumes execution after not catching exceptions"; + let description = [{ + The `cir.resume` operation handles an uncaught exception scenario. + + Used as the terminator of a `CatchUnwind` region of `cir.try`, where it + does not receive any arguments (implied from the `cir.try` scope). + + This operation is used only before the CFG flatterning pass. + + Examples: + ```mlir + cir.try { + cir.yield + } unwind { + cir.resume + } + ``` + }]; + + let assemblyFormat = "attr-dict"; + let hasLLVMLowering = false; +} + +//===----------------------------------------------------------------------===// // ScopeOp //===----------------------------------------------------------------------===// @@ -1162,6 +1204,35 @@ def CIR_SwitchOp : CIR_Op<"switch", [ } //===----------------------------------------------------------------------===// +// IsConstantOp +//===----------------------------------------------------------------------===// + +def CIR_IsConstantOp : CIR_Op<"is_constant", [Pure]> { + let summary = "Test for manifest compile-time constant"; + let description = [{ + Returns `true` if the argument is known to be a manifest compile-time + constant otherwise returns `false`. If the argument is a constant expression + which refers to a global (the address of which _is_ a constant, but not + manifest during the compile), then the intrinsic evaluates to `false`. + + This is used to represent `__builtin_constant_p` in cases where the argument + isn't known to be constant during initial translation of the source code but + might be proven to be constant after later optimizations. + + Example: + ``` + %1 = cir.is_constant %2 : !s32i -> !cir.bool + ``` + }]; + let arguments = (ins CIR_AnyType:$val); + let results = (outs CIR_BoolType:$result); + + let assemblyFormat = [{ + $val `:` qualified(type($val)) `->` qualified(type($result)) attr-dict + }]; +} + +//===----------------------------------------------------------------------===// // SwitchFlatOp //===----------------------------------------------------------------------===// @@ -1422,6 +1493,55 @@ def CIR_BrCondOp : CIR_Op<"brcond", [ } //===----------------------------------------------------------------------===// +// IndirectBrOp +//===----------------------------------------------------------------------===// + +def CIR_IndirectBrOp : CIR_Op<"indirect_br", [ + DeclareOpInterfaceMethods<BranchOpInterface>, + SameVariadicOperandSize, Terminator, Pure +]> { + let summary = "Indirect branch"; + let description = [{ + The `cir.indirectbr` operation represents an indirect branch to one of + several possible successor blocks. The target block is computed from + the value of the given address operand. + + This operation is typically generated when handling constructs like + the GCC extension `&&label` combined with an indirect `goto *ptr;`. + + The `poison` attribute is used to mark an `indirectbr` that was created + but is known to be invalid, for instance when a label address was + taken but no indirect branch was ever emitted. + + Example: + + ```mlir + %0 = cir.block_address <@A, "A"> : !cir.ptr<!void> + cir.indirectbr %0 poison : <!void>, [ + ^bb1 + ] + ``` + }]; + + let arguments = (ins + CIR_VoidPtrType:$addr, + UnitAttr:$poison, + VariadicOfVariadic<AnyType, "operand_segments">:$succ_operands, + DenseI32ArrayAttr:$operand_segments + ); + + let successors = (successor VariadicSuccessor<AnySuccessor>:$successors); + let assemblyFormat = [{ + $addr ( `poison` $poison^ )? `:` qualified(type($addr)) `,` + custom<IndirectBrOpSucessors>(ref(type($addr)), + $successors, + $succ_operands, + type($succ_operands)) + attr-dict + }]; +} + +//===----------------------------------------------------------------------===// // Common loop op definitions //===----------------------------------------------------------------------===// @@ -1629,6 +1749,82 @@ def CIR_CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> { } //===----------------------------------------------------------------------===// +// BinOpOverflowOp +//===----------------------------------------------------------------------===// + +def CIR_BinOpOverflowKind : CIR_I32EnumAttr< + "BinOpOverflowKind", "checked binary arithmetic operation kind", [ + I32EnumAttrCase<"Add", 0, "add">, + I32EnumAttrCase<"Sub", 1, "sub">, + I32EnumAttrCase<"Mul", 2, "mul"> +]>; + +def CIR_BinOpOverflowOp : CIR_Op<"binop.overflow", [Pure, SameTypeOperands]> { + let summary = "Perform binary integral arithmetic with overflow checking"; + let description = [{ + `cir.binop.overflow` performs binary arithmetic operations with overflow + checking on integral operands. + + The `kind` argument specifies the kind of arithmetic operation to perform. + It can be either `add`, `sub`, or `mul`. The `lhs` and `rhs` arguments + specify the input operands of the arithmetic operation. The types of `lhs` + and `rhs` must be the same. + + `cir.binop.overflow` produces two SSA values. `result` is the result of the + arithmetic operation truncated to its specified type. `overflow` is a + boolean value indicating whether overflow happens during the operation. + + The exact semantic of this operation is as follows: + + - `lhs` and `rhs` are promoted to an imaginary integral type that has + infinite precision. + - The arithmetic operation is performed on the promoted operands. + - The infinite-precision result is truncated to the type of `result`. The + truncated result is assigned to `result`. + - If the truncated result is equal to the un-truncated result, `overflow` + is assigned to false. Otherwise, `overflow` is assigned to true. + }]; + + let arguments = (ins + CIR_BinOpOverflowKind:$kind, + CIR_IntType:$lhs, + CIR_IntType:$rhs + ); + + let results = (outs CIR_IntType:$result, CIR_BoolType:$overflow); + + let assemblyFormat = [{ + `(` $kind `,` $lhs `,` $rhs `)` `:` qualified(type($lhs)) `,` + `(` qualified(type($result)) `,` qualified(type($overflow)) `)` + attr-dict + }]; + + let builders = [ + OpBuilder<(ins "cir::IntType":$resultTy, + "cir::BinOpOverflowKind":$kind, + "mlir::Value":$lhs, + "mlir::Value":$rhs), [{ + auto overflowTy = cir::BoolType::get($_builder.getContext()); + build($_builder, $_state, resultTy, overflowTy, kind, lhs, rhs); + }]> + ]; + + let extraLLVMLoweringPatternDecl = [{ + static std::string getLLVMIntrinName(cir::BinOpOverflowKind opKind, + bool isSigned, unsigned width); + + struct EncompassedTypeInfo { + bool sign; + unsigned width; + }; + + static EncompassedTypeInfo computeEncompassedTypeWidth(cir::IntType operandTy, + cir::IntType resultTy); + }]; +} + + +//===----------------------------------------------------------------------===// // BinOp //===----------------------------------------------------------------------===// @@ -1882,6 +2078,13 @@ def CIR_GlobalLinkageKind : CIR_I32EnumAttr< // properties of a global variable will be added over time as more of ClangIR // is upstreamed. +def CIR_TLSModel : CIR_I32EnumAttr<"TLS_Model", "TLS model", [ + I32EnumAttrCase<"GeneralDynamic", 0, "tls_dyn">, + I32EnumAttrCase<"LocalDynamic", 1, "tls_local_dyn">, + I32EnumAttrCase<"InitialExec", 2, "tls_init_exec">, + I32EnumAttrCase<"LocalExec", 3, "tls_local_exec"> +]>; + def CIR_GlobalOp : CIR_Op<"global", [ DeclareOpInterfaceMethods<RegionBranchOpInterface>, DeclareOpInterfaceMethods<CIRGlobalValueInterface>, @@ -1910,6 +2113,7 @@ def CIR_GlobalOp : CIR_Op<"global", [ OptionalAttr<StrAttr>:$sym_visibility, TypeAttr:$sym_type, CIR_GlobalLinkageKind:$linkage, + OptionalAttr<CIR_TLSModel>:$tls_model, OptionalAttr<AnyAttr>:$initial_value, UnitAttr:$comdat, UnitAttr:$constant, @@ -1925,6 +2129,7 @@ def CIR_GlobalOp : CIR_Op<"global", [ (`constant` $constant^)? $linkage (`comdat` $comdat^)? + ($tls_model^)? (`dso_local` $dso_local^)? $sym_name custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value, @@ -1988,16 +2193,22 @@ def CIR_GetGlobalOp : CIR_Op<"get_global", [ undefined. The resulting type must always be a `!cir.ptr<...>` type with the same address space as the global variable. + Addresses of thread local globals can only be retrieved if this operation + is marked `thread_local`, which indicates the address isn't constant. + Example: ```mlir %x = cir.get_global @gv : !cir.ptr<i32> + ... + %y = cir.get_global thread_local @tls_gv : !cir.ptr<i32> ``` }]; - let arguments = (ins FlatSymbolRefAttr:$name); + let arguments = (ins FlatSymbolRefAttr:$name, UnitAttr:$tls); let results = (outs Res<CIR_PointerType, "", []>:$addr); let assemblyFormat = [{ + (`thread_local` $tls^)? $name `:` qualified(type($addr)) attr-dict }]; } @@ -2476,9 +2687,9 @@ def CIR_FuncOp : CIR_Op<"func", [ Similarly, for global destructors both `global_dtor` and `global_dtor(<priority>)` are available. - The `inline(never)` keyword marks a function that should not be inlined. - The `inline(always)` keyword marks a function that should always be inlined. - The `inline(hint)` keyword suggests that the function should be inlined. + The `no_inline` attribute marks a function that should not be inlined. + The `always_inline` attribute marks a function that should always be inlined. + The `inline_hint` attribute suggests that the function should be inlined. Example: @@ -2492,7 +2703,10 @@ def CIR_FuncOp : CIR_Op<"func", [ // Linkage information cir.func linkonce_odr @some_method(...) - ``` + + // Inline information + cir.func no_inline @some_method(...) + // Builtin function cir.func builtin @__builtin_coro_end(!cir.ptr<i8>, !cir.bool) -> !cir.bool // Coroutine @@ -2504,24 +2718,29 @@ def CIR_FuncOp : CIR_Op<"func", [ ``` }]; - let arguments = (ins SymbolNameAttr:$sym_name, - CIR_VisibilityAttr:$global_visibility, - TypeAttrOf<CIR_FuncType>:$function_type, - UnitAttr:$builtin, - UnitAttr:$coroutine, - UnitAttr:$lambda, - UnitAttr:$no_proto, - UnitAttr:$dso_local, - DefaultValuedAttr<CIR_GlobalLinkageKind, - "cir::GlobalLinkageKind::ExternalLinkage">:$linkage, - OptionalAttr<CIR_InlineAttr>:$inline_kind, - OptionalAttr<StrAttr>:$sym_visibility, - UnitAttr:$comdat, - OptionalAttr<DictArrayAttr>:$arg_attrs, - OptionalAttr<DictArrayAttr>:$res_attrs, - OptionalAttr<FlatSymbolRefAttr>:$aliasee, - CIR_OptionalPriorityAttr:$global_ctor_priority, - CIR_OptionalPriorityAttr:$global_dtor_priority); + let arguments = (ins + SymbolNameAttr:$sym_name, + CIR_VisibilityAttr:$global_visibility, + TypeAttrOf<CIR_FuncType>:$function_type, + UnitAttr:$builtin, + UnitAttr:$coroutine, + OptionalAttr<CIR_InlineKind>:$inline_kind, + UnitAttr:$lambda, + UnitAttr:$no_proto, + UnitAttr:$dso_local, + DefaultValuedAttr< + CIR_GlobalLinkageKind, + "cir::GlobalLinkageKind::ExternalLinkage" + >:$linkage, + OptionalAttr<StrAttr>:$sym_visibility, + UnitAttr:$comdat, + OptionalAttr<DictArrayAttr>:$arg_attrs, + OptionalAttr<DictArrayAttr>:$res_attrs, + OptionalAttr<FlatSymbolRefAttr>:$aliasee, + CIR_OptionalPriorityAttr:$global_ctor_priority, + CIR_OptionalPriorityAttr:$global_dtor_priority, + OptionalAttr<CIR_CXXSpecialMemberAttr>:$cxx_special_member + ); let regions = (region AnyRegion:$body); @@ -2560,7 +2779,32 @@ def CIR_FuncOp : CIR_Op<"func", [ //===------------------------------------------------------------------===// bool isDeclaration(); - }]; + + //===------------------------------------------------------------------===// + // C++ Special Member Functions + //===------------------------------------------------------------------===// + + /// Returns true if this function is a C++ special member function. + bool isCXXSpecialMemberFunction(); + + bool isCxxConstructor(); + bool isCxxDestructor(); + + /// Returns true if this function is a copy or move assignment operator. + bool isCxxSpecialAssignment(); + + /// Returns the kind of constructor this function represents, if any. + std::optional<CtorKind> getCxxConstructorKind(); + + /// Returns the kind of assignment operator (move, copy) this function + /// represents, if any. + std::optional<AssignKind> getCxxSpecialAssignKind(); + + /// Returns true if the function is a trivial C++ member functions such as + /// trivial default constructor, copy/move constructor, copy/move assignment, + /// or destructor. + bool isCxxTrivialMemberFunction(); +}]; let hasCustomAssemblyFormat = 1; let hasVerifier = 1; @@ -2580,7 +2824,40 @@ def CIR_FuncOp : CIR_Op<"func", [ } //===----------------------------------------------------------------------===// -// CallOp +// LLVMIntrinsicCallOp +//===----------------------------------------------------------------------===// + +def CIR_LLVMIntrinsicCallOp : CIR_Op<"call_llvm_intrinsic"> { + let summary = "Call to llvm intrinsic functions that is not defined in CIR"; + let description = [{ + `cir.call_llvm_intrinsic` operation represents a call-like expression which has + return type and arguments that maps directly to a llvm intrinsic. + It only records intrinsic `intrinsic_name`. + }]; + + let results = (outs Optional<CIR_AnyType>:$result); + let arguments = (ins + StrAttr:$intrinsic_name, Variadic<CIR_AnyType>:$arg_ops); + + let skipDefaultBuilders = 1; + + let assemblyFormat = [{ + $intrinsic_name $arg_ops `:` functional-type($arg_ops, $result) attr-dict + }]; + + let builders = [ + OpBuilder<(ins "mlir::StringAttr":$intrinsic_name, "mlir::Type":$resType, + CArg<"mlir::ValueRange", "{}">:$operands), [{ + $_state.addAttribute("intrinsic_name", intrinsic_name); + $_state.addOperands(operands); + if (resType) + $_state.addTypes(resType); + }]>, + ]; +} + +//===----------------------------------------------------------------------===// +// CallOp and TryCallOp //===----------------------------------------------------------------------===// def CIR_SideEffect : CIR_I32EnumAttr< @@ -2707,6 +2984,190 @@ def CIR_CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> { ]; } +def CIR_TryCallOp : CIR_CallOpBase<"try_call",[ + Terminator +]> { + let summary = "try_call operation"; + let description = [{ + Similar to `cir.call` but requires two destination blocks, + one which is used if the call returns without throwing an + exception (the "normal" destination) and another which is used + if an exception is thrown (the "unwind" destination). + + This operation is used only after the CFG flatterning pass. + + Example: + + ```mlir + // Before CFG flattening + cir.try { + %call = cir.call @division(%a, %b) : () -> !s32i + cir.yield + } catch all { + cir.yield + } + + // After CFG flattening + %call = cir.try_call @division(%a, %b) ^normalDest, ^unwindDest + : (f32, f32) -> f32 + ^normalDest: + cir.br ^afterTryBlock + ^unwindDest: + %exception_ptr, %type_id = cir.eh.inflight_exception + cir.br ^catchHandlerBlock(%exception_ptr : !cir.ptr<!void>) + ^catchHandlerBlock: + ... + ``` + }]; + + let arguments = commonArgs; + let results = (outs Optional<CIR_AnyType>:$result); + let successors = (successor + AnySuccessor:$normalDest, + AnySuccessor:$unwindDest + ); + + let skipDefaultBuilders = 1; + let hasLLVMLowering = false; + + let builders = [ + OpBuilder<(ins "mlir::SymbolRefAttr":$callee, + "mlir::Type":$resType, + "mlir::Block *":$normalDest, + "mlir::Block *":$unwindDest, + CArg<"mlir::ValueRange", "{}">:$callOperands, + CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{ + $_state.addOperands(callOperands); + + if (callee) + $_state.addAttribute("callee", callee); + if (resType && !isa<VoidType>(resType)) + $_state.addTypes(resType); + + $_state.addAttribute("side_effect", + SideEffectAttr::get($_builder.getContext(), sideEffect)); + + // Handle branches + $_state.addSuccessors(normalDest); + $_state.addSuccessors(unwindDest); + }]>, + OpBuilder<(ins "mlir::Value":$ind_target, + "FuncType":$fn_type, + "mlir::Block *":$normalDest, + "mlir::Block *":$unwindDest, + CArg<"mlir::ValueRange", "{}">:$callOperands, + CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{ + ::llvm::SmallVector<mlir::Value, 4> finalCallOperands({ind_target}); + finalCallOperands.append(callOperands.begin(), callOperands.end()); + $_state.addOperands(finalCallOperands); + + if (!fn_type.hasVoidReturn()) + $_state.addTypes(fn_type.getReturnType()); + + $_state.addAttribute("side_effect", + SideEffectAttr::get($_builder.getContext(), sideEffect)); + + // Handle branches + $_state.addSuccessors(normalDest); + $_state.addSuccessors(unwindDest); + }]> + ]; +} + +//===----------------------------------------------------------------------===// +// AwaitOp +//===----------------------------------------------------------------------===// + +def CIR_AwaitKind : CIR_I32EnumAttr<"AwaitKind", "await kind", [ + I32EnumAttrCase<"Init", 0, "init">, + I32EnumAttrCase<"User", 1, "user">, + I32EnumAttrCase<"Yield", 2, "yield">, + I32EnumAttrCase<"Final", 3, "final"> +]>; + +def CIR_AwaitOp : CIR_Op<"await",[ + DeclareOpInterfaceMethods<RegionBranchOpInterface>, + RecursivelySpeculatable, NoRegionArguments +]> { + let summary = "Wraps C++ co_await implicit logic"; + let description = [{ + The under the hood effect of using C++ `co_await expr` roughly + translates to: + + ```c++ + // co_await expr; + + auto &&x = CommonExpr(); + if (!x.await_ready()) { + ... + x.await_suspend(...); + ... + } + x.await_resume(); + ``` + + `cir.await` represents this logic by using 3 regions: + - ready: covers veto power from x.await_ready() + - suspend: wraps actual x.await_suspend() logic + - resume: handles x.await_resume() + + Breaking this up in regions allows individual scrutiny of conditions + which might lead to folding some of them out. Lowerings coming out + of CIR, e.g. LLVM, should use the `suspend` region to track more + lower level codegen (e.g. intrinsic emission for coro.save/coro.suspend). + + There are also 4 flavors of `cir.await` available: + - `init`: compiler generated initial suspend via implicit `co_await`. + - `user`: also known as normal, representing a user written `co_await`. + - `yield`: user written `co_yield` expressions. + - `final`: compiler generated final suspend via implicit `co_await`. + + ```mlir + cir.scope { + ... // auto &&x = CommonExpr(); + cir.await(user, ready : { + ... // x.await_ready() + }, suspend : { + ... // x.await_suspend() + }, resume : { + ... // x.await_resume() + }) + } + ``` + + Note that resulution of the common expression is assumed to happen + as part of the enclosing await scope. + }]; + + let arguments = (ins CIR_AwaitKind:$kind); + let regions = (region SizedRegion<1>:$ready, + SizedRegion<1>:$suspend, + SizedRegion<1>:$resume); + let assemblyFormat = [{ + `(` $kind `,` + `ready` `:` $ready `,` + `suspend` `:` $suspend `,` + `resume` `:` $resume `,` + `)` + attr-dict + }]; + + let skipDefaultBuilders = 1; + let builders = [ + OpBuilder<(ins + "cir::AwaitKind":$kind, + CArg<"BuilderCallbackRef", + "nullptr">:$readyBuilder, + CArg<"BuilderCallbackRef", + "nullptr">:$suspendBuilder, + CArg<"BuilderCallbackRef", + "nullptr">:$resumeBuilder + )> + ]; + + let hasVerifier = 1; +} + //===----------------------------------------------------------------------===// // CopyOp //===----------------------------------------------------------------------===// @@ -3341,6 +3802,10 @@ def CIR_BaseClassAddrOp : CIR_Op<"base_class_addr"> { cannot be known by the operation, and that information affects how the operation is lowered. + The validity of the relationship of derived and base cannot yet be verified. + If the target class is not a valid base class for the object, the behavior + is undefined. + Example: ```c++ struct Base { }; @@ -3354,8 +3819,6 @@ def CIR_BaseClassAddrOp : CIR_Op<"base_class_addr"> { ``` }]; - // The validity of the relationship of derived and base cannot yet be - // verified, currently not worth adding a verifier. let arguments = (ins Arg<CIR_PointerType, "derived class pointer", [MemRead]>:$derived_addr, IndexAttr:$offset, UnitAttr:$assume_not_null); @@ -3370,6 +3833,56 @@ def CIR_BaseClassAddrOp : CIR_Op<"base_class_addr"> { } //===----------------------------------------------------------------------===// +// DerivedClassAddrOp +//===----------------------------------------------------------------------===// + +def CIR_DerivedClassAddrOp : CIR_Op<"derived_class_addr"> { + let summary = "Get the derived class address for a class/struct"; + let description = [{ + The `cir.derived_class_addr` operaration gets the address of a particular + derived class given a non-virtual base class pointer. The offset in bytes + of the base class must be passed in, similar to `cir.base_class_addr`, but + going into the other direction. This means lowering to a negative offset. + + The operation contains a flag for whether or not the operand may be nullptr. + That depends on the context and cannot be known by the operation, and that + information affects how the operation is lowered. + + The validity of the relationship of derived and base cannot yet be verified. + If the target class is not a valid derived class for the object, the + behavior is undefined. + + Example: + ```c++ + class A {}; + class B : public A {}; + + B *getAsB(A *a) { + return static_cast<B*>(a); + } + ``` + + leads to + ```mlir + %2 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A> + %3 = cir.base_class_addr %2 : !cir.ptr<!rec_B> [0] -> !cir.ptr<!rec_A> + ``` + }]; + + let arguments = (ins + Arg<CIR_PointerType, "base class pointer", [MemRead]>:$base_addr, + IndexAttr:$offset, UnitAttr:$assume_not_null); + + let results = (outs Res<CIR_PointerType, "">:$derived_addr); + + let assemblyFormat = [{ + $base_addr `:` qualified(type($base_addr)) + (`nonnull` $assume_not_null^)? + ` ` `[` $offset `]` `->` qualified(type($derived_addr)) attr-dict + }]; +} + +//===----------------------------------------------------------------------===// // ComplexCreateOp //===----------------------------------------------------------------------===// @@ -3922,6 +4435,72 @@ def CIR_RotateOp : CIR_Op<"rotate", [Pure, SameOperandsAndResultType]> { } //===----------------------------------------------------------------------===// +// FPClass Test Flags +//===----------------------------------------------------------------------===// + +def FPClassTestEnum : CIR_I32EnumAttr<"FPClassTest", "floating-point class test flags", [ + // Basic flags + I32EnumAttrCase<"SignalingNaN", 1, "fcSNan">, + I32EnumAttrCase<"QuietNaN", 2, "fcQNan">, + I32EnumAttrCase<"NegativeInfinity", 4, "fcNegInf">, + I32EnumAttrCase<"NegativeNormal", 8, "fcNegNormal">, + I32EnumAttrCase<"NegativeSubnormal", 16, "fcNegSubnormal">, + I32EnumAttrCase<"NegativeZero", 32, "fcNegZero">, + I32EnumAttrCase<"PositiveZero", 64, "fcPosZero">, + I32EnumAttrCase<"PositiveSubnormal", 128, "fcPosSubnormal">, + I32EnumAttrCase<"PositiveNormal", 256, "fcPosNormal">, + I32EnumAttrCase<"PositiveInfinity", 512, "fcPosInf">, + + // Composite flags + I32EnumAttrCase<"Nan", 3, "fcNan">, // fcSNan | fcQNan + I32EnumAttrCase<"Infinity", 516, "fcInf">, // fcPosInf | fcNegInf + I32EnumAttrCase<"Normal", 264, "fcNormal">, // fcPosNormal | fcNegNormal + I32EnumAttrCase<"Subnormal", 144, "fcSubnormal">, // fcPosSubnormal | fcNegSubnormal + I32EnumAttrCase<"Zero", 96, "fcZero">, // fcPosZero | fcNegZero + I32EnumAttrCase<"PositiveFinite", 448, "fcPosFinite">,// fcPosNormal | fcPosSubnormal | fcPosZero + I32EnumAttrCase<"NegativeFinite", 56, "fcNegFinite">, // fcNegNormal | fcNegSubnormal | fcNegZero + I32EnumAttrCase<"Finite", 504, "fcFinite">, // fcPosFinite | fcNegFinite + I32EnumAttrCase<"Positive", 960, "fcPositive">, // fcPosFinite | fcPosInf + I32EnumAttrCase<"Negative", 60, "fcNegative">, // fcNegFinite | fcNegInf + I32EnumAttrCase<"All", 1023, "fcAllFlags">, // fcNan | fcInf | fcFinite +]> { + let cppNamespace = "::cir"; +} + +def CIR_IsFPClassOp : CIR_Op<"is_fp_class"> { + let summary = "Corresponding to the `__builtin_fpclassify` builtin function in clang"; + + let description = [{ + The `cir.is_fp_class` operation takes a floating-point value as its first + argument and a bitfield of flags as its second argument. The operation + returns a boolean value indicating whether the floating-point value + satisfies the given flags. + + The flags must be a compile time constant and the values are: + + | Bit # | floating-point class | + | ----- | -------------------- | + | 0 | Signaling NaN | + | 1 | Quiet NaN | + | 2 | Negative infinity | + | 3 | Negative normal | + | 4 | Negative subnormal | + | 5 | Negative zero | + | 6 | Positive zero | + | 7 | Positive subnormal | + | 8 | Positive normal | + | 9 | Positive infinity | + }]; + + let arguments = (ins CIR_AnyFloatType:$src, + FPClassTestEnum:$flags); + let results = (outs CIR_BoolType:$result); + let assemblyFormat = [{ + $src `,` $flags `:` functional-type($src, $result) attr-dict + }]; +} + +//===----------------------------------------------------------------------===// // Assume Operations //===----------------------------------------------------------------------===// @@ -4090,6 +4669,57 @@ def CIR_PrefetchOp : CIR_Op<"prefetch"> { } //===----------------------------------------------------------------------===// +// ObjSizeOp +//===----------------------------------------------------------------------===// + +def CIR_ObjSizeOp : CIR_Op<"objsize", [Pure]> { + let summary = "Implements the llvm.objsize builtin"; + let description = [{ + The `cir.objsize` operation is designed to provide information to the + optimizer to determine whether a) an operation (like memcpy) will + overflow a buffer that corresponds to an object, or b) that a runtime + check for overflow isn’t necessary. An object in this context means an + allocation of a specific class, structure, array, or other object. + + When the `min` attribute is present, the operation returns the minimum + guaranteed accessible size. When absent (max mode), it returns the maximum + possible object size. Corresponds to `llvm.objectsize`'s `min` argument. + + The `dynamic` attribute determines if the value should be evaluated at + runtime. Corresponds to `llvm.objectsize`'s `dynamic` argument. + + The `nullunknown` attribute controls how null pointers are handled. When + present, null pointers are treated as having unknown size. When absent, + null pointers are treated as having 0 size (in min mode) or -1 size + (in max mode). Corresponds to `llvm.objectsize`'s `nullunknown` argument. + + Example: + + ```mlir + %size = cir.objsize min %ptr : !cir.ptr<i32> -> i64 + %dsize = cir.objsize max dynamic %ptr : !cir.ptr<i32> -> i64 + %nsize = cir.objsize min nullunknown %ptr : !cir.ptr<i32> -> i64 + ``` + }]; + + let arguments = (ins + CIR_PointerType:$ptr, + UnitAttr:$min, + UnitAttr:$nullunknown, + UnitAttr:$dynamic + ); + + let results = (outs CIR_AnyFundamentalIntType:$result); + + let assemblyFormat = [{ + (`min` $min^) : (`max`)? + (`nullunknown` $nullunknown^)? + (`dynamic` $dynamic^)? + $ptr `:` qualified(type($ptr)) `->` qualified(type($result)) attr-dict + }]; +} + +//===----------------------------------------------------------------------===// // PtrDiffOp //===----------------------------------------------------------------------===// @@ -4141,6 +4771,27 @@ class CIR_UnaryFPToFPBuiltinOp<string mnemonic, string llvmOpName> let llvmOp = llvmOpName; } +def CIR_SqrtOp : CIR_UnaryFPToFPBuiltinOp<"sqrt", "SqrtOp"> { + let summary = "Floating-point square root operation"; + + let description = [{ + Computes the square root of a floating-point value or vector. + + The input must be either: + • a floating-point scalar type, or + • a vector whose element type is floating-point. + + The result type must match the input type exactly. + + Examples: + // scalar + %r = cir.sqrt %x : !cir.fp64 + + // vector + %v = cir.sqrt %vec : !cir.vector<!cir.fp32 x 4> + }]; +} + def CIR_ACosOp : CIR_UnaryFPToFPBuiltinOp<"acos", "ACosOp"> { let summary = "Computes the arcus cosine of the specified value"; let description = [{ @@ -4201,6 +4852,16 @@ def CIR_ExpOp : CIR_UnaryFPToFPBuiltinOp<"exp", "ExpOp"> { }]; } +def CIR_Exp2Op : CIR_UnaryFPToFPBuiltinOp<"exp2", "Exp2Op"> { + let summary = "Computes the floating-point base-2 exponential value"; + let description = [{ + `cir.exp2` computes the base-2 exponential of a floating-point operand and + returns a result of the same type. + + Floating-point exceptions are ignored, and it does not set `errno`. + }]; +} + def CIR_FAbsOp : CIR_UnaryFPToFPBuiltinOp<"fabs", "FAbsOp"> { let summary = "Computes the floating-point absolute value"; let description = [{ @@ -4211,6 +4872,23 @@ def CIR_FAbsOp : CIR_UnaryFPToFPBuiltinOp<"fabs", "FAbsOp"> { }]; } +def CIR_FloorOp : CIR_UnaryFPToFPBuiltinOp<"floor", "FloorOp"> { + let summary = "Computes the floating-point floor value"; + let description = [{ + `cir.floor` computes the floor of a floating-point operand and returns + a result of the same type. + + Floating-point exceptions are ignored, and it does not set `errno`. + + Example: + + ```mlir + // $x : !cir.double + %y = cir.floor %x : !cir.double + ``` + }]; +} + //===----------------------------------------------------------------------===// // Variadic Operations //===----------------------------------------------------------------------===// @@ -4293,6 +4971,37 @@ def CIR_VAEndOp : CIR_Op<"va_end"> { }]; } +def CIR_VACopyOp : CIR_Op<"va_copy"> { + let summary = "Copied a variable argument list"; + let description = [{ + The `cir.copy` operation models the C/C++ va_copy macro. + The variable argument list passed as the `$src_list` is copied to an + unitialized `va_list` in the destination operand. The next argument that + can be extracted from the copied list is the same as the next argument in + the source list. The copied list must be destroyed with `va_end`. + + Example: + + ```mlir + // %args : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> + %p = cir.cast array_to_ptrdecay %args + : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> + -> !cir.ptr<!rec___va_list_tag> + cir.va_copy %p to %dst + : (!cir.ptr<!rec___va_list_tag>, !cir.ptr<!rec___va_list_tag>) + ``` + }]; + + let arguments = (ins + CIR_PointerType:$dst_list, + CIR_PointerType:$src_list + ); + + let assemblyFormat = [{ + $src_list `to` $dst_list attr-dict `:` type(operands) + }]; +} + def CIR_VAArgOp : CIR_Op<"va_arg"> { let summary = "Fetches next variadic element as a given type"; let description = [{ @@ -4511,6 +5220,72 @@ def CIR_TryOp : CIR_Op<"try",[ } //===----------------------------------------------------------------------===// +// CatchParamOp +//===----------------------------------------------------------------------===// + +def CIR_CatchParamOp : CIR_Op<"catch_param", [HasParent<"cir::TryOp">]> { + let summary = "Represents the catch clause formal parameter"; + let description = [{ + The `cir.catch_param` is used to retrieves the exception object inside + the handler regions of `cir.try`. + + This operation is used only before the CFG flatterning pass. + + Example: + + ```mlir + %exception = cir.catch_param : !cir.ptr<!void> + ``` + }]; + + let results = (outs Optional<CIR_AnyType>:$param); + let assemblyFormat = [{ + (`:` qualified(type($param))^)? + attr-dict + }]; + + let hasLLVMLowering = false; +} + +//===----------------------------------------------------------------------===// +// Exception related: EhInflightOp +//===----------------------------------------------------------------------===// + +def CIR_EhInflightOp : CIR_Op<"eh.inflight_exception"> { + let summary = "Materialize the catch clause formal parameter"; + let description = [{ + `cir.eh.inflight_exception` returns two values: + - `exception_ptr`: The exception pointer for the inflight exception + - `type_id`: the type info index for the exception type + This operation is expected to be the first operation in the unwind + destination basic blocks of a `cir.try_call` operation. + + The `cleanup` attribute indicates that clean up code must be run before the + values produced by this operation are used to dispatch the exception. This + cleanup code must be executed even if the exception is not caught. + This helps CIR to pass down more accurate information for LLVM lowering + to landingpads. + + Example: + + ```mlir + %exception_ptr, %type_id = cir.eh.inflight_exception + %exception_ptr, %type_id = cir.eh.inflight_exception [@_ZTIi, @_ZTIPKc] + %exception_ptr, %type_id = cir.eh.inflight_exception cleanup + `` + }]; + + let arguments = (ins UnitAttr:$cleanup, + OptionalAttr<FlatSymbolRefArrayAttr>:$catch_type_list); + let results = (outs CIR_VoidPtrType:$exception_ptr, CIR_UInt32:$type_id); + let assemblyFormat = [{ + (`cleanup` $cleanup^)? + ($catch_type_list^)? + attr-dict + }]; +} + +//===----------------------------------------------------------------------===// // Atomic operations //===----------------------------------------------------------------------===// @@ -4526,6 +5301,11 @@ def CIR_AtomicFetchKind : CIR_I32EnumAttr< I32EnumAttrCase<"Min", 7, "min"> ]>; +def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [ + I32EnumAttrCase<"SingleThread", 0, "single_thread">, + I32EnumAttrCase<"System", 1, "system"> +]>; + def CIR_AtomicFetchOp : CIR_Op<"atomic.fetch", [ AllTypesMatch<["result", "val"]>, TypesMatchWith<"type of 'val' must match the pointee type of 'ptr'", @@ -4749,4 +5529,68 @@ def CIR_AtomicClearOp : CIR_Op<"atomic.clear"> { }]; } +def CIR_AtomicFence : CIR_Op<"atomic.fence"> { + let summary = "Atomic thread fence"; + let description = [{ + C/C++ Atomic thread fence synchronization primitive. Implements the builtin + `__atomic_thread_fence` which enforces memory ordering constraints across + threads within the specified synchronization scope. + + This handles all variations including: + - `__atomic_thread_fence` + - `__atomic_signal_fence` + - `__c11_atomic_thread_fence` + - `__c11_atomic_signal_fence` + + Example: + ```mlir + cir.atomic.fence syncscope(system) seq_cst + cir.atomic.fence syncscope(single_thread) seq_cst + ``` + }]; + + let arguments = (ins + Arg<CIR_MemOrder, "memory order">:$ordering, + OptionalAttr<CIR_SyncScopeKind>:$syncscope + ); + + let assemblyFormat = [{ + (`syncscope` `(` $syncscope^ `)`)? $ordering attr-dict + }]; +} + +//===----------------------------------------------------------------------===// +// BlockAddressOp +//===----------------------------------------------------------------------===// + +def CIR_BlockAddressOp : CIR_Op<"block_address", [Pure]> { + let summary = "Get the address of a cir.label within a function"; + let description = [{ + The `cir.blockaddress` operation takes a function name and a label and + produces a pointer value that represents the address of that cir.label + within the specified function. + + This operation models GCC's "labels as values" extension (`&&label`), which + allows taking the address of a local label and using it as a computed + jump target (e.g., with `goto *addr;`). + + Example: + ```mlir + %1 = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init] + {alignment = 8 : i64} + %addr = cir.block_address <@c, "label1"> : !cir.ptr<!cir.void> + cir.store align(8) %addr, %1 : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>> + cir.br ^bb1 + ^bb1: + cir.label "label" + ``` + }]; + + let arguments = (ins CIR_BlockAddrInfoAttr:$block_addr_info); + let results = (outs CIR_VoidPtrType:$addr); + let assemblyFormat = [{ + $block_addr_info `:` qualified(type($addr)) attr-dict + }]; +} + #endif // CLANG_CIR_DIALECT_IR_CIROPS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index b2c146c..8976224 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -173,7 +173,7 @@ def CIR_AnyComplexType : CIR_TypeBase<"::cir::ComplexType", "complex type">; def CIR_AnyComplexOrIntOrBoolOrFloatType : AnyTypeOf<[CIR_AnyComplexType, CIR_AnyIntOrBoolOrFloatType], - "complex, integer or floating point type"> { + "complex, integer, boolean or floating point type"> { let cppFunctionName = "isComplexOrIntegerOrBoolOrFloatingPointType"; } @@ -310,6 +310,13 @@ def CIR_AnyFloatOrVecOfFloatType } //===----------------------------------------------------------------------===// +// Data member type predicates +//===----------------------------------------------------------------------===// + +def CIR_AnyDataMemberType : CIR_TypeBase<"::cir::DataMemberType", + "data member type">; + +//===----------------------------------------------------------------------===// // VPtr type predicates //===----------------------------------------------------------------------===// @@ -322,7 +329,8 @@ def CIR_PtrToVPtr : CIR_PtrToType<CIR_AnyVPtrType>; //===----------------------------------------------------------------------===// defvar CIR_ScalarTypes = [ - CIR_AnyBoolType, CIR_AnyIntType, CIR_AnyFloatType, CIR_AnyPtrType + CIR_AnyBoolType, CIR_AnyIntType, CIR_AnyFloatType, CIR_AnyPtrType, + CIR_AnyDataMemberType, CIR_AnyVPtrType ]; def CIR_AnyScalarType : AnyTypeOf<CIR_ScalarTypes, "cir scalar type"> { diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 45f646f..939e774 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -13,7 +13,9 @@ #ifndef CLANG_CIR_DIALECT_IR_CIRTYPES_H #define CLANG_CIR_DIALECT_IR_CIRTYPES_H +#include "mlir/IR/Attributes.h" #include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/MLIRContext.h" #include "mlir/IR/Types.h" #include "mlir/Interfaces/DataLayoutInterfaces.h" #include "clang/Basic/AddressSpaces.h" @@ -38,6 +40,15 @@ bool isValidFundamentalIntWidth(unsigned width); /// void, or abstract types. bool isSized(mlir::Type ty); +//===----------------------------------------------------------------------===// +// AddressSpace helpers +//===----------------------------------------------------------------------===// +cir::TargetAddressSpaceAttr toCIRTargetAddressSpace(mlir::MLIRContext &context, + clang::LangAS langAS); + +bool isMatchingAddressSpace(cir::TargetAddressSpaceAttr cirAS, + clang::LangAS as); + } // namespace cir //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 3131847..59b97f0 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -306,6 +306,36 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [ } //===----------------------------------------------------------------------===// +// CIR_DataMemberType +//===----------------------------------------------------------------------===// + +def CIR_DataMemberType : CIR_Type<"DataMember", "data_member", + [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>] +> { + let summary = "CIR type that represents a pointer-to-data-member in C++"; + let description = [{ + `cir.data_member` models a pointer-to-data-member in C++. Values of this + type are essentially offsets of the pointed-to member within one of its + containing record. + }]; + + let parameters = (ins "mlir::Type":$member_ty, + "cir::RecordType":$class_ty); + + let builders = [ + TypeBuilderWithInferredContext<(ins + "mlir::Type":$member_ty, "cir::RecordType":$class_ty + ), [{ + return $_get(member_ty.getContext(), member_ty, class_ty); + }]>, + ]; + + let assemblyFormat = [{ + `<` $member_ty `in` $class_ty `>` + }]; +} + +//===----------------------------------------------------------------------===// // CIR_VPtrType //===----------------------------------------------------------------------===// @@ -657,6 +687,9 @@ def CIR_RecordType : CIR_Type<"Record", "record", [ } llvm_unreachable("Invalid value for RecordType::getKind()"); } + mlir::Type getElementType(size_t idx) { + return getMembers()[idx]; + } std::string getPrefixedName() { return getKindAsStr() + "." + getName().getValue().str(); } @@ -690,7 +723,7 @@ def CIRRecordType : Type< def CIR_AnyType : AnyTypeOf<[ CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_IntType, CIR_AnyFloatType, CIR_PointerType, CIR_FuncType, CIR_RecordType, - CIR_ComplexType, CIR_VPtrType + CIR_ComplexType, CIR_VPtrType, CIR_DataMemberType ]>; #endif // CLANG_CIR_DIALECT_IR_CIRTYPES_TD diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 48ef8be..b2d9470 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -29,7 +29,6 @@ struct MissingFeatures { // Unhandled global/linkage information. static bool opGlobalThreadLocal() { return false; } - static bool opGlobalConstant() { return false; } static bool opGlobalWeakRef() { return false; } static bool opGlobalUnnamedAddr() { return false; } static bool opGlobalSection() { return false; } @@ -94,6 +93,7 @@ struct MissingFeatures { static bool opFuncNoReturn() { return false; } static bool setFunctionAttributes() { return false; } static bool setLLVMFunctionFEnvAttributes() { return false; } + static bool setFunctionPersonality() { return false; } // CallOp handling static bool opCallAggregateArgs() { return false; } @@ -151,8 +151,10 @@ struct MissingFeatures { // Coroutines static bool coroEndBuiltinCall() { return false; } - static bool coroutineFrame() { return false; } static bool emitBodyAndFallthrough() { return false; } + static bool coroOutsideFrameMD() { return false; } + static bool coroCoReturn() { return false; } + static bool coroCoYield() { return false; } // Various handling of deferred processing in CIRGenModule. static bool cgmRelease() { return false; } @@ -180,13 +182,24 @@ struct MissingFeatures { static bool atomicSyncScopeID() { return false; } static bool atomicTypes() { return false; } static bool atomicUseLibCall() { return false; } + static bool atomicMicrosoftVolatile() { return false; } + static bool atomicOpenMP() { return false; } // Global ctor handling static bool globalCtorLexOrder() { return false; } static bool globalCtorAssociatedData() { return false; } + // LowerModule handling + static bool lowerModuleCodeGenOpts() { return false; } + static bool lowerModuleLangOpts() { return false; } + // Misc + static bool aarch64SIMDIntrinsics() { return false; } + static bool aarch64SMEIntrinsics() { return false; } + static bool aarch64SVEIntrinsics() { return false; } + static bool aarch64TblBuiltinExpr() { return false; } static bool abiArgInfo() { return false; } + static bool addAutoInitAnnotation() { return false; } static bool addHeapAllocSiteMetadata() { return false; } static bool aggEmitFinalDestCopyRValue() { return false; } static bool aggValueSlot() { return false; } @@ -196,6 +209,8 @@ struct MissingFeatures { static bool aggValueSlotMayOverlap() { return false; } static bool aggValueSlotVolatile() { return false; } static bool alignCXXRecordDecl() { return false; } + static bool allocToken() { return false; } + static bool appleKext() { return false; } static bool armComputeVolatileBitfields() { return false; } static bool asmGoto() { return false; } static bool asmInputOperands() { return false; } @@ -213,6 +228,7 @@ struct MissingFeatures { static bool builtinCallMathErrno() { return false; } static bool builtinCheckKind() { return false; } static bool cgCapturedStmtInfo() { return false; } + static bool countedBySize() { return false; } static bool cgFPOptionsRAII() { return false; } static bool checkBitfieldClipping() { return false; } static bool cirgenABIInfo() { return false; } @@ -220,6 +236,7 @@ struct MissingFeatures { static bool cleanupAppendInsts() { return false; } static bool cleanupBranchThrough() { return false; } static bool cleanupIndexAndBIAdjustment() { return false; } + static bool cleanupWithPreservedValues() { return false; } static bool cleanupsToDeactivate() { return false; } static bool constEmitterAggILE() { return false; } static bool constEmitterArrayILE() { return false; } @@ -232,7 +249,6 @@ struct MissingFeatures { static bool ctorConstLvalueToRvalueConversion() { return false; } static bool ctorMemcpyizer() { return false; } static bool cudaSupport() { return false; } - static bool cxxRecordStaticMembers() { return false; } static bool dataLayoutTypeIsSized() { return false; } static bool dataLayoutTypeAllocSize() { return false; } static bool dataLayoutTypeStoreSize() { return false; } @@ -241,7 +257,8 @@ struct MissingFeatures { static bool deleteArray() { return false; } static bool devirtualizeDestructor() { return false; } static bool devirtualizeMemberFunction() { return false; } - static bool ehCleanupFlags() { return false; } + static bool dtorCleanups() { return false; } + static bool ehCleanupActiveFlag() { return false; } static bool ehCleanupHasPrebranchedFallthrough() { return false; } static bool ehCleanupScope() { return false; } static bool ehCleanupScopeRequiresEHCleanup() { return false; } @@ -250,6 +267,7 @@ struct MissingFeatures { static bool emitBranchThroughCleanup() { return false; } static bool emitCheckedInBoundsGEP() { return false; } static bool emitCondLikelihoodViaExpectIntrinsic() { return false; } + static bool emitConstrainedFPCall() { return false; } static bool emitLifetimeMarkers() { return false; } static bool emitLValueAlignmentAssumption() { return false; } static bool emitNullCheckForDeleteCalls() { return false; } @@ -257,6 +275,7 @@ struct MissingFeatures { static bool emitTypeCheck() { return false; } static bool emitTypeMetadataCodeForVCall() { return false; } static bool fastMathFlags() { return false; } + static bool fpConstraints() { return false; } static bool generateDebugInfo() { return false; } static bool globalViewIndices() { return false; } @@ -267,6 +286,7 @@ struct MissingFeatures { static bool innermostEHScope() { return false; } static bool insertBuiltinUnpredictable() { return false; } static bool instrumentation() { return false; } + static bool intrinsicElementTypeSupport() { return false; } static bool intrinsics() { return false; } static bool isMemcpyEquivalentSpecialMember() { return false; } static bool isTrivialCtorOrDtor() { return false; } @@ -276,21 +296,25 @@ struct MissingFeatures { static bool lowerModeOptLevel() { return false; } static bool loweringPrepareX86CXXABI() { return false; } static bool loweringPrepareAArch64XXABI() { return false; } + static bool makeTripleAlwaysPresent() { return false; } static bool maybeHandleStaticInExternC() { return false; } static bool mergeAllConstants() { return false; } static bool metaDataNode() { return false; } static bool moduleNameHash() { return false; } static bool msabi() { return false; } + static bool neonSISDIntrinsics() { return false; } static bool nrvo() { return false; } static bool objCBlocks() { return false; } static bool objCGC() { return false; } static bool objCLifetime() { return false; } static bool hlsl() { return false; } + static bool msvcBuiltins() { return false; } static bool openCL() { return false; } static bool openMP() { return false; } static bool opTBAA() { return false; } static bool peepholeProtection() { return false; } static bool pgoUse() { return false; } + static bool pointerAuthentication() { return false; } static bool pointerOverflowSanitizer() { return false; } static bool preservedAccessIndexRegion() { return false; } static bool requiresCleanups() { return false; } @@ -300,6 +324,10 @@ struct MissingFeatures { static bool setNonGC() { return false; } static bool setObjCGCLValueClass() { return false; } static bool setTargetAttributes() { return false; } + static bool shouldCreateMemCpyFromGlobal() { return false; } + static bool shouldSplitConstantStore() { return false; } + static bool shouldUseBZeroPlusStoresToInitialize() { return false; } + static bool shouldUseMemSetToInitialize() { return false; } static bool simplifyCleanupEntry() { return false; } static bool sourceLanguageCases() { return false; } static bool stackBase() { return false; } @@ -311,16 +339,18 @@ struct MissingFeatures { static bool thunks() { return false; } static bool tryEmitAsConstant() { return false; } static bool typeChecks() { return false; } - static bool weakRefReference() { return false; } - static bool writebacks() { return false; } - static bool appleKext() { return false; } - static bool dtorCleanups() { return false; } + static bool useEHCleanupForArray() { return false; } + static bool vaArgABILowering() { return false; } + static bool vectorConstants() { return false; } + static bool vlas() { return false; } static bool vtableInitialization() { return false; } static bool vtableEmitMetadata() { return false; } static bool vtableRelativeLayout() { return false; } - static bool msvcBuiltins() { return false; } - static bool vaArgABILowering() { return false; } - static bool vlas() { return false; } + static bool weakRefReference() { return false; } + static bool writebacks() { return false; } + static bool msvcCXXPersonality() { return false; } + static bool functionUsesSEHTry() { return false; } + static bool nothrowAttr() { return false; } // Missing types static bool dataMemberType() { return false; } @@ -336,7 +366,6 @@ struct MissingFeatures { static bool awaitOp() { return false; } static bool callOp() { return false; } static bool ifOp() { return false; } - static bool invokeOp() { return false; } static bool labelOp() { return false; } static bool ptrDiffOp() { return false; } static bool llvmLoweringPtrDiffConsidersPointee() { return false; } @@ -346,6 +375,7 @@ struct MissingFeatures { static bool tryOp() { return false; } static bool vecTernaryOp() { return false; } static bool zextOp() { return false; } + static bool catchParamOp() { return false; } // Future CIR attributes static bool optInfoAttr() { return false; } diff --git a/clang/include/clang/CMakeLists.txt b/clang/include/clang/CMakeLists.txt index 47ac70c..77a44e4 100644 --- a/clang/include/clang/CMakeLists.txt +++ b/clang/include/clang/CMakeLists.txt @@ -3,7 +3,7 @@ add_subdirectory(Basic) if(CLANG_ENABLE_CIR) add_subdirectory(CIR) endif() -add_subdirectory(Driver) +add_subdirectory(Options) add_subdirectory(Parse) add_subdirectory(Sema) add_subdirectory(Serialization) diff --git a/clang/include/clang/DependencyScanning/DependencyScannerImpl.h b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h new file mode 100644 index 0000000..352a0ad --- /dev/null +++ b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h @@ -0,0 +1,196 @@ +//===----------------------------------------------------------------------===// +// +// 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 LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNERIMPL_H +#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNERIMPL_H + +#include "clang/DependencyScanning/DependencyScanningFilesystem.h" +#include "clang/DependencyScanning/ModuleDepCollector.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Serialization/ObjectFilePCHContainerReader.h" + +namespace clang { +class DiagnosticConsumer; + +namespace dependencies { +class DependencyScanningService; +class DependencyScanningWorker; + +class DependencyConsumer; +class DependencyActionController; +class DependencyScanningWorkerFilesystem; + +class DependencyScanningAction { +public: + DependencyScanningAction( + DependencyScanningService &Service, StringRef WorkingDirectory, + DependencyConsumer &Consumer, DependencyActionController &Controller, + IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS, + std::optional<StringRef> ModuleName = std::nullopt) + : Service(Service), WorkingDirectory(WorkingDirectory), + Consumer(Consumer), Controller(Controller), DepFS(std::move(DepFS)) {} + bool runInvocation(std::string Executable, + std::unique_ptr<CompilerInvocation> Invocation, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + DiagnosticConsumer *DiagConsumer); + + bool hasScanned() const { return Scanned; } + bool hasDiagConsumerFinished() const { return DiagConsumerFinished; } + +private: + DependencyScanningService &Service; + StringRef WorkingDirectory; + DependencyConsumer &Consumer; + DependencyActionController &Controller; + IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; + std::optional<CompilerInstance> ScanInstanceStorage; + std::shared_ptr<ModuleDepCollector> MDC; + bool Scanned = false; + bool DiagConsumerFinished = false; +}; + +// Helper functions and data types. +std::unique_ptr<DiagnosticOptions> +createDiagOptions(ArrayRef<std::string> CommandLine); + +struct DignosticsEngineWithDiagOpts { + // We need to bound the lifetime of the DiagOpts used to create the + // DiganosticsEngine with the DiagnosticsEngine itself. + std::unique_ptr<DiagnosticOptions> DiagOpts; + IntrusiveRefCntPtr<DiagnosticsEngine> DiagEngine; + + DignosticsEngineWithDiagOpts(ArrayRef<std::string> CommandLine, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, + DiagnosticConsumer &DC); +}; + +struct TextDiagnosticsPrinterWithOutput { + // We need to bound the lifetime of the data that supports the DiagPrinter + // with it together so they have the same lifetime. + std::string DiagnosticOutput; + llvm::raw_string_ostream DiagnosticsOS; + std::unique_ptr<DiagnosticOptions> DiagOpts; + TextDiagnosticPrinter DiagPrinter; + + TextDiagnosticsPrinterWithOutput(ArrayRef<std::string> CommandLine) + : DiagnosticsOS(DiagnosticOutput), + DiagOpts(createDiagOptions(CommandLine)), + DiagPrinter(DiagnosticsOS, *DiagOpts) {} +}; + +std::pair<std::unique_ptr<driver::Driver>, std::unique_ptr<driver::Compilation>> +buildCompilation(ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, + llvm::BumpPtrAllocator &Alloc); + +std::unique_ptr<CompilerInvocation> +createCompilerInvocation(ArrayRef<std::string> CommandLine, + DiagnosticsEngine &Diags); + +std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>> +initVFSForTUBufferScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS, + ArrayRef<std::string> CommandLine, + StringRef WorkingDirectory, + llvm::MemoryBufferRef TUBuffer); + +std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>, + std::vector<std::string>> +initVFSForByNameScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS, + ArrayRef<std::string> CommandLine, + StringRef WorkingDirectory, StringRef ModuleName); + +bool initializeScanCompilerInstance( + CompilerInstance &ScanInstance, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, + DiagnosticConsumer *DiagConsumer, DependencyScanningService &Service, + IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS); + +SmallVector<StringRef> +getInitialStableDirs(const CompilerInstance &ScanInstance); + +std::optional<PrebuiltModulesAttrsMap> +computePrebuiltModulesASTMap(CompilerInstance &ScanInstance, + SmallVector<StringRef> &StableDirs); + +std::unique_ptr<DependencyOutputOptions> +takeAndUpdateDependencyOutputOptionsFrom(CompilerInstance &ScanInstance); + +/// Create the dependency collector that will collect the produced +/// dependencies. May return the created ModuleDepCollector depending +/// on the scanning format. +std::shared_ptr<ModuleDepCollector> initializeScanInstanceDependencyCollector( + CompilerInstance &ScanInstance, + std::unique_ptr<DependencyOutputOptions> DepOutputOpts, + StringRef WorkingDirectory, DependencyConsumer &Consumer, + DependencyScanningService &Service, CompilerInvocation &Inv, + DependencyActionController &Controller, + PrebuiltModulesAttrsMap PrebuiltModulesASTMap, + llvm::SmallVector<StringRef> &StableDirs); + +class CompilerInstanceWithContext { + // Context + DependencyScanningWorker &Worker; + llvm::StringRef CWD; + std::vector<std::string> CommandLine; + + // Context - file systems + llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS; + + // Context - Diagnostics engine. + std::unique_ptr<TextDiagnosticsPrinterWithOutput> DiagPrinterWithOS; + // DiagConsumer may points to DiagPrinterWithOS->DiagPrinter, or a custom + // DiagnosticConsumer passed in from initialize. + DiagnosticConsumer *DiagConsumer = nullptr; + std::unique_ptr<DignosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts; + + // Context - compiler invocation + // Compilation's command's arguments may be owned by Alloc when expanded from + // response files, so we need to keep Alloc alive in the context. + llvm::BumpPtrAllocator Alloc; + std::unique_ptr<clang::driver::Driver> Driver; + std::unique_ptr<clang::driver::Compilation> Compilation; + std::unique_ptr<CompilerInvocation> OriginalInvocation; + + // Context - output options + std::unique_ptr<DependencyOutputOptions> OutputOpts; + + // Context - stable directory handling + llvm::SmallVector<StringRef> StableDirs; + PrebuiltModulesAttrsMap PrebuiltModuleASTMap; + + // Compiler Instance + std::unique_ptr<CompilerInstance> CIPtr; + + // Source location offset. + int32_t SrcLocOffset = 0; + +public: + CompilerInstanceWithContext(DependencyScanningWorker &Worker, StringRef CWD, + const std::vector<std::string> &CMD) + : Worker(Worker), CWD(CWD), CommandLine(CMD) {}; + + // The three methods below returns false when they fail, with the detail + // accumulated in DiagConsumer. + bool initialize(DiagnosticConsumer *DC); + bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer, + DependencyActionController &Controller); + bool finalize(); + + // The method below turns the return status from the above methods + // into an llvm::Error using a default DiagnosticConsumer. + llvm::Error handleReturnStatus(bool Success); +}; +} // namespace dependencies +} // namespace clang + +#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNERIMPL_H diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h b/clang/include/clang/DependencyScanning/DependencyScanningFilesystem.h index 2b21be7..2162222 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ b/clang/include/clang/DependencyScanning/DependencyScanningFilesystem.h @@ -1,4 +1,4 @@ -//===- DependencyScanningFilesystem.h - clang-scan-deps fs ===---*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H +#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H #include "clang/Basic/LLVM.h" #include "clang/Lex/DependencyDirectivesScanner.h" @@ -21,7 +21,6 @@ #include <variant> namespace clang { -namespace tooling { namespace dependencies { using DependencyDirectivesTy = @@ -521,7 +520,6 @@ private: }; } // end namespace dependencies -} // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H +#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/DependencyScanning/DependencyScanningService.h index 4e97c7b..371b862 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ b/clang/include/clang/DependencyScanning/DependencyScanningService.h @@ -1,4 +1,4 @@ -//===- DependencyScanningService.h - clang-scan-deps service ===-*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,16 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H +#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H -#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h" -#include "clang/Tooling/DependencyScanning/InProcessModuleCache.h" +#include "clang/DependencyScanning/DependencyScanningFilesystem.h" +#include "clang/DependencyScanning/InProcessModuleCache.h" #include "llvm/ADT/BitmaskEnum.h" #include "llvm/Support/Chrono.h" namespace clang { -namespace tooling { namespace dependencies { /// The mode in which the dependency scanner will operate to find the @@ -125,7 +124,6 @@ private: }; } // end namespace dependencies -} // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H +#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/DependencyScanning/DependencyScanningUtils.h index f222ded..124f1ea 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/clang/include/clang/DependencyScanning/DependencyScanningUtils.h @@ -1,4 +1,4 @@ -//===- DependencyScanningTool.h - clang-scan-deps service -----------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,29 +6,20 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGUTILS_H +#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGUTILS_H -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" -#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" -#include "clang/Tooling/JSONCompilationDatabase.h" +#include "clang/DependencyScanning/DependencyScannerImpl.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" +#include "clang/DependencyScanning/ModuleDepCollector.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" -#include "llvm/ADT/STLExtras.h" -#include <functional> -#include <optional> #include <string> #include <vector> namespace clang { -namespace tooling { namespace dependencies { -/// A callback to lookup module outputs for "-fmodule-file=", "-o" etc. -using LookupModuleOutputCallback = - llvm::function_ref<std::string(const ModuleDeps &, ModuleOutputKind)>; - /// Graph of modular dependencies. using ModuleDepsGraph = std::vector<ModuleDeps>; @@ -76,95 +67,6 @@ struct TranslationUnitDeps { std::vector<std::string> DriverCommandLine; }; -struct P1689Rule { - std::string PrimaryOutput; - std::optional<P1689ModuleInfo> Provides; - std::vector<P1689ModuleInfo> Requires; -}; - -/// The high-level implementation of the dependency discovery tool that runs on -/// an individual worker thread. -class DependencyScanningTool { -public: - /// Construct a dependency scanning tool. - /// - /// @param Service The parent service. Must outlive the tool. - /// @param FS The filesystem for the tool to use. Defaults to the physical FS. - DependencyScanningTool(DependencyScanningService &Service, - llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = - llvm::vfs::createPhysicalFileSystem()); - - /// Print out the dependency information into a string using the dependency - /// file format that is specified in the options (-MD is the default) and - /// return it. - /// - /// \returns A \c StringError with the diagnostic output if clang errors - /// occurred, dependency file contents otherwise. - llvm::Expected<std::string> - getDependencyFile(const std::vector<std::string> &CommandLine, StringRef CWD); - - /// Collect the module dependency in P1689 format for C++20 named modules. - /// - /// \param MakeformatOutput The output parameter for dependency information - /// in make format if the command line requires to generate make-format - /// dependency information by `-MD -MF <dep_file>`. - /// - /// \param MakeformatOutputPath The output parameter for the path to - /// \param MakeformatOutput. - /// - /// \returns A \c StringError with the diagnostic output if clang errors - /// occurred, P1689 dependency format rules otherwise. - llvm::Expected<P1689Rule> - getP1689ModuleDependencyFile(const clang::tooling::CompileCommand &Command, - StringRef CWD, std::string &MakeformatOutput, - std::string &MakeformatOutputPath); - llvm::Expected<P1689Rule> - getP1689ModuleDependencyFile(const clang::tooling::CompileCommand &Command, - StringRef CWD) { - std::string MakeformatOutput; - std::string MakeformatOutputPath; - - return getP1689ModuleDependencyFile(Command, CWD, MakeformatOutput, - MakeformatOutputPath); - } - - /// Given a Clang driver command-line for a translation unit, gather the - /// modular dependencies and return the information needed for explicit build. - /// - /// \param AlreadySeen This stores modules which have previously been - /// reported. Use the same instance for all calls to this - /// function for a single \c DependencyScanningTool in a - /// single build. Use a different one for different tools, - /// and clear it between builds. - /// \param LookupModuleOutput This function is called to fill in - /// "-fmodule-file=", "-o" and other output - /// arguments for dependencies. - /// \param TUBuffer Optional memory buffer for translation unit input. If - /// TUBuffer is nullopt, the input should be included in the - /// Commandline already. - /// - /// \returns a \c StringError with the diagnostic output if clang errors - /// occurred, \c TranslationUnitDeps otherwise. - llvm::Expected<TranslationUnitDeps> getTranslationUnitDependencies( - const std::vector<std::string> &CommandLine, StringRef CWD, - const llvm::DenseSet<ModuleID> &AlreadySeen, - LookupModuleOutputCallback LookupModuleOutput, - std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt); - - /// Given a compilation context specified via the Clang driver command-line, - /// gather modular dependencies of module with the given name, and return the - /// information needed for explicit build. - llvm::Expected<TranslationUnitDeps> getModuleDependencies( - StringRef ModuleName, const std::vector<std::string> &CommandLine, - StringRef CWD, const llvm::DenseSet<ModuleID> &AlreadySeen, - LookupModuleOutputCallback LookupModuleOutput); - - llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); } - -private: - DependencyScanningWorker Worker; -}; - class FullDependencyConsumer : public DependencyConsumer { public: FullDependencyConsumer(const llvm::DenseSet<ModuleID> &AlreadySeen) @@ -223,6 +125,10 @@ private: const llvm::DenseSet<ModuleID> &AlreadySeen; }; +/// A callback to lookup module outputs for "-fmodule-file=", "-o" etc. +using LookupModuleOutputCallback = + llvm::function_ref<std::string(const ModuleDeps &, ModuleOutputKind)>; + /// A simple dependency action controller that uses a callback. If no callback /// is provided, it is assumed that looking up module outputs is unreachable. class CallbackActionController : public DependencyActionController { @@ -251,7 +157,6 @@ private: }; } // end namespace dependencies -} // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H +#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGUTILS_H diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h index 6060e4b..ebd7d42 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h @@ -1,4 +1,4 @@ -//===- DependencyScanningWorker.h - clang-scan-deps worker ===---*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H +#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" +#include "clang/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/ModuleDepCollector.h" #include "clang/Frontend/PCHContainerOperations.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" -#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBufferRef.h" @@ -25,10 +25,10 @@ namespace clang { class DependencyOutputOptions; -namespace tooling { namespace dependencies { class DependencyScanningWorkerFilesystem; +class CompilerInstanceWithContext; /// A command-line tool invocation that is part of building a TU. /// @@ -85,9 +85,11 @@ public: /// Construct a dependency scanning worker. /// /// @param Service The parent service. Must outlive the worker. - /// @param FS The filesystem for the worker to use. + /// @param BaseFS The filesystem for the worker to use. DependencyScanningWorker(DependencyScanningService &Service, - llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS); + IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS); + + ~DependencyScanningWorker(); /// Run the dependency scanning tool for a given clang driver command-line, /// and report the discovered dependencies to the provided consumer. If @@ -98,71 +100,85 @@ public: /// \returns false if clang errors occurred (with diagnostics reported to /// \c DiagConsumer), true otherwise. bool computeDependencies( - StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, + StringRef WorkingDirectory, ArrayRef<std::string> CommandLine, DependencyConsumer &DepConsumer, DependencyActionController &Controller, DiagnosticConsumer &DiagConsumer, std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt); /// Run the dependency scanning tool for a given clang driver command-line - /// for a specific module. - /// - /// \returns false if clang errors occurred (with diagnostics reported to - /// \c DiagConsumer), true otherwise. - bool computeDependencies(StringRef WorkingDirectory, - const std::vector<std::string> &CommandLine, - DependencyConsumer &DepConsumer, - DependencyActionController &Controller, - DiagnosticConsumer &DiagConsumer, - StringRef ModuleName); - - /// Run the dependency scanning tool for a given clang driver command-line /// for a specific translation unit via file system or memory buffer. /// /// \returns A \c StringError with the diagnostic output if clang errors /// occurred, success otherwise. llvm::Error computeDependencies( - StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, + StringRef WorkingDirectory, ArrayRef<std::string> CommandLine, DependencyConsumer &Consumer, DependencyActionController &Controller, std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt); - /// Run the dependency scanning tool for a given clang driver command-line - /// for a specific module. - /// - /// \returns A \c StringError with the diagnostic output if clang errors - /// occurred, success otherwise. - llvm::Error computeDependencies(StringRef WorkingDirectory, - const std::vector<std::string> &CommandLine, - DependencyConsumer &Consumer, - DependencyActionController &Controller, - StringRef ModuleName); - - llvm::vfs::FileSystem &getVFS() const { return *BaseFS; } + /// The three method below implements a new interface for by name + /// dependency scanning. They together enable the dependency scanning worker + /// to more effectively perform scanning for a sequence of modules + /// by name when the CWD and CommandLine do not change across the queries. + + /// @brief Initializing the context and the compiler instance. + /// @param CWD The current working directory used during the scan. + /// @param CommandLine The commandline used for the scan. + /// @return Error if the initializaiton fails. + llvm::Error initializeCompilerInstanceWithContextOrError( + StringRef CWD, ArrayRef<std::string> CommandLine); + + /// @brief Performaces dependency scanning for the module whose name is + /// specified. + /// @param ModuleName The name of the module whose dependency will be + /// scanned. + /// @param Consumer The dependency consumer that stores the results. + /// @param Controller The controller for the dependency scanning action. + /// @return Error if the scanner incurs errors. + llvm::Error computeDependenciesByNameWithContextOrError( + StringRef ModuleName, DependencyConsumer &Consumer, + DependencyActionController &Controller); + + /// @brief Finalizes the diagnostics engine and deletes the compiler instance. + /// @return Error if errors occur during finalization. + llvm::Error finalizeCompilerInstanceWithContextOrError(); + + /// The three methods below provides the same functionality as the + /// three methods above. Instead of returning `llvm::Error`s, these + /// three methods return a flag to indicate if the call is successful. + /// The initialization function asks the client for a DiagnosticsConsumer + /// that it direct the diagnostics to. + bool initializeCompilerInstanceWithContext(StringRef CWD, + ArrayRef<std::string> CommandLine, + DiagnosticConsumer *DC = nullptr); + bool + computeDependenciesByNameWithContext(StringRef ModuleName, + DependencyConsumer &Consumer, + DependencyActionController &Controller); + bool finalizeCompilerInstance(); + + llvm::vfs::FileSystem &getVFS() const { return *DepFS; } private: /// The parent dependency scanning service. DependencyScanningService &Service; std::shared_ptr<PCHContainerOperations> PCHContainerOps; - /// The file system to be used during the scan. - /// This is either \c FS passed in the constructor (when performing canonical - /// preprocessing), or \c DepFS (when performing dependency directives scan). - llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS; - /// When performing dependency directives scan, this is the caching (and - /// dependency-directives-extracting) filesystem overlaid on top of \c FS - /// (passed in the constructor). - llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; - - /// Private helper functions. - bool scanDependencies(StringRef WorkingDirectory, - const std::vector<std::string> &CommandLine, - DependencyConsumer &Consumer, - DependencyActionController &Controller, - DiagnosticConsumer &DC, - llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, - std::optional<StringRef> ModuleName); + /// This is the caching (and optionally dependency-directives-providing) VFS + /// overlaid on top of the base VFS passed in the constructor. + IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; + + friend CompilerInstanceWithContext; + std::unique_ptr<CompilerInstanceWithContext> CIWithContext; + + /// Actually carries out the scan. If \c OverlayFS is provided, it must be + /// based on top of DepFS. + bool scanDependencies( + StringRef WorkingDirectory, ArrayRef<std::string> CommandLine, + DependencyConsumer &Consumer, DependencyActionController &Controller, + DiagnosticConsumer &DC, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS = nullptr); }; } // end namespace dependencies -} // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H +#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H diff --git a/clang/include/clang/Tooling/DependencyScanning/InProcessModuleCache.h b/clang/include/clang/DependencyScanning/InProcessModuleCache.h index 213e60b..0585348 100644 --- a/clang/include/clang/Tooling/DependencyScanning/InProcessModuleCache.h +++ b/clang/include/clang/DependencyScanning/InProcessModuleCache.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H +#define LLVM_CLANG_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H #include "clang/Serialization/ModuleCache.h" #include "llvm/ADT/StringMap.h" @@ -16,8 +16,8 @@ #include <shared_mutex> namespace clang { -namespace tooling { namespace dependencies { + struct ModuleCacheEntry { std::shared_mutex CompilationMutex; std::atomic<std::time_t> Timestamp = 0; @@ -30,8 +30,8 @@ struct ModuleCacheEntries { IntrusiveRefCntPtr<ModuleCache> makeInProcessModuleCache(ModuleCacheEntries &Entries); + } // namespace dependencies -} // namespace tooling } // namespace clang -#endif +#endif // LLVM_CLANG_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/DependencyScanning/ModuleDepCollector.h index 4136cb7..8f665da 100644 --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/DependencyScanning/ModuleDepCollector.h @@ -1,4 +1,4 @@ -//===- ModuleDepCollector.h - Callbacks to collect deps ---------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,18 +6,18 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H +#define LLVM_CLANG_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H #include "clang/Basic/LLVM.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" +#include "clang/DependencyScanning/DependencyScanningService.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/Utils.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Serialization/ASTReader.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringSet.h" @@ -28,7 +28,6 @@ #include <variant> namespace clang { -namespace tooling { namespace dependencies { class DependencyActionController; @@ -109,7 +108,7 @@ struct ModuleID { std::tie(Other.ModuleName, Other.ContextHash); } - bool operator<(const ModuleID& Other) const { + bool operator<(const ModuleID &Other) const { return std::tie(ModuleName, ContextHash) < std::tie(Other.ModuleName, Other.ContextHash); } @@ -264,10 +263,11 @@ private: /// Traverses the affecting modules and updates \c MD with references to the /// parent \c ModuleDepCollector info. - void addAllAffectingClangModules(const Module *M, ModuleDeps &MD, + void + addAllAffectingClangModules(const Module *M, ModuleDeps &MD, llvm::DenseSet<const Module *> &AddedModules); void addAffectingClangModule(const Module *M, ModuleDeps &MD, - llvm::DenseSet<const Module *> &AddedModules); + llvm::DenseSet<const Module *> &AddedModules); /// Add discovered module dependency for the given module. void addOneModuleDep(const Module *M, const ModuleID ID, ModuleDeps &MD); @@ -288,6 +288,8 @@ public: void attachToPreprocessor(Preprocessor &PP) override; void attachToASTReader(ASTReader &R) override; + PPCallbacks *getPPCallbacks() { return CollectorPPPtr; } + /// Apply any changes implied by the discovered dependencies to the given /// invocation, (e.g. disable implicit modules, add explicit module paths). void applyDiscoveredDependencies(CompilerInvocation &CI); @@ -339,6 +341,11 @@ private: std::optional<P1689ModuleInfo> ProvidedStdCXXModule; std::vector<P1689ModuleInfo> RequiredStdCXXModules; + /// A pointer to the preprocessor callback so we can invoke it directly + /// if needed. The callback is created and added to a Preprocessor instance by + /// attachToPreprocessor and the Preprocessor instance owns it. + ModuleDepCollectorPP *CollectorPPPtr = nullptr; + /// Checks whether the module is known as being prebuilt. bool isPrebuiltModule(const Module *M); @@ -399,16 +406,15 @@ bool areOptionsInStableDir(const ArrayRef<StringRef> Directories, const HeaderSearchOptions &HSOpts); } // end namespace dependencies -} // end namespace tooling } // end namespace clang namespace llvm { -inline hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID) { +inline hash_code hash_value(const clang::dependencies::ModuleID &ID) { return hash_combine(ID.ModuleName, ID.ContextHash); } -template <> struct DenseMapInfo<clang::tooling::dependencies::ModuleID> { - using ModuleID = clang::tooling::dependencies::ModuleID; +template <> struct DenseMapInfo<clang::dependencies::ModuleID> { + using ModuleID = clang::dependencies::ModuleID; static inline ModuleID getEmptyKey() { return ModuleID{"", ""}; } static inline ModuleID getTombstoneKey() { return ModuleID{"~", "~"}; // ~ is not a valid module name or context hash @@ -420,4 +426,4 @@ template <> struct DenseMapInfo<clang::tooling::dependencies::ModuleID> { }; } // namespace llvm -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H +#endif // LLVM_CLANG_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H diff --git a/clang/include/clang/Driver/CommonArgs.h b/clang/include/clang/Driver/CommonArgs.h index ac17d62..264bd49 100644 --- a/clang/include/clang/Driver/CommonArgs.h +++ b/clang/include/clang/Driver/CommonArgs.h @@ -291,16 +291,6 @@ void handleVectorizeLoopsArgs(const llvm::opt::ArgList &Args, void handleVectorizeSLPArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs); -// Parse -mprefer-vector-width=. Return the Value string if well-formed. -// Otherwise, return an empty string and issue a diagnosic message if needed. -StringRef parseMPreferVectorWidthOption(clang::DiagnosticsEngine &Diags, - const llvm::opt::ArgList &Args); - -// Parse -mrecip. Return the Value string if well-formed. -// Otherwise, return an empty string and issue a diagnosic message if needed. -StringRef parseMRecipOption(clang::DiagnosticsEngine &Diags, - const llvm::opt::ArgList &Args); - // Convert ComplexRangeKind to a string that can be passed as a frontend option. std::string complexRangeKindToStr(LangOptions::ComplexRangeKind Range); diff --git a/clang/include/clang/Driver/CreateASTUnitFromArgs.h b/clang/include/clang/Driver/CreateASTUnitFromArgs.h new file mode 100644 index 0000000..30575cc --- /dev/null +++ b/clang/include/clang/Driver/CreateASTUnitFromArgs.h @@ -0,0 +1,80 @@ +//===-- CreateInvocationFromArgs.h - Create an ASTUnit from Args-*- 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 +// +//===----------------------------------------------------------------------===// +// +// Utility for creating an ASTUnit from a vector of command line arguments. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DRIVER_CREATEASTUNITFROMARGS_H +#define LLVM_CLANG_DRIVER_CREATEASTUNITFROMARGS_H + +#include "clang/Frontend/ASTUnit.h" + +namespace clang { + +/// Create an ASTUnit from a vector of command line arguments, which must +/// specify exactly one source file. +/// +/// \param ArgBegin - The beginning of the argument vector. +/// +/// \param ArgEnd - The end of the argument vector. +/// +/// \param PCHContainerOps - The PCHContainerOperations to use for loading and +/// creating modules. +/// +/// \param Diags - The diagnostics engine to use for reporting errors; its +/// lifetime is expected to extend past that of the returned ASTUnit. +/// +/// \param ResourceFilesPath - The path to the compiler resource files. +/// +/// \param StorePreamblesInMemory - Whether to store PCH in memory. If false, +/// PCH are stored in temporary files. +/// +/// \param PreambleStoragePath - The path to a directory, in which to create +/// temporary PCH files. If empty, the default system temporary directory is +/// used. This parameter is ignored if \p StorePreamblesInMemory is true. +/// +/// \param ModuleFormat - If provided, uses the specific module format. +/// +/// \param ErrAST - If non-null and parsing failed without any AST to return +/// (e.g. because the PCH could not be loaded), this accepts the ASTUnit +/// mainly to allow the caller to see the diagnostics. +/// +/// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses. +/// Note that preamble is saved to a temporary directory on a RealFileSystem, +/// so in order for it to be loaded correctly, VFS should have access to +/// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used +/// if \p VFS is nullptr. +/// +// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we +// shouldn't need to specify them at construction time. +std::unique_ptr<ASTUnit> CreateASTUnitFromCommandLine( + const char **ArgBegin, const char **ArgEnd, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + std::shared_ptr<DiagnosticOptions> DiagOpts, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath, + bool StorePreamblesInMemory = false, + StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false, + CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, + ArrayRef<ASTUnit::RemappedFile> RemappedFiles = {}, + bool RemappedFilesKeepOriginalName = true, + unsigned PrecompilePreambleAfterNParses = 0, + TranslationUnitKind TUKind = TU_Complete, + bool CacheCodeCompletionResults = false, + bool IncludeBriefCommentsInCodeCompletion = false, + bool AllowPCHWithCompilerErrors = false, + SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None, + bool SingleFileParse = false, bool UserFilesAreVolatile = false, + bool ForSerialization = false, bool RetainExcludedConditionalBlocks = false, + std::optional<StringRef> ModuleFormat = std::nullopt, + std::unique_ptr<ASTUnit> *ErrAST = nullptr, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); + +} // namespace clang + +#endif // LLVM_CLANG_DRIVER_CREATEASTUNITFROMARGS_H diff --git a/clang/include/clang/Driver/CreateInvocationFromArgs.h b/clang/include/clang/Driver/CreateInvocationFromArgs.h new file mode 100644 index 0000000..0e0f673 --- /dev/null +++ b/clang/include/clang/Driver/CreateInvocationFromArgs.h @@ -0,0 +1,76 @@ +//===--- CreateInvocationFromArgs.h - CompilerInvocation from Args --------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Utility for creating a CompilerInvocation from command-line arguments, for +// tools to use in preparation to parse a file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DRIVER_CREATEINVOCATIONFROMARGS_H +#define LLVM_CLANG_DRIVER_CREATEINVOCATIONFROMARGS_H + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/LLVM.h" +#include "llvm/Support/VirtualFileSystem.h" +#include <memory> +#include <string> +#include <vector> + +namespace clang { + +class CompilerInvocation; +class DiagnosticsEngine; + +/// Optional inputs to createInvocation. +struct CreateInvocationOptions { + /// Receives diagnostics encountered while parsing command-line flags. + /// If not provided, these are printed to stderr. + IntrusiveRefCntPtr<DiagnosticsEngine> Diags = nullptr; + /// Used e.g. to probe for system headers locations. + /// If not provided, the real filesystem is used. + /// FIXME: the driver does perform some non-virtualized IO. + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr; + /// Whether to attempt to produce a non-null (possibly incorrect) invocation + /// if any errors were encountered. + /// By default, always return null on errors. + bool RecoverOnError = false; + /// Allow the driver to probe the filesystem for PCH files. + /// This is used to replace -include with -include-pch in the cc1 args. + /// FIXME: ProbePrecompiled=true is a poor, historical default. + /// It misbehaves if the PCH file is from GCC, has the wrong version, etc. + bool ProbePrecompiled = false; + /// If set, the target is populated with the cc1 args produced by the driver. + /// This may be populated even if createInvocation returns nullptr. + std::vector<std::string> *CC1Args = nullptr; +}; + +/// Interpret clang arguments in preparation to parse a file. +/// +/// This simulates a number of steps Clang takes when its driver is invoked: +/// - choosing actions (e.g compile + link) to run +/// - probing the system for settings like standard library locations +/// - spawning a cc1 subprocess to compile code, with more explicit arguments +/// - in the cc1 process, assembling those arguments into a CompilerInvocation +/// which is used to configure the parser +/// +/// This simulation is lossy, e.g. in some situations one driver run would +/// result in multiple parses. (Multi-arch, CUDA, ...). +/// This function tries to select a reasonable invocation that tools should use. +/// +/// Args[0] should be the driver name, such as "clang" or "/usr/bin/g++". +/// Absolute path is preferred - this affects searching for system headers. +/// +/// May return nullptr if an invocation could not be determined. +/// See CreateInvocationOptions::RecoverOnError to try harder! +std::unique_ptr<CompilerInvocation> +createInvocation(ArrayRef<const char *> Args, + CreateInvocationOptions Opts = {}); + +} // namespace clang + +#endif // LLVM_CLANG_DRIVER_CREATEINVOCATIONFROMARGS_H diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index b9b187a..76a6c5a 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -15,11 +15,11 @@ #include "clang/Driver/Action.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/InputInfo.h" -#include "clang/Driver/Options.h" #include "clang/Driver/Phases.h" #include "clang/Driver/ToolChain.h" #include "clang/Driver/Types.h" #include "clang/Driver/Util.h" +#include "clang/Options/Options.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/StringMap.h" @@ -406,11 +406,6 @@ private: SmallString<128> &CrashDiagDir); public: - - /// Takes the path to a binary that's either in bin/ or lib/ and returns - /// the path to clang's resource directory. - static std::string GetResourcesPath(StringRef BinaryPath); - Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title = "clang LLVM compiler", IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index eea7897..84fb66e 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -67,6 +67,8 @@ class SanitizerArgs { bool TsanFuncEntryExit = true; bool TsanAtomics = true; bool MinimalRuntime = false; + bool TysanOutlineInstrumentation = true; + bool HandlerPreserveAllRegs = false; // True if cross-dso CFI support if provided by the system (i.e. Android). bool ImplicitCfiRuntime = false; bool NeedsMemProfRt = false; diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index f246def..c7e57d4 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -601,9 +601,19 @@ struct FormatStyle { /// int abcdef; // but this isn't /// \endcode unsigned OverEmptyLines; + /// If comments following preprocessor directive should be aligned with + /// comments that don't. + /// \code + /// true: false: + /// #define A // Comment vs. #define A // Comment + /// #define AB // Aligned #define AB // Aligned + /// int i; // Aligned int i; // Not aligned + /// \endcode + bool AlignPPAndNotPP; bool operator==(const TrailingCommentsAlignmentStyle &R) const { - return Kind == R.Kind && OverEmptyLines == R.OverEmptyLines; + return Kind == R.Kind && OverEmptyLines == R.OverEmptyLines && + AlignPPAndNotPP == R.AlignPPAndNotPP; } bool operator!=(const TrailingCommentsAlignmentStyle &R) const { return !(*this == R); @@ -3265,9 +3275,20 @@ struct FormatStyle { /// Hex: -1 /// \endcode /// - /// You can also specify a minimum number of digits (``BinaryMinDigits``, - /// ``DecimalMinDigits``, and ``HexMinDigits``) the integer literal must - /// have in order for the separators to be inserted. + /// You can also specify a minimum number of digits + /// (``BinaryMinDigitsInsert``, ``DecimalMinDigitsInsert``, and + /// ``HexMinDigitsInsert``) the integer literal must have in order for the + /// separators to be inserted, and a maximum number of digits + /// (``BinaryMaxDigitsRemove``, ``DecimalMaxDigitsRemove``, and + /// ``HexMaxDigitsRemove``) until the separators are removed. This divides the + /// literals in 3 regions, always without separator (up until including + /// ``xxxMaxDigitsRemove``), maybe with, or without separators (up until + /// excluding ``xxxMinDigitsInsert``), and finally always with separators. + /// \note + /// ``BinaryMinDigits``, ``DecimalMinDigits``, and ``HexMinDigits`` are + /// deprecated and renamed to ``BinaryMinDigitsInsert``, + /// ``DecimalMinDigitsInsert``, and ``HexMinDigitsInsert``, respectively. + /// \endnote struct IntegerLiteralSeparatorStyle { /// Format separators in binary literals. /// \code{.text} @@ -3280,11 +3301,23 @@ struct FormatStyle { /// Format separators in binary literals with a minimum number of digits. /// \code{.text} /// // Binary: 3 - /// // BinaryMinDigits: 7 + /// // BinaryMinDigitsInsert: 7 /// b1 = 0b101101; /// b2 = 0b1'101'101; /// \endcode - int8_t BinaryMinDigits; + int8_t BinaryMinDigitsInsert; + /// Remove separators in binary literals with a maximum number of digits. + /// \code{.text} + /// // Binary: 3 + /// // BinaryMinDigitsInsert: 7 + /// // BinaryMaxDigitsRemove: 4 + /// b0 = 0b1011; // Always removed. + /// b1 = 0b101101; // Not added. + /// b2 = 0b1'01'101; // Not removed, not corrected. + /// b3 = 0b1'101'101; // Always added. + /// b4 = 0b10'1101; // Corrected to 0b101'101. + /// \endcode + int8_t BinaryMaxDigitsRemove; /// Format separators in decimal literals. /// \code{.text} /// /* -1: */ d = 18446744073709550592ull; @@ -3295,11 +3328,23 @@ struct FormatStyle { /// Format separators in decimal literals with a minimum number of digits. /// \code{.text} /// // Decimal: 3 - /// // DecimalMinDigits: 5 + /// // DecimalMinDigitsInsert: 5 /// d1 = 2023; /// d2 = 10'000; /// \endcode - int8_t DecimalMinDigits; + int8_t DecimalMinDigitsInsert; + /// Remove separators in decimal literals with a maximum number of digits. + /// \code{.text} + /// // Decimal: 3 + /// // DecimalMinDigitsInsert: 7 + /// // DecimalMaxDigitsRemove: 4 + /// d0 = 2023; // Always removed. + /// d1 = 123456; // Not added. + /// d2 = 1'23'456; // Not removed, not corrected. + /// d3 = 5'000'000; // Always added. + /// d4 = 1'23'45; // Corrected to 12'345. + /// \endcode + int8_t DecimalMaxDigitsRemove; /// Format separators in hexadecimal literals. /// \code{.text} /// /* -1: */ h = 0xDEADBEEFDEADBEEFuz; @@ -3311,15 +3356,36 @@ struct FormatStyle { /// digits. /// \code{.text} /// // Hex: 2 - /// // HexMinDigits: 6 + /// // HexMinDigitsInsert: 6 /// h1 = 0xABCDE; /// h2 = 0xAB'CD'EF; /// \endcode - int8_t HexMinDigits; + int8_t HexMinDigitsInsert; + /// Remove separators in hexadecimal literals with a maximum number of + /// digits. + /// \code{.text} + /// // Hex: 2 + /// // HexMinDigitsInsert: 6 + /// // HexMaxDigitsRemove: 4 + /// h0 = 0xAFFE; // Always removed. + /// h1 = 0xABCDE; // Not added. + /// h2 = 0xABC'DE; // Not removed, not corrected. + /// h3 = 0xAB'CD'EF; // Always added. + /// h4 = 0xABCD'E; // Corrected to 0xA'BC'DE. + /// \endcode + int8_t HexMaxDigitsRemove; bool operator==(const IntegerLiteralSeparatorStyle &R) const { - return Binary == R.Binary && BinaryMinDigits == R.BinaryMinDigits && - Decimal == R.Decimal && DecimalMinDigits == R.DecimalMinDigits && - Hex == R.Hex && HexMinDigits == R.HexMinDigits; + return Binary == R.Binary && + BinaryMinDigitsInsert == R.BinaryMinDigitsInsert && + BinaryMaxDigitsRemove == R.BinaryMaxDigitsRemove && + Decimal == R.Decimal && + DecimalMinDigitsInsert == R.DecimalMinDigitsInsert && + DecimalMaxDigitsRemove == R.DecimalMaxDigitsRemove && + Hex == R.Hex && HexMinDigitsInsert == R.HexMinDigitsInsert && + HexMaxDigitsRemove == R.HexMaxDigitsRemove; + } + bool operator!=(const IntegerLiteralSeparatorStyle &R) const { + return !operator==(R); } }; diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 3cea159..341460e 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -22,12 +22,14 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetOptions.h" +#include "clang/Frontend/PrecompiledPreamble.h" +#include "clang/Frontend/StandaloneDiagnostic.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/ModuleLoader.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Serialization/ASTBitCodes.h" -#include "clang/Frontend/PrecompiledPreamble.h" +#include "clang/Serialization/ASTWriter.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -36,6 +38,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Bitstream/BitstreamWriter.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -88,25 +91,6 @@ enum class CaptureDiagsKind { None, All, AllWithoutNonErrorsFromIncludes }; /// Utility class for loading a ASTContext from an AST file. class ASTUnit { -public: - struct StandaloneFixIt { - std::pair<unsigned, unsigned> RemoveRange; - std::pair<unsigned, unsigned> InsertFromRange; - std::string CodeToInsert; - bool BeforePreviousInsertions; - }; - - struct StandaloneDiagnostic { - unsigned ID; - DiagnosticsEngine::Level Level; - std::string Message; - std::string Filename; - unsigned LocOffset; - std::vector<std::pair<unsigned, unsigned>> Ranges; - std::vector<StandaloneFixIt> FixIts; - }; - -private: std::unique_ptr<LangOptions> LangOpts; std::unique_ptr<CodeGenOptions> CodeGenOpts; // FIXME: The documentation on \c LoadFrom* member functions states that the @@ -129,7 +113,15 @@ private: bool HadModuleLoaderFatalFailure = false; bool StorePreamblesInMemory = false; - struct ASTWriterData; + /// Utility struct for managing ASTWriter and its associated data streams. + struct ASTWriterData { + SmallString<128> Buffer; + llvm::BitstreamWriter Stream; + ASTWriter Writer; + + ASTWriterData(ModuleCache &ModCache, const CodeGenOptions &CGOpts) + : Stream(Buffer), Writer(Stream, Buffer, ModCache, CGOpts, {}) {} + }; std::unique_ptr<ASTWriterData> WriterData; FileSystemOptions FileSystemOpts; @@ -271,11 +263,6 @@ private: static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags, ASTUnit &AST, CaptureDiagsKind CaptureDiagnostics); - void TranslateStoredDiagnostics(FileManager &FileMgr, - SourceManager &SrcMan, - const SmallVectorImpl<StandaloneDiagnostic> &Diags, - SmallVectorImpl<StoredDiagnostic> &Out); - void clearFileLevelDecls(); public: @@ -834,65 +821,24 @@ public: bool IncludeBriefCommentsInCodeCompletion = false, bool UserFilesAreVolatile = false); - /// LoadFromCommandLine - Create an ASTUnit from a vector of command line - /// arguments, which must specify exactly one source file. - /// - /// \param ArgBegin - The beginning of the argument vector. - /// - /// \param ArgEnd - The end of the argument vector. - /// - /// \param PCHContainerOps - The PCHContainerOperations to use for loading and - /// creating modules. - /// - /// \param Diags - The diagnostics engine to use for reporting errors; its - /// lifetime is expected to extend past that of the returned ASTUnit. - /// - /// \param ResourceFilesPath - The path to the compiler resource files. - /// - /// \param StorePreamblesInMemory - Whether to store PCH in memory. If false, - /// PCH are stored in temporary files. - /// - /// \param PreambleStoragePath - The path to a directory, in which to create - /// temporary PCH files. If empty, the default system temporary directory is - /// used. This parameter is ignored if \p StorePreamblesInMemory is true. - /// - /// \param ModuleFormat - If provided, uses the specific module format. - /// - /// \param ErrAST - If non-null and parsing failed without any AST to return - /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit - /// mainly to allow the caller to see the diagnostics. - /// - /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses. - /// Note that preamble is saved to a temporary directory on a RealFileSystem, - /// so in order for it to be loaded correctly, VFS should have access to - /// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used - /// if \p VFS is nullptr. - /// - // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we - // shouldn't need to specify them at construction time. - static std::unique_ptr<ASTUnit> LoadFromCommandLine( + friend std::unique_ptr<ASTUnit> CreateASTUnitFromCommandLine( const char **ArgBegin, const char **ArgEnd, std::shared_ptr<PCHContainerOperations> PCHContainerOps, std::shared_ptr<DiagnosticOptions> DiagOpts, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath, - bool StorePreamblesInMemory = false, - StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false, - CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, - ArrayRef<RemappedFile> RemappedFiles = {}, - bool RemappedFilesKeepOriginalName = true, - unsigned PrecompilePreambleAfterNParses = 0, - TranslationUnitKind TUKind = TU_Complete, - bool CacheCodeCompletionResults = false, - bool IncludeBriefCommentsInCodeCompletion = false, - bool AllowPCHWithCompilerErrors = false, - SkipFunctionBodiesScope SkipFunctionBodies = - SkipFunctionBodiesScope::None, - bool SingleFileParse = false, bool UserFilesAreVolatile = false, - bool ForSerialization = false, - bool RetainExcludedConditionalBlocks = false, - std::optional<StringRef> ModuleFormat = std::nullopt, - std::unique_ptr<ASTUnit> *ErrAST = nullptr, - IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); + bool StorePreamblesInMemory, StringRef PreambleStoragePath, + bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics, + ArrayRef<ASTUnit::RemappedFile> RemappedFiles, + bool RemappedFilesKeepOriginalName, + unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind, + bool CacheCodeCompletionResults, + bool IncludeBriefCommentsInCodeCompletion, + bool AllowPCHWithCompilerErrors, + SkipFunctionBodiesScope SkipFunctionBodies, bool SingleFileParse, + bool UserFilesAreVolatile, bool ForSerialization, + bool RetainExcludedConditionalBlocks, + std::optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS); /// Reparse the source files using the same command-line options that /// were originally used to produce this translation unit. @@ -963,6 +909,44 @@ public: bool serialize(raw_ostream &OS); }; +/// Diagnostic consumer that saves each diagnostic it is given. +class FilterAndStoreDiagnosticConsumer : public DiagnosticConsumer { + SmallVectorImpl<StoredDiagnostic> *StoredDiags; + SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags; + bool CaptureNonErrorsFromIncludes = true; + const LangOptions *LangOpts = nullptr; + SourceManager *SourceMgr = nullptr; + +public: + FilterAndStoreDiagnosticConsumer( + SmallVectorImpl<StoredDiagnostic> *StoredDiags, + SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags, + bool CaptureNonErrorsFromIncludes); + + void BeginSourceFile(const LangOptions &LangOpts, + const Preprocessor *PP = nullptr) override; + + void HandleDiagnostic(DiagnosticsEngine::Level Level, + const Diagnostic &Info) override; +}; + +/// RAII object that optionally captures and filters diagnostics, if +/// there is no diagnostic client to capture them already. +class CaptureDroppedDiagnostics { + DiagnosticsEngine &Diags; + FilterAndStoreDiagnosticConsumer Client; + DiagnosticConsumer *PreviousClient = nullptr; + std::unique_ptr<DiagnosticConsumer> OwningPreviousClient; + +public: + CaptureDroppedDiagnostics( + CaptureDiagsKind CaptureDiagnostics, DiagnosticsEngine &Diags, + SmallVectorImpl<StoredDiagnostic> *StoredDiags, + SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags); + + ~CaptureDroppedDiagnostics(); +}; + } // namespace clang #endif // LLVM_CLANG_FRONTEND_ASTUNIT_H diff --git a/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h b/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h index ca28456..839b5e7 100644 --- a/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h +++ b/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h @@ -66,6 +66,6 @@ public: } }; -} // end namspace clang +} // namespace clang #endif diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index 2403cbb..18ad7bf 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -946,6 +946,12 @@ public: DependencyCollectors.push_back(std::move(Listener)); } + void clearDependencyCollectors() { DependencyCollectors.clear(); } + + std::vector<std::shared_ptr<DependencyCollector>> &getDependencyCollectors() { + return DependencyCollectors; + } + void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS); ModuleCache &getModuleCache() const { return *ModCache; } diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index e147d2b..903583e 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -67,6 +67,11 @@ bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags = nullptr, bool DefaultDiagColor = true); +unsigned getOptimizationLevel(const llvm::opt::ArgList &Args, InputKind IK, + DiagnosticsEngine &Diags); + +unsigned getOptimizationLevelSize(const llvm::opt::ArgList &Args); + /// The base class of CompilerInvocation. It keeps individual option objects /// behind reference-counted pointers, which is useful for clients that want to /// keep select option objects alive (even after CompilerInvocation gets @@ -147,6 +152,13 @@ public: } /// @} + /// Visitation. + /// @{ + /// Visits paths stored in the invocation. The callback may return true to + /// short-circuit the visitation, or return false to continue visiting. + void visitPaths(llvm::function_ref<bool(StringRef)> Callback) const; + /// @} + /// Command line generation. /// @{ using StringAllocator = llvm::function_ref<const char *(const Twine &)>; @@ -181,6 +193,12 @@ public: /// This is a (less-efficient) wrapper over generateCC1CommandLine(). std::vector<std::string> getCC1CommandLine() const; +protected: + /// Visits paths stored in the invocation. This is generally unsafe to call + /// directly, and each sub-class need to ensure calling this doesn't violate + /// its invariants. + void visitPathsImpl(llvm::function_ref<bool(std::string &)> Predicate); + private: /// Generate command line options from DiagnosticOptions. static void GenerateDiagnosticArgs(const DiagnosticOptions &Opts, @@ -281,16 +299,6 @@ public: DiagnosticsEngine &Diags, const char *Argv0 = nullptr); - /// Get the directory where the compiler headers - /// reside, relative to the compiler binary (found by the passed in - /// arguments). - /// - /// \param Argv0 - The program path (from argv[0]), for finding the builtin - /// compiler path. - /// \param MainAddr - The address of main (or some other function in the main - /// executable), for finding the builtin compiler path. - static std::string GetResourcesPath(const char *Argv0, void *MainAddr); - /// Populate \p Opts with the default set of pointer authentication-related /// options given \p LangOpts and \p Triple. /// diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h index 73308c0..87a9f0d 100644 --- a/clang/include/clang/Frontend/FrontendActions.h +++ b/clang/include/clang/Frontend/FrontendActions.h @@ -320,15 +320,6 @@ protected: bool hasPCHSupport() const override { return true; } }; -class GetDependenciesByModuleNameAction : public PreprocessOnlyAction { - StringRef ModuleName; - void ExecuteAction() override; - -public: - GetDependenciesByModuleNameAction(StringRef ModuleName) - : ModuleName(ModuleName) {} -}; - //===----------------------------------------------------------------------===// // HLSL Specific Actions //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index c919a53..ba7da56 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -241,6 +241,8 @@ class FrontendInputFile { /// Whether we're dealing with a 'system' input (vs. a 'user' input). bool IsSystem = false; + friend class CompilerInvocationBase; + public: FrontendInputFile() = default; FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false) diff --git a/clang/include/clang/Frontend/SARIFDiagnostic.h b/clang/include/clang/Frontend/SARIFDiagnostic.h index 780f36c..7a6f27e 100644 --- a/clang/include/clang/Frontend/SARIFDiagnostic.h +++ b/clang/include/clang/Frontend/SARIFDiagnostic.h @@ -63,10 +63,20 @@ private: ArrayRef<CharSourceRange> Ranges, const Diagnostic &Diag); + SarifResult addRelatedLocationToResult(SarifResult Result, FullSourceLoc Loc, + PresumedLoc PLoc); + + llvm::SmallVector<CharSourceRange> + getSarifLocation(FullSourceLoc Loc, PresumedLoc PLoc, + ArrayRef<CharSourceRange> Ranges); + SarifRule addDiagnosticLevelToRule(SarifRule Rule, DiagnosticsEngine::Level Level); llvm::StringRef emitFilename(StringRef Filename, const SourceManager &SM); + + llvm::SmallVector<std::pair<FullSourceLoc, PresumedLoc>> + RelatedLocationsCache; }; } // end namespace clang diff --git a/clang/include/clang/Frontend/StandaloneDiagnostic.h b/clang/include/clang/Frontend/StandaloneDiagnostic.h new file mode 100644 index 0000000..c23d5f9 --- /dev/null +++ b/clang/include/clang/Frontend/StandaloneDiagnostic.h @@ -0,0 +1,82 @@ +//===--- StandaloneDiagnostic.h - Serializable Diagnostic -------*- 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 +// +//===----------------------------------------------------------------------===// +// +// A serializable diagnostic representation to retain diagnostics after their +// SourceManager has been destroyed. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_STANDALONEDIAGNOSTICS_H +#define LLVM_CLANG_FRONTEND_STANDALONEDIAGNOSTICS_H + +#include "clang/Basic/DiagnosticIDs.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/StringExtras.h" +#include <cassert> +#include <string> +#include <vector> + +namespace clang { + +/// Represents a StoredDiagnostic in a form that can be retained until after its +/// SourceManager has been destroyed. +/// +/// Source locations are stored as a combination of filename and offsets into +/// that file. +/// To report the diagnostic, it must first be translated back into a +/// StoredDiagnostic with a new associated SourceManager. +struct StandaloneDiagnostic { + /// Represents a CharSourceRange within a StandaloneDiagnostic. + struct SourceOffsetRange { + SourceOffsetRange(CharSourceRange Range, const SourceManager &SrcMgr, + const LangOptions &LangOpts); + + unsigned Begin = 0; + unsigned End = 0; + }; + + /// Represents a FixItHint within a StandaloneDiagnostic. + struct StandaloneFixIt { + StandaloneFixIt(const SourceManager &SrcMgr, const LangOptions &LangOpts, + const FixItHint &FixIt); + + SourceOffsetRange RemoveRange; + SourceOffsetRange InsertFromRange; + std::string CodeToInsert; + bool BeforePreviousInsertions; + }; + + StandaloneDiagnostic(const LangOptions &LangOpts, + const StoredDiagnostic &InDiag); + + DiagnosticsEngine::Level Level; + SrcMgr::CharacteristicKind FileKind; + unsigned ID = 0; + unsigned FileOffset = 0; + std::string Message; + std::string Filename; + std::vector<SourceOffsetRange> Ranges; + std::vector<StandaloneFixIt> FixIts; +}; + +/// Translates \c StandaloneDiag into a StoredDiagnostic, associating it with +/// the provided FileManager and SourceManager. +/// +/// This allows the diagnostic to be emitted using the diagnostics engine, since +/// StandaloneDiagnostics themselfs cannot be emitted directly. +StoredDiagnostic +translateStandaloneDiag(FileManager &FileMgr, SourceManager &SrcMgr, + const StandaloneDiagnostic &StandaloneDiag, + llvm::StringMap<SourceLocation> &SrcLocCache); + +} // namespace clang + +#endif // STANDALONEDIAGNOSTICS diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h index 49fd920..1c561b4 100644 --- a/clang/include/clang/Frontend/Utils.h +++ b/clang/include/clang/Frontend/Utils.h @@ -15,8 +15,8 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LLVM.h" -#include "clang/Driver/OptionUtils.h" #include "clang/Frontend/DependencyOutputOptions.h" +#include "clang/Options/OptionUtils.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringMap.h" @@ -192,51 +192,6 @@ IntrusiveRefCntPtr<ExternalSemaSource> createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr<ASTReader> &OutReader); -/// Optional inputs to createInvocation. -struct CreateInvocationOptions { - /// Receives diagnostics encountered while parsing command-line flags. - /// If not provided, these are printed to stderr. - IntrusiveRefCntPtr<DiagnosticsEngine> Diags = nullptr; - /// Used e.g. to probe for system headers locations. - /// If not provided, the real filesystem is used. - /// FIXME: the driver does perform some non-virtualized IO. - IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr; - /// Whether to attempt to produce a non-null (possibly incorrect) invocation - /// if any errors were encountered. - /// By default, always return null on errors. - bool RecoverOnError = false; - /// Allow the driver to probe the filesystem for PCH files. - /// This is used to replace -include with -include-pch in the cc1 args. - /// FIXME: ProbePrecompiled=true is a poor, historical default. - /// It misbehaves if the PCH file is from GCC, has the wrong version, etc. - bool ProbePrecompiled = false; - /// If set, the target is populated with the cc1 args produced by the driver. - /// This may be populated even if createInvocation returns nullptr. - std::vector<std::string> *CC1Args = nullptr; -}; - -/// Interpret clang arguments in preparation to parse a file. -/// -/// This simulates a number of steps Clang takes when its driver is invoked: -/// - choosing actions (e.g compile + link) to run -/// - probing the system for settings like standard library locations -/// - spawning a cc1 subprocess to compile code, with more explicit arguments -/// - in the cc1 process, assembling those arguments into a CompilerInvocation -/// which is used to configure the parser -/// -/// This simulation is lossy, e.g. in some situations one driver run would -/// result in multiple parses. (Multi-arch, CUDA, ...). -/// This function tries to select a reasonable invocation that tools should use. -/// -/// Args[0] should be the driver name, such as "clang" or "/usr/bin/g++". -/// Absolute path is preferred - this affects searching for system headers. -/// -/// May return nullptr if an invocation could not be determined. -/// See CreateInvocationOptions::ShouldRecoverOnErrors to try harder! -std::unique_ptr<CompilerInvocation> -createInvocation(ArrayRef<const char *> Args, - CreateInvocationOptions Opts = {}); - } // namespace clang #endif // LLVM_CLANG_FRONTEND_UTILS_H diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index 850aea4..5369c87 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -465,6 +465,12 @@ public: ExternalSource = ES; } + void diagnoseHeaderShadowing( + StringRef Filename, OptionalFileEntryRef FE, bool &DiagnosedShadowing, + SourceLocation IncludeLoc, ConstSearchDirIterator FromDir, + ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers, + bool isAngled, int IncluderLoopIndex, ConstSearchDirIterator MainLoopIt); + /// Set the target information for the header search, if not /// already known. void setTarget(const TargetInfo &Target); diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h index 313b730..e6120c5 100644 --- a/clang/include/clang/Lex/PPCallbacks.h +++ b/clang/include/clang/Lex/PPCallbacks.h @@ -499,10 +499,10 @@ public: } bool EmbedFileNotFound(StringRef FileName) override { - bool Skip = First->FileNotFound(FileName); + bool Skip = First->EmbedFileNotFound(FileName); // Make sure to invoke the second callback, no matter if the first already // returned true to skip the file. - Skip |= Second->FileNotFound(FileName); + Skip |= Second->EmbedFileNotFound(FileName); return Skip; } diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 4120022..b1c648e 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1327,6 +1327,7 @@ public: std::move(Callbacks)); Callbacks = std::move(C); } + void removePPCallbacks() { Callbacks.reset(); } /// \} /// Get the number of tokens processed so far. diff --git a/clang/include/clang/Lex/Token.h b/clang/include/clang/Lex/Token.h index d9dc5a5..43091a6 100644 --- a/clang/include/clang/Lex/Token.h +++ b/clang/include/clang/Lex/Token.h @@ -100,13 +100,19 @@ public: /// is/isNot - Predicates to check if this token is a specific kind, as in /// "if (Tok.is(tok::l_brace)) {...}". bool is(tok::TokenKind K) const { return Kind == K; } - bool isNot(tok::TokenKind K) const { return Kind != K; } template <typename... Ts> bool isOneOf(Ts... Ks) const { static_assert(sizeof...(Ts) > 0, "requires at least one tok::TokenKind specified"); return (is(Ks) || ...); } + bool isNot(tok::TokenKind K) const { return Kind != K; } + template <typename... Ts> bool isNoneOf(Ts... Ks) const { + static_assert(sizeof...(Ts) > 0, + "requires at least one tok::TokenKind specified"); + return (isNot(Ks) && ...); + } + /// Return true if this is a raw identifier (when lexing /// in raw mode) or a non-keyword identifier (when lexing in non-raw mode). bool isAnyIdentifier() const { diff --git a/clang/include/clang/Driver/CMakeLists.txt b/clang/include/clang/Options/CMakeLists.txt index a9d9880..a9d9880 100644 --- a/clang/include/clang/Driver/CMakeLists.txt +++ b/clang/include/clang/Options/CMakeLists.txt diff --git a/clang/include/clang/Driver/ClangOptionDocs.td b/clang/include/clang/Options/ClangOptionDocs.td index dea6a7c..dea6a7c 100644 --- a/clang/include/clang/Driver/ClangOptionDocs.td +++ b/clang/include/clang/Options/ClangOptionDocs.td diff --git a/clang/include/clang/Driver/OptionUtils.h b/clang/include/clang/Options/OptionUtils.h index 922f536..02c9c27 100644 --- a/clang/include/clang/Driver/OptionUtils.h +++ b/clang/include/clang/Options/OptionUtils.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_DRIVER_OPTIONUTILS_H -#define LLVM_CLANG_DRIVER_OPTIONUTILS_H +#ifndef LLVM_CLANG_OPTIONS_OPTIONUTILS_H +#define LLVM_CLANG_OPTIONS_OPTIONUTILS_H #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LLVM.h" @@ -28,6 +28,7 @@ class ArgList; } // namespace llvm namespace clang { + /// Return the value of the last argument as an integer, or a default. If Diags /// is non-null, emits an error if the argument is given, but non-integral. int getLastArgIntValue(const llvm::opt::ArgList &Args, @@ -53,6 +54,29 @@ inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args, return getLastArgUInt64Value(Args, Id, Default, &Diags, Base); } +// Parse -mprefer-vector-width=. Return the Value string if well-formed. +// Otherwise, return an empty string and issue a diagnosic message if needed. +StringRef parseMPreferVectorWidthOption(clang::DiagnosticsEngine &Diags, + const llvm::opt::ArgList &Args); + +// Parse -mrecip. Return the Value string if well-formed. +// Otherwise, return an empty string and issue a diagnosic message if needed. +StringRef parseMRecipOption(clang::DiagnosticsEngine &Diags, + const llvm::opt::ArgList &Args); + +/// Get the directory where the compiler headers reside, relative to the +/// compiler binary path \p BinaryPath. +std::string GetResourcesPath(StringRef BinaryPath); + +/// Get the directory where the compiler headers reside, relative to the +/// compiler binary path (found by the passed in arguments). +/// +/// \param Argv0 The program path (from argv[0]), for finding the builtin +/// compiler path. +/// \param MainAddr The address of main (or some other function in the main +/// executable), for finding the builtin compiler path. +std::string GetResourcesPath(const char *Argv0, void *MainAddr); + } // namespace clang -#endif // LLVM_CLANG_DRIVER_OPTIONUTILS_H +#endif // LLVM_CLANG_OPTIONS_OPTIONUTILS_H diff --git a/clang/include/clang/Driver/Options.h b/clang/include/clang/Options/Options.h index 0797410..ac98699 100644 --- a/clang/include/clang/Driver/Options.h +++ b/clang/include/clang/Options/Options.h @@ -6,14 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_DRIVER_OPTIONS_H -#define LLVM_CLANG_DRIVER_OPTIONS_H +#ifndef LLVM_CLANG_OPTIONS_OPTIONS_H +#define LLVM_CLANG_OPTIONS_OPTIONS_H #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" namespace clang { -namespace driver { namespace options { /// Flags specifically for clang options. Must not overlap with @@ -42,16 +41,15 @@ enum ClangVisibility { }; enum ID { - OPT_INVALID = 0, // This is not an option ID. + OPT_INVALID = 0, // This is not an option ID. #define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__), -#include "clang/Driver/Options.inc" - LastOption +#include "clang/Options/Options.inc" + LastOption #undef OPTION - }; -} +}; +} // namespace options const llvm::opt::OptTable &getDriverOptTable(); -} -} +} // namespace clang -#endif +#endif // LLVM_CLANG_OPTIONS_OPTIONS_H diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Options/Options.td index 11e81e0..cac122d 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Options/Options.td @@ -201,6 +201,10 @@ def hlsl_Group : OptionGroup<"<HLSL group>">, Group<f_Group>, DocName<"HLSL options">, Visibility<[ClangOption]>; +def fsan_cov_Group : OptionGroup<"<-fsanitize-coverage group>">, + Group<f_clang_Group>, + DocName<"Sanitizer Coverage options">; + // Feature groups - these take command line options that correspond directly to // target specific features and can be translated directly from command line // options. @@ -316,7 +320,8 @@ def mno_mpx : Flag<["-"], "mno-mpx">, Group<clang_ignored_legacy_options_Group>; // Group that ignores all gcc optimizations that won't be implemented def clang_ignored_gcc_optimization_f_Group : OptionGroup< - "<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>, Flags<[Ignored]>; + "<clang_ignored_gcc_optimization_f_Group>">, + Group<f_Group>, Flags<[Ignored]>, Visibility<[ClangOption, FlangOption]>; class DiagnosticOpts<string base> : KeyPathAndMacro<"DiagnosticOpts->", base, "DIAG_"> {} @@ -1423,6 +1428,16 @@ def fhip_emit_relocatable : Flag<["-"], "fhip-emit-relocatable">, HelpText<"Compile HIP source to relocatable">; def fno_hip_emit_relocatable : Flag<["-"], "fno-hip-emit-relocatable">, HelpText<"Do not override toolchain to compile HIP source to relocatable">; +def use_spirv_backend + : Flag<["-"], "use-spirv-backend">, + Group<hip_Group>, + Flags<[HelpHidden]>, + HelpText<"Use the SPIRV backend for compilation ">; +def no_use_spirv_backend + : Flag<["-"], "no-use-spirv-backend">, + Group<hip_Group>, + Flags<[HelpHidden]>, + HelpText<"Do not use the SPIRV backend for compilation ">; } // Clang specific/exclusive options for OpenACC. @@ -2407,26 +2422,26 @@ def : Flag<["-"], "fno-sanitize-blacklist">, Group<f_clang_Group>, Flags<[HelpHidden]>, Alias<fno_sanitize_ignorelist>; def fsanitize_coverage : CommaJoined<["-"], "fsanitize-coverage=">, - Group<f_clang_Group>, + Group<fsan_cov_Group>, HelpText<"Specify the type of coverage instrumentation for Sanitizers">; def fno_sanitize_coverage : CommaJoined<["-"], "fno-sanitize-coverage=">, - Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>, + Group<fsan_cov_Group>, Visibility<[ClangOption, CLOption]>, HelpText<"Disable features of coverage instrumentation for Sanitizers">, Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep," "8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters," "inline-bool-flag">; def fsanitize_coverage_allowlist : Joined<["-"], "fsanitize-coverage-allowlist=">, - Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>, + Group<fsan_cov_Group>, Visibility<[ClangOption, CLOption]>, HelpText<"Restrict sanitizer coverage instrumentation exclusively to modules and functions that match the provided special case list, except the blocked ones">, MarshallingInfoStringVector<CodeGenOpts<"SanitizeCoverageAllowlistFiles">>; def fsanitize_coverage_ignorelist : Joined<["-"], "fsanitize-coverage-ignorelist=">, - Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>, + Group<fsan_cov_Group>, Visibility<[ClangOption, CLOption]>, HelpText<"Disable sanitizer coverage instrumentation for modules and functions " "that match the provided special case list, even the allowed ones">, MarshallingInfoStringVector<CodeGenOpts<"SanitizeCoverageIgnorelistFiles">>; def fsanitize_coverage_stack_depth_callback_min_EQ : Joined<["-"], "fsanitize-coverage-stack-depth-callback-min=">, - Group<f_clang_Group>, + Group<fsan_cov_Group>, MetaVarName<"<M>">, HelpText<"Use callback for max stack depth tracing with minimum stack " "depth M">, @@ -2459,6 +2474,12 @@ def fsanitize_address_outline_instrumentation : Flag<["-"], "fsanitize-address-o def fno_sanitize_address_outline_instrumentation : Flag<["-"], "fno-sanitize-address-outline-instrumentation">, Group<f_clang_Group>, HelpText<"Use default code inlining logic for the address sanitizer">; +def fsanitize_type_outline_instrumentation : Flag<["-"], "fsanitize-type-outline-instrumentation">, + Group<f_clang_Group>, + HelpText<"Always generate function calls for type sanitizer instrumentation">; +def fno_sanitize_type_outline_instrumentation : Flag<["-"], "fno-sanitize-type-outline-instrumentation">, + Group<f_clang_Group>, + HelpText<"Use code inlining logic for the type sanitizer">; defm sanitize_stable_abi : OptInCC1FFlag<"sanitize-stable-abi", "Stable ", "Conventional ", "ABI instrumentation for sanitizer runtime. Default: Conventional">; @@ -2656,6 +2677,15 @@ defm sanitize_minimal_runtime : BoolOption<"f", "sanitize-minimal-runtime", PosFlag<SetTrue>, NegFlag<SetFalse>>, Group<f_clang_Group>; +defm sanitize_handler_preserve_all_regs + : BoolOption< + "f", "sanitize-handler-preserve-all-regs", + CodeGenOpts<"SanitizeHandlerPreserveAllRegs">, DefaultFalse, + PosFlag<SetTrue, [], [], + "Enable handlers with preserve_all calling convention">, + NegFlag<SetFalse, [], [], + "Disable handlers with preserve_all calling convention">>, + Group<f_clang_Group>; def fsanitize_link_runtime : Flag<["-"], "fsanitize-link-runtime">, Group<f_clang_Group>; def fno_sanitize_link_runtime : Flag<["-"], "fno-sanitize-link-runtime">, @@ -2690,6 +2720,16 @@ def fsanitize_kcfi_arity : Flag<["-"], "fsanitize-kcfi-arity">, Group<f_clang_Group>, HelpText<"Embed function arity information into the KCFI patchable function prefix">, MarshallingInfoFlag<CodeGenOpts<"SanitizeKcfiArity">>; +def fsanitize_kcfi_hash_EQ + : Joined<["-"], "fsanitize-kcfi-hash=">, + HelpText<"Select hash algorithm for KCFI type IDs (xxHash64, FNV-1a)">, + Visibility<[ClangOption, CC1Option]>, + Values<"xxHash64,FNV-1a">, + NormalizedValuesScope<"llvm">, + NormalizedValues<["KCFIHashAlgorithm::xxHash64", + "KCFIHashAlgorithm::FNV1a"]>, + MarshallingInfoEnum<CodeGenOpts<"SanitizeKcfiHash">, + "KCFIHashAlgorithm::xxHash64">; defm sanitize_stats : BoolOption<"f", "sanitize-stats", CodeGenOpts<"SanitizeStats">, DefaultFalse, PosFlag<SetTrue, [], [ClangOption], "Enable">, @@ -2754,7 +2794,7 @@ defm sanitize_alloc_token_extended : BoolOption<"f", "sanitize-alloc-token-exten def falloc_token_max_EQ : Joined<["-"], "falloc-token-max=">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, MetaVarName<"<N>">, - HelpText<"Limit to maximum N allocation tokens (0 = no max)">; + HelpText<"Limit to maximum N allocation tokens (0 = target SIZE_MAX)">; def falloc_token_mode_EQ : Joined<["-"], "falloc-token-mode=">, Group<f_Group>, Visibility<[CC1Option]>, @@ -2778,6 +2818,9 @@ def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations"> Group<f_Group>; def fassociative_math : Flag<["-"], "fassociative-math">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>; def fno_associative_math : Flag<["-"], "fno-associative-math">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>; +def ffast_real_mod : Flag<["-"], "ffast-real-mod">, + Group<f_Group>, Visibility<[FlangOption, FC1Option]>, + HelpText<"Enable optimization of MOD for REAL types">; def fno_fast_real_mod : Flag<["-"], "fno-fast-real-mod">, Group<f_Group>, Visibility<[FlangOption, FC1Option]>, HelpText<"Disable optimization of MOD for REAL types in presence of -ffast-math">; @@ -4480,6 +4523,13 @@ defm new_infallible : BoolFOption<"new-infallible", BothFlags<[], [ClangOption, CC1Option], " treating throwing global C++ operator new as always returning valid memory " "(annotates with __attribute__((returns_nonnull)) and throw()). This is detectable in source.">>; +defm devirtualize_speculatively + : BoolFOption<"devirtualize-speculatively", + CodeGenOpts<"DevirtualizeSpeculatively">, DefaultFalse, + PosFlag<SetTrue, [], [], + "Enables speculative devirtualization optimization.">, + NegFlag<SetFalse>, + BothFlags<[], [ClangOption, CLOption, CC1Option]>>; defm whole_program_vtables : BoolFOption<"whole-program-vtables", CodeGenOpts<"WholeProgramVTables">, DefaultFalse, PosFlag<SetTrue, [], [ClangOption, CC1Option], @@ -4733,25 +4783,25 @@ def ggdb3 : Flag<["-"], "ggdb3">, Group<ggdbN_Group>; def glldb : Flag<["-"], "glldb">, Group<gTune_Group>; def gsce : Flag<["-"], "gsce">, Group<gTune_Group>; def gdbx : Flag<["-"], "gdbx">, Group<gTune_Group>; -// Equivalent to our default dwarf version. Forces usual dwarf emission when +// Equivalent to our default DWARF version. Forces usual DWARF emission when // CodeView is enabled. def gdwarf : Flag<["-"], "gdwarf">, Group<g_Group>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, - HelpText<"Generate source-level debug information with the default dwarf version">; + HelpText<"Generate source-level debug information with the default DWARF version">; let Visibility = [ClangOption, FlangOption] in { def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group<g_Group>, - HelpText<"Generate source-level debug information with dwarf version 2">; + HelpText<"Generate source-level debug information with DWARF version 2">; def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group<g_Group>, - HelpText<"Generate source-level debug information with dwarf version 3">; + HelpText<"Generate source-level debug information with DWARF version 3">; def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>, - HelpText<"Generate source-level debug information with dwarf version 4">; + HelpText<"Generate source-level debug information with DWARF version 4">; def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group<g_Group>, - HelpText<"Generate source-level debug information with dwarf version 5">; + HelpText<"Generate source-level debug information with DWARF version 5">; def gdwarf_6 : Flag<["-"], "gdwarf-6">, Group<g_Group>, - HelpText<"Generate source-level debug information with dwarf version 6">; + HelpText<"Generate source-level debug information with DWARF version 6">; } def gdwarf64 : Flag<["-"], "gdwarf64">, Group<g_Group>, Visibility<[ClangOption, CC1Option, CC1AsOption]>, @@ -4761,7 +4811,7 @@ def gdwarf32 : Flag<["-"], "gdwarf32">, Group<g_Group>, Visibility<[ClangOption, CC1Option, CC1AsOption]>, HelpText<"Enables DWARF32 format for ELF binaries, if debug information emission is enabled.">; -def gcodeview : Flag<["-"], "gcodeview">, +def gcodeview : Flag<["-"], "gcodeview">, Group<g_Group>, HelpText<"Generate CodeView debug information">, Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption]>, MarshallingInfoFlag<CodeGenOpts<"EmitCodeView">>; @@ -4769,17 +4819,20 @@ defm codeview_ghash : BoolOption<"g", "codeview-ghash", CodeGenOpts<"CodeViewGHash">, DefaultFalse, PosFlag<SetTrue, [], [ClangOption, CC1Option], "Emit type record hashes in a .debug$H section">, - NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>; + NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>, + Group<g_flags_Group>; defm codeview_command_line : BoolOption<"g", "codeview-command-line", CodeGenOpts<"CodeViewCommandLine">, DefaultTrue, PosFlag<SetTrue, [], [ClangOption], "Emit compiler path and command line into CodeView debug information">, NegFlag<SetFalse, [], [ClangOption], "Don't emit compiler path and command line into CodeView debug information">, - BothFlags<[], [ClangOption, CLOption, DXCOption, CC1Option]>>; + BothFlags<[], [ClangOption, CLOption, DXCOption, CC1Option]>>, + Group<g_flags_Group>; defm inline_line_tables : BoolGOption<"inline-line-tables", CodeGenOpts<"NoInlineLineTables">, DefaultFalse, NegFlag<SetTrue, [], [ClangOption, CC1Option], "Don't emit inline line tables.">, - PosFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>; + PosFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>, + Group<g_flags_Group>; def gfull : Flag<["-"], "gfull">, Group<g_Group>; def gused : Flag<["-"], "gused">, Group<g_Group>; @@ -4804,12 +4857,21 @@ defm strict_dwarf : BoolOption<"g", "strict-dwarf", defm omit_unreferenced_methods : BoolGOption<"omit-unreferenced-methods", CodeGenOpts<"DebugOmitUnreferencedMethods">, DefaultFalse, NegFlag<SetFalse>, - PosFlag<SetTrue, [], [CC1Option]>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>; + PosFlag<SetTrue, [], [CC1Option]>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>, + Group<g_flags_Group>; defm column_info : BoolOption<"g", "column-info", CodeGenOpts<"DebugColumnInfo">, DefaultTrue, NegFlag<SetFalse, [], [ClangOption, CC1Option]>, PosFlag<SetTrue>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>, Group<g_flags_Group>; +defm call_site_info : BoolOption<"g", "call-site-info", + CodeGenOpts<"DebugCallSiteInfo">, + DefaultTrue, + PosFlag<SetTrue, [], [], "Enable">, + NegFlag<SetFalse, [], [], "Disable">, + BothFlags<[], [ClangOption, CC1Option], " call site debug info">>, + Group<g_flags_Group>, + DocBrief<[{Call site debug info enables various debugger features including detecting tail calls for display in backtraces and displaying some source variable values that reference the call entry value.}]>; def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; def gsplit_dwarf_EQ : Joined<["-"], "gsplit-dwarf=">, Group<g_flags_Group>, @@ -4863,6 +4925,7 @@ defm structor_decl_linkage_names "Attach linkage names to C++ constructor/destructor " "declarations in DWARF.">, BothFlags<[], [ClangOption, CLOption, CC1Option]>>, + Group<g_flags_Group>, DocBrief<[{On some ABIs (e.g., Itanium), constructors and destructors may have multiple variants. Historically, when generating DWARF, Clang did not attach ``DW_AT_linkage_name`` to structor DIEs because there were multiple possible manglings (depending on the structor variant) that could be used. With ``-gstructor-decl-linkage-names``, for ABIs with structor variants, we attach a "unified" mangled name to structor declarations DIEs which debuggers can use to look up all the definitions for a structor declaration. E.g., a "unified" mangled name ``_ZN3FooC4Ev`` may have multiple definitions associated with it such as ``_ZN3FooC1Ev`` and ``_ZN3FooC2Ev``. Enabling this flag results in a better interactive debugging experience (both GDB and LLDB have support for understanding these "unified" linkage names). However, it comes with a significant increase in debug-info size (particularly the `.debug_str` section). As an escape hatch, users can disable this feature using ``-gno-structor-decl-linkage-names``.}]>; @@ -4871,7 +4934,8 @@ defm key_instructions : BoolGOption<"key-instructions", NegFlag<SetFalse>, PosFlag<SetTrue, [], [], "Enable Key Instructions, which reduces the jumpiness of debug stepping in optimized C/C++ code" " in some debuggers. DWARF only.">, - BothFlags<[], [ClangOption, CLOption, CC1Option]>>; + BothFlags<[], [ClangOption, CLOption, CC1Option]>>, + Group<g_flags_Group>; def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">; def help : Flag<["-", "--"], "help">, Visibility<[ClangOption, CC1Option, CC1AsOption, @@ -5666,6 +5730,9 @@ def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>; def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>, HelpText<"Omit frame pointer setup for leaf functions">; +def mno_reserve_frame_pointer_reg : Flag<["-"], "mno-reserve-frame-pointer-reg">, Group<m_Group>; +def mreserve_frame_pointer_reg : Flag<["-"], "mreserve-frame-pointer-reg">, Group<m_Group>, + HelpText<"Reserve the frame pointer register even if the function doesn't have a frame">; def moslib_EQ : Joined<["-"], "moslib=">, Group<m_Group>; def mpascal_strings : Flag<["-"], "mpascal-strings">, Alias<fpascal_strings>; def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>; @@ -7073,9 +7140,8 @@ defm variable_expansion_in_unroller : BooleanFFlag<"variable-expansion-in-unroll Group<clang_ignored_gcc_optimization_f_Group>; defm web : BooleanFFlag<"web">, Group<clang_ignored_gcc_optimization_f_Group>; defm whole_program : BooleanFFlag<"whole-program">, Group<clang_ignored_gcc_optimization_f_Group>; -defm devirtualize : BooleanFFlag<"devirtualize">, Group<clang_ignored_gcc_optimization_f_Group>; -defm devirtualize_speculatively : BooleanFFlag<"devirtualize-speculatively">, - Group<clang_ignored_gcc_optimization_f_Group>; +defm devirtualize : BooleanFFlag<"devirtualize">, + Group<clang_ignored_gcc_optimization_f_Group>; // Generic gfortran options. def A_DASH : Joined<["-"], "A-">, Group<gfortran_Group>; @@ -7898,70 +7964,87 @@ def linker_option : Joined<["--"], "linker-option=">, HelpText<"Add linker option">, MarshallingInfoStringVector<CodeGenOpts<"LinkerOptions">>; def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">, + Group<fsan_cov_Group>, HelpText<"Sanitizer coverage type">, MarshallingInfoInt<CodeGenOpts<"SanitizeCoverageType">>; def fsanitize_coverage_indirect_calls : Flag<["-"], "fsanitize-coverage-indirect-calls">, + Group<fsan_cov_Group>, HelpText<"Enable sanitizer coverage for indirect calls">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageIndirectCalls">>; def fsanitize_coverage_trace_bb : Flag<["-"], "fsanitize-coverage-trace-bb">, + Group<fsan_cov_Group>, HelpText<"Enable basic block tracing in sanitizer coverage">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceBB">>; def fsanitize_coverage_trace_cmp : Flag<["-"], "fsanitize-coverage-trace-cmp">, + Group<fsan_cov_Group>, HelpText<"Enable cmp instruction tracing in sanitizer coverage">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceCmp">>; def fsanitize_coverage_trace_div : Flag<["-"], "fsanitize-coverage-trace-div">, + Group<fsan_cov_Group>, HelpText<"Enable div instruction tracing in sanitizer coverage">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceDiv">>; def fsanitize_coverage_trace_gep : Flag<["-"], "fsanitize-coverage-trace-gep">, + Group<fsan_cov_Group>, HelpText<"Enable gep instruction tracing in sanitizer coverage">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceGep">>; def fsanitize_coverage_8bit_counters : Flag<["-"], "fsanitize-coverage-8bit-counters">, + Group<fsan_cov_Group>, HelpText<"Enable frequency counters in sanitizer coverage">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverage8bitCounters">>; def fsanitize_coverage_inline_8bit_counters : Flag<["-"], "fsanitize-coverage-inline-8bit-counters">, + Group<fsan_cov_Group>, HelpText<"Enable inline 8-bit counters in sanitizer coverage">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageInline8bitCounters">>; def fsanitize_coverage_inline_bool_flag : Flag<["-"], "fsanitize-coverage-inline-bool-flag">, + Group<fsan_cov_Group>, HelpText<"Enable inline bool flag in sanitizer coverage">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageInlineBoolFlag">>; def fsanitize_coverage_pc_table : Flag<["-"], "fsanitize-coverage-pc-table">, + Group<fsan_cov_Group>, HelpText<"Create a table of coverage-instrumented PCs">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoveragePCTable">>; def fsanitize_coverage_control_flow : Flag<["-"], "fsanitize-coverage-control-flow">, + Group<fsan_cov_Group>, HelpText<"Collect control flow of function">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageControlFlow">>; def fsanitize_coverage_trace_pc : Flag<["-"], "fsanitize-coverage-trace-pc">, + Group<fsan_cov_Group>, HelpText<"Enable PC tracing in sanitizer coverage">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTracePC">>; def fsanitize_coverage_trace_pc_guard : Flag<["-"], "fsanitize-coverage-trace-pc-guard">, + Group<fsan_cov_Group>, HelpText<"Enable PC tracing with guard in sanitizer coverage">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTracePCGuard">>; def fsanitize_coverage_no_prune : Flag<["-"], "fsanitize-coverage-no-prune">, + Group<fsan_cov_Group>, HelpText<"Disable coverage pruning (i.e. instrument all blocks/edges)">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageNoPrune">>; def fsanitize_coverage_stack_depth : Flag<["-"], "fsanitize-coverage-stack-depth">, + Group<fsan_cov_Group>, HelpText<"Enable max stack depth tracing">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageStackDepth">>; def fsanitize_coverage_trace_loads : Flag<["-"], "fsanitize-coverage-trace-loads">, + Group<fsan_cov_Group>, HelpText<"Enable tracing of loads">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceLoads">>; def fsanitize_coverage_trace_stores : Flag<["-"], "fsanitize-coverage-trace-stores">, + Group<fsan_cov_Group>, HelpText<"Enable tracing of stores">, MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceStores">>; def fexperimental_sanitize_metadata_EQ_covered @@ -8470,7 +8553,7 @@ def main_file_name : Separate<["-"], "main-file-name">, Visibility<[CC1Option, CC1AsOption]>, MarshallingInfoString<CodeGenOpts<"MainFileName">>; def split_dwarf_output : Separate<["-"], "split-dwarf-output">, - HelpText<"File name to use for split dwarf debug info output">, + HelpText<"File name to use for split DWARF debug info output">, Visibility<[CC1Option, CC1AsOption, FC1Option]>, MarshallingInfoString<CodeGenOpts<"SplitDwarfOutput">>; @@ -8494,8 +8577,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">, MarshallingInfoFlag<LangOpts<"PIE">>; def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">, - HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,reserved,none">, - NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "Reserved", "None"]>, + HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,non-leaf-no-reserve,reserved,none">, + NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "NonLeafNoReserve", "Reserved", "None"]>, MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">; @@ -8504,7 +8587,7 @@ def dependent_lib : Joined<["--"], "dependent-lib=">, MarshallingInfoStringVector<CodeGenOpts<"DependentLibraries">>; def split_dwarf_file : Separate<["-"], "split-dwarf-file">, - HelpText<"Name of the split dwarf debug info file to encode in the object file">, + HelpText<"Name of the split DWARF debug info file to encode in the object file">, MarshallingInfoString<CodeGenOpts<"SplitDwarfFile">>; } // let Visibility = [CC1Option, FC1Option] @@ -9218,6 +9301,12 @@ def : CLFlag<"Qscatter-">, Alias<mno_scatter>, def _SLASH_arch : CLCompileJoined<"arch:">, HelpText<"Set architecture for code generation">; +def _SLASH_vlen : CLFlag<"vlen">, + HelpText<"Set default vector length for autovectorization and other optimizations">; +def _SLASH_vlen_EQ_256 : CLFlag<"vlen=256">, + HelpText<"Set vector length of 256 bits for autovectorization and other optimizations">; +def _SLASH_vlen_EQ_512 : CLFlag<"vlen=512">, + HelpText<"Set vector length of 512 bits for autovectorization and other optimizations">; def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>; def _SLASH_volatile_Group : OptionGroup<"</volatile group>">, diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index dad8efd0..58eb1c0 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -5223,11 +5223,7 @@ private: /// assignment-expression /// '{' ... /// \endverbatim - ExprResult ParseInitializer() { - if (Tok.isNot(tok::l_brace)) - return ParseAssignmentExpression(); - return ParseBraceInitializer(); - } + ExprResult ParseInitializer(Decl *DeclForInitializer = nullptr); /// MayBeDesignationStart - Return true if the current token might be the /// start of a designator. If we can tell it is impossible that it is a diff --git a/clang/include/clang/Sema/AnalysisBasedWarnings.h b/clang/include/clang/Sema/AnalysisBasedWarnings.h index 4103c3f..20a2030 100644 --- a/clang/include/clang/Sema/AnalysisBasedWarnings.h +++ b/clang/include/clang/Sema/AnalysisBasedWarnings.h @@ -14,15 +14,19 @@ #define LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H #include "clang/AST/Decl.h" +#include "clang/Sema/ScopeInfo.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/MapVector.h" #include <memory> namespace clang { +class AnalysisDeclContext; class Decl; class FunctionDecl; class QualType; class Sema; +class VarDecl; namespace sema { class FunctionScopeInfo; class SemaPPCallbacks; @@ -57,6 +61,8 @@ private: enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 }; llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD; + std::multimap<VarDecl *, PossiblyUnreachableDiag> + VarDeclPossiblyUnreachableDiags; Policy PolicyOverrides; void clearOverrides(); @@ -107,6 +113,10 @@ public: // Issue warnings that require whole-translation-unit analysis. void IssueWarnings(TranslationUnitDecl *D); + void registerVarDeclWarning(VarDecl *VD, PossiblyUnreachableDiag PUD); + + void issueWarningsForRegisteredVarDecl(VarDecl *VD); + // Gets the default policy which is in effect at the given source location. Policy getPolicyInEffectAt(SourceLocation Loc); diff --git a/clang/include/clang/Sema/CMakeLists.txt b/clang/include/clang/Sema/CMakeLists.txt index 9077e22..3f540ea5 100644 --- a/clang/include/clang/Sema/CMakeLists.txt +++ b/clang/include/clang/Sema/CMakeLists.txt @@ -8,6 +8,11 @@ clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds SOURCE ../Basic/Attr.td TARGET ClangAttrParsedAttrKinds) +clang_tablegen(AttrIsTypeDependent.inc -gen-clang-attr-is-type-dependent + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + SOURCE ../Basic/Attr.td + TARGET ClangAttrIsTypeDependent) + clang_tablegen(AttrSpellingListIndex.inc -gen-clang-attr-spelling-index -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ SOURCE ../Basic/Attr.td diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index 59bbd0f..ab45328 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -198,6 +198,9 @@ class Sema; /// HLSL vector truncation. ICK_HLSL_Vector_Truncation, + /// HLSL Matrix truncation. + ICK_HLSL_Matrix_Truncation, + /// HLSL non-decaying array rvalue cast. ICK_HLSL_Array_RValue, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index c67ed99..d14b5dc 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3019,7 +3019,7 @@ private: llvm::SmallBitVector &CheckedVarArgs); bool CheckFormatArguments(ArrayRef<const Expr *> Args, FormatArgumentPassingKind FAPK, - const StringLiteral *ReferenceFormatString, + StringLiteral *ReferenceFormatString, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, SourceLocation Loc, SourceRange range, @@ -4456,6 +4456,10 @@ public: NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK = AvailabilityMergeKind::Redeclaration); + /// CheckAttributesOnDeducedType - Calls Sema functions for attributes that + /// requires the type to be deduced. + void CheckAttributesOnDeducedType(Decl *D); + /// MergeTypedefNameDecl - We just parsed a typedef 'New' which has the /// same name and scope as a previous declaration 'Old'. Figure out /// how to resolve this situation, merging decls or emitting @@ -4760,6 +4764,8 @@ private: // linkage or not. static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD); +#include "clang/Sema/AttrIsTypeDependent.inc" + ///@} // @@ -4951,6 +4957,11 @@ public: IdentifierInfo *Format, int FormatIdx, StringLiteral *FormatStr); + ModularFormatAttr *mergeModularFormatAttr(Decl *D, + const AttributeCommonInfo &CI, + IdentifierInfo *ModularImplFn, + StringRef ImplName, + MutableArrayRef<StringRef> Aspects); /// AddAlignedAttr - Adds an aligned attribute to a particular declaration. void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, @@ -5105,6 +5116,11 @@ public: /// Essentially, this just moves them to the current pool. void redelayDiagnostics(sema::DelayedDiagnosticPool &pool); + /// Check that the type is a plain record with one field being a pointer + /// type and the other field being an integer. This matches the common + /// implementation of std::span or sized_allocation_t in P0901R11. + bool CheckSpanLikeType(const AttributeCommonInfo &CI, const QualType &Ty); + /// Check if IdxExpr is a valid parameter index for a function or /// instance method D. May output an error. /// @@ -6756,6 +6772,11 @@ public: /// suffice, e.g., in a default function argument. Decl *ManglingContextDecl; + /// Declaration for initializer if one is currently being + /// parsed. Used when an expression has a possibly unreachable + /// diagnostic to reference the declaration as a whole. + VarDecl *DeclForInitializer = nullptr; + /// If we are processing a decltype type, a set of call expressions /// for which we have deferred checking the completeness of the return type. SmallVector<CallExpr *, 8> DelayedDecltypeCalls; @@ -8705,10 +8726,6 @@ public: ExprResult &RHS, SourceLocation QuestionLoc); - QualType CheckSizelessVectorConditionalTypes(ExprResult &Cond, - ExprResult &LHS, ExprResult &RHS, - SourceLocation QuestionLoc); - //// Determines if a type is trivially relocatable /// according to the C++26 rules. // FIXME: This is in Sema because it requires @@ -11309,9 +11326,6 @@ public: InventedParameterInfos.end()); } - /// The number of SFINAE diagnostics that have been trapped. - unsigned NumSFINAEErrors; - ArrayRef<sema::FunctionScopeInfo *> getFunctionScopes() const { return llvm::ArrayRef(FunctionScopes.begin() + FunctionScopesStart, FunctionScopes.end()); @@ -11668,7 +11682,7 @@ public: ASTTemplateArgsPtr TemplateArgsIn, SourceLocation RAngleLoc); DeclResult ActOnVarTemplateSpecialization( - Scope *S, Declarator &D, TypeSourceInfo *DI, LookupResult &Previous, + Scope *S, Declarator &D, TypeSourceInfo *TSI, LookupResult &Previous, SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams, StorageClass SC, bool IsPartialSpecialization); @@ -12385,49 +12399,65 @@ public: ///@{ public: - /// When true, access checking violations are treated as SFINAE - /// failures rather than hard errors. - bool AccessCheckingSFINAE; + class SFINAETrap; + + struct SFINAEContextBase { + SFINAEContextBase(Sema &S, SFINAETrap *Cur) + : S(S), Prev(std::exchange(S.CurrentSFINAEContext, Cur)) {} + + protected: + Sema &S; + ~SFINAEContextBase() { S.CurrentSFINAEContext = Prev; } + + private: + SFINAETrap *Prev; + }; + + struct NonSFINAEContext : SFINAEContextBase { + NonSFINAEContext(Sema &S) : SFINAEContextBase(S, nullptr) {} + }; /// RAII class used to determine whether SFINAE has /// trapped any errors that occur during template argument /// deduction. - class SFINAETrap { - Sema &SemaRef; - unsigned PrevSFINAEErrors; - bool PrevInNonInstantiationSFINAEContext; - bool PrevAccessCheckingSFINAE; - bool PrevLastDiagnosticIgnored; + class SFINAETrap : SFINAEContextBase { + bool HasErrorOcurred = false; + bool WithAccessChecking = false; + bool PrevLastDiagnosticIgnored = + S.getDiagnostics().isLastDiagnosticIgnored(); + sema::TemplateDeductionInfo *DeductionInfo = nullptr; + + SFINAETrap(Sema &S, sema::TemplateDeductionInfo *Info, + bool WithAccessChecking) + : SFINAEContextBase(S, this), WithAccessChecking(WithAccessChecking), + DeductionInfo(Info) {} public: - /// \param ForValidityCheck If true, discard all diagnostics (from the + /// \param WithAccessChecking If true, discard all diagnostics (from the /// immediate context) instead of adding them to the currently active - /// \ref TemplateDeductionInfo (as returned by \ref isSFINAEContext). - explicit SFINAETrap(Sema &SemaRef, bool ForValidityCheck = false) - : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors), - PrevInNonInstantiationSFINAEContext( - SemaRef.InNonInstantiationSFINAEContext), - PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE), - PrevLastDiagnosticIgnored( - SemaRef.getDiagnostics().isLastDiagnosticIgnored()) { - if (ForValidityCheck || !SemaRef.isSFINAEContext()) - SemaRef.InNonInstantiationSFINAEContext = true; - SemaRef.AccessCheckingSFINAE = ForValidityCheck; - } + /// \ref TemplateDeductionInfo. + explicit SFINAETrap(Sema &S, bool WithAccessChecking = false) + : SFINAETrap(S, /*Info=*/nullptr, WithAccessChecking) {} + + SFINAETrap(Sema &S, sema::TemplateDeductionInfo &Info) + : SFINAETrap(S, &Info, /*WithAccessChecking=*/false) {} ~SFINAETrap() { - SemaRef.NumSFINAEErrors = PrevSFINAEErrors; - SemaRef.InNonInstantiationSFINAEContext = - PrevInNonInstantiationSFINAEContext; - SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE; - SemaRef.getDiagnostics().setLastDiagnosticIgnored( - PrevLastDiagnosticIgnored); + S.getDiagnostics().setLastDiagnosticIgnored(PrevLastDiagnosticIgnored); } - /// Determine whether any SFINAE errors have been trapped. - bool hasErrorOccurred() const { - return SemaRef.NumSFINAEErrors > PrevSFINAEErrors; + SFINAETrap(const SFINAETrap &) = delete; + SFINAETrap &operator=(const SFINAETrap &) = delete; + + sema::TemplateDeductionInfo *getDeductionInfo() const { + return DeductionInfo; } + + /// Determine whether any SFINAE errors have been trapped. + bool hasErrorOccurred() const { return HasErrorOcurred; } + void setErrorOccurred() { HasErrorOcurred = true; } + + bool withAccessChecking() const { return WithAccessChecking; } }; /// RAII class used to indicate that we are performing provisional @@ -13148,9 +13178,6 @@ public: PartialOrderingTTP, } Kind; - /// Was the enclosing context a non-instantiation SFINAE context? - bool SavedInNonInstantiationSFINAEContext; - /// Whether we're substituting into constraints. bool InConstraintSubstitution; @@ -13195,22 +13222,15 @@ public: return {TemplateArgs, NumTemplateArgs}; } - /// The template deduction info object associated with the - /// substitution or checking of explicit or deduced template arguments. - sema::TemplateDeductionInfo *DeductionInfo; - /// The source range that covers the construct that cause /// the instantiation, e.g., the template-id that causes a class /// template instantiation. SourceRange InstantiationRange; CodeSynthesisContext() - : Kind(TemplateInstantiation), - SavedInNonInstantiationSFINAEContext(false), - InConstraintSubstitution(false), + : Kind(TemplateInstantiation), InConstraintSubstitution(false), InParameterMappingSubstitution(false), Entity(nullptr), - Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0), - DeductionInfo(nullptr) {} + Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0) {} /// Determines whether this template is an actual instantiation /// that should be counted toward the maximum instantiation depth. @@ -13262,7 +13282,6 @@ public: FunctionTemplateDecl *FunctionTemplate, ArrayRef<TemplateArgument> TemplateArgs, CodeSynthesisContext::SynthesisKind Kind, - sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); /// Note that we are instantiating as part of template @@ -13270,7 +13289,6 @@ public: InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs, - sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); /// Note that we are instantiating as part of template @@ -13279,7 +13297,6 @@ public: InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, ClassTemplatePartialSpecializationDecl *PartialSpec, ArrayRef<TemplateArgument> TemplateArgs, - sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); /// Note that we are instantiating as part of template @@ -13288,7 +13305,6 @@ public: InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, VarTemplatePartialSpecializationDecl *PartialSpec, ArrayRef<TemplateArgument> TemplateArgs, - sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); /// Note that we are instantiating a default argument for a function @@ -13334,7 +13350,6 @@ public: /// concept. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, ConstraintSubstitution, NamedDecl *Template, - sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange); struct ConstraintNormalization {}; @@ -13354,7 +13369,6 @@ public: /// a requirement of a requires expression. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, concepts::Requirement *Req, - sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); /// \brief Note that we are checking the satisfaction of the constraint @@ -13366,7 +13380,6 @@ public: /// \brief Note that we are checking a requires clause. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, const RequiresExpr *E, - sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange); struct BuildingDeductionGuidesTag {}; @@ -13399,8 +13412,7 @@ public: SourceLocation PointOfInstantiation, SourceRange InstantiationRange, Decl *Entity, NamedDecl *Template = nullptr, - ArrayRef<TemplateArgument> TemplateArgs = {}, - sema::TemplateDeductionInfo *DeductionInfo = nullptr); + ArrayRef<TemplateArgument> TemplateArgs = {}); InstantiatingTemplate(const InstantiatingTemplate &) = delete; @@ -13541,12 +13553,7 @@ public: /// recent visible declaration of that namespace. llvm::DenseMap<NamedDecl *, NamedDecl *> VisibleNamespaceCache; - /// Whether we are in a SFINAE context that is not associated with - /// template instantiation. - /// - /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside - /// of a template instantiation or template argument deduction. - bool InNonInstantiationSFINAEContext; + SFINAETrap *CurrentSFINAEContext = nullptr; /// The number of \p CodeSynthesisContexts that are not template /// instantiations and, therefore, should not be counted as part of the @@ -13617,15 +13624,13 @@ public: PrintInstantiationStack(getDefaultDiagFunc()); } - /// Determines whether we are currently in a context where - /// template argument substitution failures are not considered - /// errors. - /// - /// \returns An empty \c Optional if we're not in a SFINAE context. - /// Otherwise, contains a pointer that, if non-NULL, contains the nearest - /// template-deduction context object, which can be used to capture - /// diagnostics that will be suppressed. - std::optional<sema::TemplateDeductionInfo *> isSFINAEContext() const; + /// Returns a pointer to the current SFINAE context, if any. + [[nodiscard]] SFINAETrap *getSFINAEContext() const { + return CurrentSFINAEContext; + } + [[nodiscard]] bool isSFINAEContext() const { + return CurrentSFINAEContext != nullptr; + } /// Perform substitution on the type T with a given set of template /// arguments. @@ -14637,7 +14642,8 @@ public: ArrayRef<UnexpandedParameterPack> Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool FailOnPackProducingTemplates, bool &ShouldExpand, - bool &RetainExpansion, UnsignedOrNone &NumExpansions); + bool &RetainExpansion, UnsignedOrNone &NumExpansions, + bool Diagnose = true); /// Determine the number of arguments in the given pack expansion /// type. @@ -15474,6 +15480,8 @@ public: std::optional<FunctionEffectMode> ActOnEffectExpression(Expr *CondExpr, StringRef AttributeName); + void ActOnCleanupAttr(Decl *D, const Attr *A); + private: /// The implementation of RequireCompleteType bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h index 104992e..af8e0e90 100644 --- a/clang/include/clang/Sema/SemaARM.h +++ b/clang/include/clang/Sema/SemaARM.h @@ -92,10 +92,14 @@ public: /// false otherwise. bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType); - bool checkTargetVersionAttr(const StringRef Str, const SourceLocation Loc); + bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc, + SmallString<64> &NewParam); bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params, SmallVectorImpl<SourceLocation> &Locs, SmallVectorImpl<SmallString<64>> &NewParams); + bool checkSVETypeSupport(QualType Ty, SourceLocation Loc, + const FunctionDecl *FD, + const llvm::StringMap<bool> &FeatureMap); }; SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); diff --git a/clang/include/clang/Sema/SemaCUDA.h b/clang/include/clang/Sema/SemaCUDA.h index dbc14328..dbb4290 100644 --- a/clang/include/clang/Sema/SemaCUDA.h +++ b/clang/include/clang/Sema/SemaCUDA.h @@ -273,6 +273,11 @@ public: /// of the function that will be called to configure kernel call, with the /// parameters specified via <<<>>>. std::string getConfigureFuncName() const; + /// Return the name of the parameter buffer allocation function for the + /// device kernel launch. + std::string getGetParameterBufferFuncName() const; + /// Return the name of the device kernel launch function. + std::string getLaunchDeviceFuncName() const; /// Record variables that are potentially ODR-used in CUDA/HIP. void recordPotentialODRUsedVariable(MultiExprArg Args, diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 8c3b6ae..a2faa91 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -20,7 +20,9 @@ #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/SemaBase.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringSet.h" #include "llvm/TargetParser/Triple.h" #include <initializer_list> @@ -132,9 +134,6 @@ public: void CheckEntryPoint(FunctionDecl *FD); bool CheckResourceBinOp(BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, SourceLocation Loc); - void DiagnoseAttrStageMismatch( - const Attr *A, llvm::Triple::EnvironmentType Stage, - std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages); QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS, QualType LHSType, QualType RHSType, @@ -169,6 +168,7 @@ public: void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL); void handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL); void handleVkBindingAttr(Decl *D, const ParsedAttr &AL); + void handleVkLocationAttr(Decl *D, const ParsedAttr &AL); void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL); void handleShaderAttr(Decl *D, const ParsedAttr &AL); void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL); @@ -176,18 +176,11 @@ public: bool handleResourceTypeAttr(QualType T, const ParsedAttr &AL); template <typename T> - T *createSemanticAttr(const AttributeCommonInfo &ACI, NamedDecl *TargetDecl, + T *createSemanticAttr(const AttributeCommonInfo &ACI, std::optional<unsigned> Location) { - T *Attr = - ::new (getASTContext()) T(getASTContext(), ACI, TargetDecl, - Location.value_or(0), Location.has_value()); - - if (!Attr->isSemanticIndexable() && Location.has_value()) { - Diag(Attr->getLocation(), diag::err_hlsl_semantic_indexing_not_supported) - << Attr->getAttrName()->getName(); - return nullptr; - } - return Attr; + return ::new (getASTContext()) + T(getASTContext(), ACI, ACI.getAttrName()->getName(), + Location.value_or(0)); } void diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL, @@ -244,9 +237,36 @@ private: IdentifierInfo *RootSigOverrideIdent = nullptr; + // Information about the current subtree being flattened. struct SemanticInfo { - HLSLSemanticAttr *Semantic; - std::optional<uint32_t> Index; + HLSLParsedSemanticAttr *Semantic; + std::optional<uint32_t> Index = std::nullopt; + }; + + // Bitmask used to recall if the current semantic subtree is + // input, output or inout. + enum IOType { + In = 0b01, + Out = 0b10, + InOut = 0b11, + }; + + // The context shared by all semantics with the same IOType during + // flattening. + struct SemanticContext { + // Present if any semantic sharing the same IO type has an explicit or + // implicit SPIR-V location index assigned. + std::optional<bool> UsesExplicitVkLocations = std::nullopt; + // The set of semantics found to be active during flattening. Used to detect + // index collisions. + llvm::StringSet<> ActiveSemantics = {}; + // The IOType of this semantic set. + IOType CurrentIOType; + }; + + struct SemanticStageInfo { + llvm::Triple::EnvironmentType Stage; + IOType AllowedIOTypesMask; }; private: @@ -255,18 +275,31 @@ private: const RecordType *RT); void checkSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param, - const HLSLSemanticAttr *SemanticAttr); - HLSLSemanticAttr *createSemantic(const SemanticInfo &Semantic, - DeclaratorDecl *TargetDecl); - bool determineActiveSemanticOnScalar(FunctionDecl *FD, DeclaratorDecl *D, - SemanticInfo &ActiveSemantic); - bool determineActiveSemantic(FunctionDecl *FD, DeclaratorDecl *D, - SemanticInfo &ActiveSemantic); + const HLSLAppliedSemanticAttr *SemanticAttr, + const SemanticContext &SC); + + bool determineActiveSemanticOnScalar(FunctionDecl *FD, + DeclaratorDecl *OutputDecl, + DeclaratorDecl *D, + SemanticInfo &ActiveSemantic, + SemanticContext &SC); + + bool determineActiveSemantic(FunctionDecl *FD, DeclaratorDecl *OutputDecl, + DeclaratorDecl *D, SemanticInfo &ActiveSemantic, + SemanticContext &SC); void processExplicitBindingsOnDecl(VarDecl *D); void diagnoseAvailabilityViolations(TranslationUnitDecl *TU); + void diagnoseAttrStageMismatch( + const Attr *A, llvm::Triple::EnvironmentType Stage, + std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages); + + void diagnoseSemanticStageMismatch( + const Attr *A, llvm::Triple::EnvironmentType Stage, IOType CurrentIOType, + std::initializer_list<SemanticStageInfo> AllowedStages); + uint32_t getNextImplicitBindingOrderID() { return ImplicitBindingNextOrderID++; } diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h index f751e98..b5e3eca 100644 --- a/clang/include/clang/Sema/SemaOpenACC.h +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -37,8 +37,16 @@ class Scope; class SemaOpenACC : public SemaBase { public: using DeclGroupPtrTy = OpaquePtr<DeclGroupRef>; + using RoutineRefListTy = std::pair<FunctionDecl *, OpenACCRoutineDecl *>; private: + // We save a list of routine clauses that refer to a different function(that + // is, routine-with-a-name) so that we can do the emission at the 'end'. We + // have to do this, since functions can be emitted before they are referenced, + // and the OpenACCRoutineDecl isn't necessarily emitted, as it might be in a + // function/etc. So we do these emits at the end of the TU. + llvm::SmallVector<RoutineRefListTy> RoutineRefList; + struct ComputeConstructInfo { /// Which type of compute construct we are inside of, which we can use to /// determine whether we should add loops to the above collection. We can @@ -752,6 +760,7 @@ public: }; SemaOpenACC(Sema &S); + void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU); // Called when we encounter a 'while' statement, before looking at its 'body'. void ActOnWhileStmt(SourceLocation WhileLoc); diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index ba12b40..2d05b44 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1174,6 +1174,8 @@ public: int ExtraModifier = -1; ///< Additional modifier for linear, map, depend or ///< lastprivate clause. int OriginalSharingModifier = 0; // Default is shared + int NeedDevicePtrModifier = 0; + SourceLocation NeedDevicePtrModifierLoc; SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> MapTypeModifiers; SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> @@ -1349,7 +1351,7 @@ public: OMPClause * ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers, ArrayRef<SourceLocation> MotionModifiersLoc, - CXXScopeSpec &MapperIdScopeSpec, + Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers = {}); @@ -1357,7 +1359,7 @@ public: OMPClause * ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers, ArrayRef<SourceLocation> MotionModifiersLoc, - CXXScopeSpec &MapperIdScopeSpec, + Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers = {}); @@ -1411,6 +1413,13 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); + /// Called on a well-formed 'dyn_groupprivate' clause. + OMPClause *ActOnOpenMPDynGroupprivateClause( + OpenMPDynGroupprivateClauseModifier M1, + OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, + SourceLocation M2Loc, SourceLocation EndLoc); + /// Called on well-formed 'doacross' clause. OMPClause * ActOnOpenMPDoacrossClause(OpenMPDoacrossClauseModifier DepType, diff --git a/clang/include/clang/Sema/SemaRISCV.h b/clang/include/clang/Sema/SemaRISCV.h index 844cc3c..863b8a1 100644 --- a/clang/include/clang/Sema/SemaRISCV.h +++ b/clang/include/clang/Sema/SemaRISCV.h @@ -56,7 +56,8 @@ public: std::unique_ptr<sema::RISCVIntrinsicManager> IntrinsicManager; - bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc); + bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc, + SmallString<64> &NewParam); bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params, SmallVectorImpl<SourceLocation> &Locs, SmallVectorImpl<SmallString<64>> &NewParams); diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 5d09d55..d7d429e 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -151,14 +151,14 @@ struct UnsafeQualTypeDenseMapInfo { }; /// An ID number that refers to a macro in an AST file. -using MacroID = uint32_t; +using MacroID = uint64_t; /// A global ID number that refers to a macro in an AST file. -using GlobalMacroID = uint32_t; +using GlobalMacroID = uint64_t; /// A local to a module ID number that refers to a macro in an /// AST file. -using LocalMacroID = uint32_t; +using LocalMacroID = uint64_t; /// The number of predefined macro IDs. const unsigned int NUM_PREDEF_MACRO_IDS = 1; @@ -179,7 +179,7 @@ using CXXCtorInitializersID = uint32_t; /// An ID number that refers to an entity in the detailed /// preprocessing record. -using PreprocessedEntityID = uint32_t; +using PreprocessedEntityID = uint64_t; /// An ID number that refers to a submodule in a module file. using SubmoduleID = uint32_t; diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 4ca45a1..d276f0d 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -800,14 +800,6 @@ private: /// files. llvm::DenseSet<LoadedMacroInfo> LoadedUndefs; - using GlobalMacroMapType = - ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>; - - /// Mapping from global macro IDs to the module in which the - /// macro resides along with the offset that should be added to the - /// global macro ID to produce a local ID. - GlobalMacroMapType GlobalMacroMap; - /// A vector containing submodules that have already been loaded. /// /// This vector is indexed by the Submodule ID (-1). NULL submodule entries @@ -1013,7 +1005,7 @@ private: /// /// The AST context tracks a few important decls, currently cudaConfigureCall, /// directly. - SmallVector<GlobalDeclID, 2> CUDASpecialDeclRefs; + SmallVector<GlobalDeclID, 4> CUDASpecialDeclRefs; /// The floating point pragma option settings. SmallVector<uint64_t, 1> FPPragmaOptions; @@ -1655,8 +1647,7 @@ private: /// Returns the first preprocessed entity ID that begins or ends after /// \arg Loc. - serialization::PreprocessedEntityID - findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const; + unsigned findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const; /// Find the next module that contains entities and return the ID /// of the first entry. @@ -1664,9 +1655,8 @@ private: /// \param SLocMapI points at a chunk of a module that contains no /// preprocessed entities or the entities it contains are not the /// ones we are looking for. - serialization::PreprocessedEntityID - findNextPreprocessedEntity( - GlobalSLocOffsetMapType::const_iterator SLocMapI) const; + unsigned findNextPreprocessedEntity( + GlobalSLocOffsetMapType::const_iterator SLocMapI) const; /// Returns (ModuleFile, Local index) pair for \p GlobalIndex of a /// preprocessed entity. @@ -1748,6 +1738,14 @@ private: std::pair<ModuleFile *, unsigned> translateIdentifierIDToIndex(serialization::IdentifierID ID) const; + /// Translate an \param MacroID ID to the index of MacrosLoaded + /// array and the corresponding module file. + std::pair<ModuleFile *, unsigned> + translateMacroIDToIndex(serialization::MacroID ID) const; + + unsigned translatePreprocessedEntityIDToIndex( + serialization::PreprocessedEntityID ID) const; + /// Translate an \param TypeID ID to the index of TypesLoaded /// array and the corresponding module file. std::pair<ModuleFile *, unsigned> @@ -2163,6 +2161,14 @@ public: LocalDeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M, GlobalDeclID GlobalID); + /// Reads a macro ID from the given position in a record in the + /// given module. + /// + /// \returns The declaration ID read from the record, adjusted to a global + /// Macro ID. + serialization::MacroID + ReadMacroID(ModuleFile &F, const RecordDataImpl &Record, unsigned &Idx); + /// Reads a declaration ID from the given position in a record in the /// given module. /// @@ -2388,7 +2394,8 @@ public: /// Retrieve the global macro ID corresponding to the given local /// ID within the given module file. - serialization::MacroID getGlobalMacroID(ModuleFile &M, unsigned LocalID); + serialization::MacroID getGlobalMacroID(ModuleFile &M, + serialization::MacroID LocalID); /// Read the source location entry with index ID. bool ReadSLocEntry(int ID) override; @@ -2572,8 +2579,8 @@ public: /// Determine the global preprocessed entity ID that corresponds to /// the given local ID within the given module. - serialization::PreprocessedEntityID - getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const; + serialization::PreprocessedEntityID getGlobalPreprocessedEntityID( + ModuleFile &M, serialization::PreprocessedEntityID LocalID) const; /// Add a macro to deserialize its macro directive history. /// diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 28c3e55..c77c98d 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -782,6 +782,10 @@ public: void AddLookupOffsets(const LookupBlockOffsets &Offsets, RecordDataImpl &Record); + /// Emit a reference to a macro. + void AddMacroRef(MacroInfo *MI, const IdentifierInfo *Name, + RecordDataImpl &Record); + /// Emit a reference to a declaration. void AddDeclRef(const Decl *D, RecordDataImpl &Record); // Emit a reference to a declaration if the declaration was emitted. diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index f20cb2f..783e2ba 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -353,9 +353,6 @@ public: /// Base macro ID for macros local to this module. serialization::MacroID BaseMacroID = 0; - /// Remapping table for macro IDs in this module. - ContinuousRangeMap<uint32_t, int, 2> MacroRemap; - /// The offset of the start of the set of defined macros. uint64_t MacroStartOffset = 0; @@ -372,9 +369,6 @@ public: /// this module. serialization::PreprocessedEntityID BasePreprocessedEntityID = 0; - /// Remapping table for preprocessed entity IDs in this module. - ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap; - const PPEntityOffset *PreprocessedEntityOffsets = nullptr; unsigned NumPreprocessedEntities = 0; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h index 1a9bef0..440603f 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h @@ -58,6 +58,8 @@ SVal getDynamicExtentWithOffset(ProgramStateRef State, SVal BufV); DefinedOrUnknownSVal getDynamicElementCountWithOffset(ProgramStateRef State, SVal BufV, QualType Ty); +void markAllDynamicExtentLive(ProgramStateRef State, SymbolReaper &SymReaper); + } // namespace ento } // namespace clang diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h index 7f25223..b0673b6 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h @@ -456,17 +456,15 @@ public: llvm::SMTExprRef OperandExp = getSymExpr(Solver, Ctx, USE->getOperand(), &OperandTy, hasComparison); - if (const BinarySymExpr *BSE = - dyn_cast<BinarySymExpr>(USE->getOperand())) { - if (USE->getOpcode() == UO_Minus && - BinaryOperator::isComparisonOp(BSE->getOpcode())) - // The comparison operator yields a boolean value in the Z3 - // language and applying the unary minus operator on a boolean - // crashes Z3. However, the unary minus does nothing in this - // context (a number is truthy if and only if its negative is - // truthy), so let's just ignore the unary minus. - // TODO: Replace this with a more general solution. - return OperandExp; + // When the operand is a bool expr, but the operator is an integeral + // operator, casting the bool expr to the integer before creating the + // unary operator. + // E.g. -(5 && a) + if (OperandTy == Ctx.BoolTy && OperandTy != *RetTy && + (*RetTy)->isIntegerType()) { + OperandExp = fromCast(Solver, OperandExp, (*RetTy), + Ctx.getTypeSize(*RetTy), OperandTy, 1); + OperandTy = (*RetTy); } llvm::SMTExprRef UnaryExp = diff --git a/clang/include/clang/Tooling/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanningTool.h new file mode 100644 index 0000000..0af07ea --- /dev/null +++ b/clang/include/clang/Tooling/DependencyScanningTool.h @@ -0,0 +1,163 @@ +//===----------------------------------------------------------------------===// +// +// 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 LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H +#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H + +#include "clang/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/DependencyScanningUtils.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" +#include "clang/DependencyScanning/ModuleDepCollector.h" +#include "clang/Tooling/CompilationDatabase.h" +#include "llvm/ADT/DenseSet.h" +#include <optional> +#include <string> +#include <vector> + +namespace clang { +namespace tooling { + +struct P1689Rule { + std::string PrimaryOutput; + std::optional<dependencies::P1689ModuleInfo> Provides; + std::vector<dependencies::P1689ModuleInfo> Requires; +}; + +/// The high-level implementation of the dependency discovery tool that runs on +/// an individual worker thread. +class DependencyScanningTool { +public: + /// Construct a dependency scanning tool. + /// + /// @param Service The parent service. Must outlive the tool. + /// @param FS The filesystem for the tool to use. Defaults to the physical FS. + DependencyScanningTool(dependencies::DependencyScanningService &Service, + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = + llvm::vfs::createPhysicalFileSystem()); + + /// Print out the dependency information into a string using the dependency + /// file format that is specified in the options (-MD is the default) and + /// return it. + /// + /// \returns A \c StringError with the diagnostic output if clang errors + /// occurred, dependency file contents otherwise. + llvm::Expected<std::string> + getDependencyFile(ArrayRef<std::string> CommandLine, StringRef CWD); + + /// Collect the module dependency in P1689 format for C++20 named modules. + /// + /// \param MakeformatOutput The output parameter for dependency information + /// in make format if the command line requires to generate make-format + /// dependency information by `-MD -MF <dep_file>`. + /// + /// \param MakeformatOutputPath The output parameter for the path to + /// \param MakeformatOutput. + /// + /// \returns A \c StringError with the diagnostic output if clang errors + /// occurred, P1689 dependency format rules otherwise. + llvm::Expected<P1689Rule> + getP1689ModuleDependencyFile(const CompileCommand &Command, StringRef CWD, + std::string &MakeformatOutput, + std::string &MakeformatOutputPath); + llvm::Expected<P1689Rule> + getP1689ModuleDependencyFile(const CompileCommand &Command, StringRef CWD) { + std::string MakeformatOutput; + std::string MakeformatOutputPath; + + return getP1689ModuleDependencyFile(Command, CWD, MakeformatOutput, + MakeformatOutputPath); + } + + /// Given a Clang driver command-line for a translation unit, gather the + /// modular dependencies and return the information needed for explicit build. + /// + /// \param AlreadySeen This stores modules which have previously been + /// reported. Use the same instance for all calls to this + /// function for a single \c DependencyScanningTool in a + /// single build. Use a different one for different tools, + /// and clear it between builds. + /// \param LookupModuleOutput This function is called to fill in + /// "-fmodule-file=", "-o" and other output + /// arguments for dependencies. + /// \param TUBuffer Optional memory buffer for translation unit input. If + /// TUBuffer is nullopt, the input should be included in the + /// Commandline already. + /// + /// \returns a \c StringError with the diagnostic output if clang errors + /// occurred, \c TranslationUnitDeps otherwise. + llvm::Expected<dependencies::TranslationUnitDeps> + getTranslationUnitDependencies( + ArrayRef<std::string> CommandLine, StringRef CWD, + const llvm::DenseSet<dependencies::ModuleID> &AlreadySeen, + dependencies::LookupModuleOutputCallback LookupModuleOutput, + std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt); + + /// Given a compilation context specified via the Clang driver command-line, + /// gather modular dependencies of module with the given name, and return the + /// information needed for explicit build. + /// TODO: this method should be removed as soon as Swift and our C-APIs adopt + /// CompilerInstanceWithContext. We are keeping it here so that it is easier + /// to coordinate with Swift and C-API changes. + llvm::Expected<dependencies::TranslationUnitDeps> getModuleDependencies( + StringRef ModuleName, ArrayRef<std::string> CommandLine, StringRef CWD, + const llvm::DenseSet<dependencies::ModuleID> &AlreadySeen, + dependencies::LookupModuleOutputCallback LookupModuleOutput); + + /// The following three methods provide a new interface to perform + /// by name dependency scan. The new interface's intention is to improve + /// dependency scanning performance when a sequence of name is looked up + /// with the same current working directory and the command line. + + /// @brief Initializing the context and the compiler instance. + /// This method must be called before calling + /// computeDependenciesByNameWithContext. + /// @param CWD The current working directory used during the scan. + /// @param CommandLine The commandline used for the scan. + /// @return Error if the initializaiton fails. + llvm::Error + initializeCompilerInstanceWithContext(StringRef CWD, + ArrayRef<std::string> CommandLine); + + /// @brief Computes the dependeny for the module named ModuleName. + /// @param ModuleName The name of the module for which this method computes + ///. dependencies. + /// @param AlreadySeen This stores modules which have previously been + /// reported. Use the same instance for all calls to this + /// function for a single \c DependencyScanningTool in a + /// single build. Note that this parameter is not part of + /// the context because it can be shared across different + /// worker threads and each worker thread may update it. + /// @param LookupModuleOutput This function is called to fill in + /// "-fmodule-file=", "-o" and other output + /// arguments for dependencies. + /// @return An instance of \c TranslationUnitDeps if the scan is successful. + /// Otherwise it returns an error. + llvm::Expected<dependencies::TranslationUnitDeps> + computeDependenciesByNameWithContext( + StringRef ModuleName, + const llvm::DenseSet<dependencies::ModuleID> &AlreadySeen, + dependencies::LookupModuleOutputCallback LookupModuleOutput); + + /// @brief This method finializes the compiler instance. It finalizes the + /// diagnostics and deletes the compiler instance. Call this method + /// once all names for a same commandline are scanned. + /// @return Error if an error occured during finalization. + llvm::Error finalizeCompilerInstanceWithContext(); + + llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); } + +private: + dependencies::DependencyScanningWorker Worker; + std::unique_ptr<dependencies::TextDiagnosticsPrinterWithOutput> + DiagPrinterWithOS; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H diff --git a/clang/include/clang/Tooling/Transformer/RangeSelector.h b/clang/include/clang/Tooling/Transformer/RangeSelector.h index 462a9da..c76a510 100644 --- a/clang/include/clang/Tooling/Transformer/RangeSelector.h +++ b/clang/include/clang/Tooling/Transformer/RangeSelector.h @@ -37,6 +37,10 @@ RangeSelector enclose(RangeSelector Begin, RangeSelector End); /// Convenience version of \c range where end-points are bound nodes. RangeSelector encloseNodes(std::string BeginID, std::string EndID); +/// Selects the merge of the two ranges, i.e. from min(First.begin, +/// Second.begin) to max(First.end, Second.end). +RangeSelector merge(RangeSelector First, RangeSelector Second); + /// DEPRECATED. Use `enclose`. inline RangeSelector range(RangeSelector Begin, RangeSelector End) { return enclose(std::move(Begin), std::move(End)); diff --git a/clang/include/module.modulemap b/clang/include/module.modulemap index c553526..a11c868 100644 --- a/clang/include/module.modulemap +++ b/clang/include/module.modulemap @@ -146,6 +146,7 @@ module Clang_Lex { module * { export * } } +module Clang_Options { requires cplusplus umbrella "clang/Options" module * { export * } } module Clang_Parse { requires cplusplus umbrella "clang/Parse" module * { export * } } module Clang_Rewrite { requires cplusplus umbrella "clang/Rewrite/Core" module * { export * } } module Clang_RewriteFrontend { requires cplusplus umbrella "clang/Rewrite/Frontend" module * { export * } } |
