diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:53:39 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:53:39 +0000 |
commit | 11edbfca22fe6e8280caeb77832f4dfbb68ed274 (patch) | |
tree | a3e238dbe004c4ea0f061135a0c1d4430e50c28e | |
parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) |
Vendor import of llvm-project branch release/16.x llvmorg-16.0.0-rc2-10-g073506d8c15c.vendor/llvm-project/llvmorg-16.0.0-rc2-10-g073506d8c15c
64 files changed, 835 insertions, 446 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index fd758ddde085..a3e54285f89f 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -34,7 +34,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 62 +#define CINDEX_VERSION_MINOR 63 #define CINDEX_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1)) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index c367a34b762b..36d4bc2a700d 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1607,11 +1607,6 @@ def err_import_in_wrong_fragment : Error< def err_export_empty : Error<"export declaration cannot be empty">; } -def ext_offsetof_member_designator : Extension< - "using %select{a member access expression|an array subscript expression}0 " - "within '%select{__builtin_offsetof|offsetof}1' is a Clang extension">, - InGroup<GNUOffsetofExtensions>; - let CategoryName = "Generics Issue" in { def err_objc_expected_type_parameter : Error< diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index e910036117b7..e547bbd34b5e 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -1249,16 +1249,37 @@ def SVZIP1_BF16 : SInst<"svzip1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve def SVZIP2_BF16 : SInst<"svzip2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2">; } -def SVREV_B : SInst<"svrev_{d}", "PP", "PcPsPiPl", MergeNone, "aarch64_sve_rev">; -def SVSEL_B : SInst<"svsel[_b]", "PPPP", "Pc", MergeNone, "aarch64_sve_sel">; -def SVTRN1_B : SInst<"svtrn1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_trn1">; -def SVTRN2_B : SInst<"svtrn2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_trn2">; -def SVPUNPKHI : SInst<"svunpkhi[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpkhi">; -def SVPUNPKLO : SInst<"svunpklo[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpklo">; -def SVUZP1_B : SInst<"svuzp1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_uzp1">; -def SVUZP2_B : SInst<"svuzp2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_uzp2">; -def SVZIP1_B : SInst<"svzip1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_zip1">; -def SVZIP2_B : SInst<"svzip2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_zip2">; +def SVREV_B8 : SInst<"svrev_b8", "PP", "Pc", MergeNone, "aarch64_sve_rev">; +def SVREV_B16 : SInst<"svrev_b16", "PP", "Pc", MergeNone, "aarch64_sve_rev_b16", [IsOverloadNone]>; +def SVREV_B32 : SInst<"svrev_b32", "PP", "Pc", MergeNone, "aarch64_sve_rev_b32", [IsOverloadNone]>; +def SVREV_B64 : SInst<"svrev_b64", "PP", "Pc", MergeNone, "aarch64_sve_rev_b64", [IsOverloadNone]>; +def SVSEL_B : SInst<"svsel[_b]", "PPPP", "Pc", MergeNone, "aarch64_sve_sel">; +def SVTRN1_B8 : SInst<"svtrn1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn1">; +def SVTRN1_B16 : SInst<"svtrn1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b16", [IsOverloadNone]>; +def SVTRN1_B32 : SInst<"svtrn1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b32", [IsOverloadNone]>; +def SVTRN1_B64 : SInst<"svtrn1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b64", [IsOverloadNone]>; +def SVTRN2_B8 : SInst<"svtrn2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn2">; +def SVTRN2_B16 : SInst<"svtrn2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b16", [IsOverloadNone]>; +def SVTRN2_B32 : SInst<"svtrn2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b32", [IsOverloadNone]>; +def SVTRN2_B64 : SInst<"svtrn2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b64", [IsOverloadNone]>; +def SVPUNPKHI : SInst<"svunpkhi[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpkhi">; +def SVPUNPKLO : SInst<"svunpklo[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpklo">; +def SVUZP1_B8 : SInst<"svuzp1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1">; +def SVUZP1_B16 : SInst<"svuzp1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b16", [IsOverloadNone]>; +def SVUZP1_B32 : SInst<"svuzp1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b32", [IsOverloadNone]>; +def SVUZP1_B64 : SInst<"svuzp1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b64", [IsOverloadNone]>; +def SVUZP2_B8 : SInst<"svuzp2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2">; +def SVUZP2_B16 : SInst<"svuzp2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b16", [IsOverloadNone]>; +def SVUZP2_B32 : SInst<"svuzp2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b32", [IsOverloadNone]>; +def SVUZP2_B64 : SInst<"svuzp2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b64", [IsOverloadNone]>; +def SVZIP1_B8 : SInst<"svzip1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip1">; +def SVZIP1_B16 : SInst<"svzip1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b16", [IsOverloadNone]>; +def SVZIP1_B32 : SInst<"svzip1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b32", [IsOverloadNone]>; +def SVZIP1_B64 : SInst<"svzip1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b64", [IsOverloadNone]>; +def SVZIP2_B : SInst<"svzip2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip2">; +def SVZIP2_B16 : SInst<"svzip2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b16", [IsOverloadNone]>; +def SVZIP2_B32 : SInst<"svzip2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b32", [IsOverloadNone]>; +def SVZIP2_B64 : SInst<"svzip2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b64", [IsOverloadNone]>; //////////////////////////////////////////////////////////////////////////////// // Predicate creation diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td index c63cba9aa459..b23e26ecaa57 100644 --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -1539,7 +1539,7 @@ enum RVV_CSR { }; static __inline__ __attribute__((__always_inline__, __nodebug__)) -unsigned long vread_csr(enum RVV_CSR __csr) { +unsigned long __riscv_vread_csr(enum RVV_CSR __csr) { unsigned long __rv = 0; switch (__csr) { case RVV_VSTART: @@ -1559,7 +1559,7 @@ unsigned long vread_csr(enum RVV_CSR __csr) { } static __inline__ __attribute__((__always_inline__, __nodebug__)) -void vwrite_csr(enum RVV_CSR __csr, unsigned long __value) { +void __riscv_vwrite_csr(enum RVV_CSR __csr, unsigned long __value) { switch (__csr) { case RVV_VSTART: __asm__ __volatile__ ("csrw\tvstart, %z0" : : "rJ"(__value) : "memory"); @@ -1580,7 +1580,7 @@ def vread_vwrite_csr: RVVHeader; let HeaderCode = [{ -#define vlenb() __builtin_rvv_vlenb() +#define __riscv_vlenb() __builtin_rvv_vlenb() }] in def vlenb_macro: RVVHeader; @@ -1611,62 +1611,62 @@ let HasBuiltinAlias = false, HasVL = false, HasMasked = false, // and LMUL. let HeaderCode = [{ -#define vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6) -#define vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7) -#define vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0) -#define vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1) -#define vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2) -#define vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3) - -#define vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7) -#define vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0) -#define vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1) -#define vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2) -#define vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3) - -#define vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0) -#define vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1) -#define vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2) -#define vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3) +#define __riscv_vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6) +#define __riscv_vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7) +#define __riscv_vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0) +#define __riscv_vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1) +#define __riscv_vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2) +#define __riscv_vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3) + +#define __riscv_vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7) +#define __riscv_vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0) +#define __riscv_vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1) +#define __riscv_vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2) +#define __riscv_vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3) + +#define __riscv_vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0) +#define __riscv_vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1) +#define __riscv_vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2) +#define __riscv_vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3) #if __riscv_v_elen >= 64 -#define vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5) -#define vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6) -#define vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7) - -#define vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0) -#define vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1) -#define vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2) -#define vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3) +#define __riscv_vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5) +#define __riscv_vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6) +#define __riscv_vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7) + +#define __riscv_vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0) +#define __riscv_vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1) +#define __riscv_vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2) +#define __riscv_vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3) #endif -#define vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6) -#define vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7) -#define vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0) -#define vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1) -#define vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2) -#define vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3) +#define __riscv_vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6) +#define __riscv_vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7) +#define __riscv_vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0) +#define __riscv_vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1) +#define __riscv_vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2) +#define __riscv_vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3) -#define vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7) -#define vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0) -#define vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1) -#define vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2) -#define vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3) +#define __riscv_vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7) +#define __riscv_vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0) +#define __riscv_vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1) +#define __riscv_vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2) +#define __riscv_vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3) -#define vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0) -#define vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1) -#define vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2) -#define vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3) +#define __riscv_vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0) +#define __riscv_vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1) +#define __riscv_vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2) +#define __riscv_vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3) #if __riscv_v_elen >= 64 -#define vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5) -#define vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6) -#define vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7) - -#define vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0) -#define vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1) -#define vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2) -#define vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3) +#define __riscv_vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5) +#define __riscv_vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6) +#define __riscv_vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7) + +#define __riscv_vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0) +#define __riscv_vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1) +#define __riscv_vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2) +#define __riscv_vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3) #endif }] in diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index a95fe5686009..69fe2c541607 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -506,16 +506,8 @@ public: assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type"); return TypeRep; } - // Returns the underlying decl, if any. Decl *getRepAsDecl() const { - auto *D = getRepAsFoundDecl(); - if (const auto *Using = dyn_cast_or_null<UsingShadowDecl>(D)) - return Using->getTargetDecl(); - return D; - } - // Returns the originally found decl, if any. - Decl *getRepAsFoundDecl() const { - assert(isDeclRep((TST)TypeSpecType) && "DeclSpec does not store a decl"); + assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl"); return DeclRep; } Expr *getRepAsExpr() const { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 3e3fb2b0cc56..66b018d8fba1 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3327,9 +3327,7 @@ public: SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, - OffsetOfKind OOK, - UsingShadowDecl*& FoundUsingShadow, - SkipBodyInfo *SkipBody = nullptr); + OffsetOfKind OOK, SkipBodyInfo *SkipBody = nullptr); DeclResult ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, unsigned TagSpec, SourceLocation TagLoc, @@ -7281,24 +7279,34 @@ private: private: // The current stack of constraint satisfactions, so we can exit-early. - llvm::SmallVector<llvm::FoldingSetNodeID, 10> SatisfactionStack; + using SatisfactionStackEntryTy = + std::pair<const NamedDecl *, llvm::FoldingSetNodeID>; + llvm::SmallVector<SatisfactionStackEntryTy, 10> + SatisfactionStack; public: - void PushSatisfactionStackEntry(const llvm::FoldingSetNodeID &ID) { - SatisfactionStack.push_back(ID); + void PushSatisfactionStackEntry(const NamedDecl *D, + const llvm::FoldingSetNodeID &ID) { + const NamedDecl *Can = cast<NamedDecl>(D->getCanonicalDecl()); + SatisfactionStack.emplace_back(Can, ID); } void PopSatisfactionStackEntry() { SatisfactionStack.pop_back(); } - bool SatisfactionStackContains(const llvm::FoldingSetNodeID &ID) const { - return llvm::find(SatisfactionStack, ID) != SatisfactionStack.end(); + bool SatisfactionStackContains(const NamedDecl *D, + const llvm::FoldingSetNodeID &ID) const { + const NamedDecl *Can = cast<NamedDecl>(D->getCanonicalDecl()); + return llvm::find(SatisfactionStack, + SatisfactionStackEntryTy{Can, ID}) != + SatisfactionStack.end(); } // Resets the current SatisfactionStack for cases where we are instantiating // constraints as a 'side effect' of normal instantiation in a way that is not // indicative of recursive definition. class SatisfactionStackResetRAII { - llvm::SmallVector<llvm::FoldingSetNodeID, 10> BackupSatisfactionStack; + llvm::SmallVector<SatisfactionStackEntryTy, 10> + BackupSatisfactionStack; Sema &SemaRef; public: @@ -7311,8 +7319,8 @@ public: } }; - void - SwapSatisfactionStack(llvm::SmallVectorImpl<llvm::FoldingSetNodeID> &NewSS) { + void SwapSatisfactionStack( + llvm::SmallVectorImpl<SatisfactionStackEntryTy> &NewSS) { SatisfactionStack.swap(NewSS); } diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h index fc53d70019c5..bf31dced98b2 100644 --- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h +++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h @@ -92,25 +92,24 @@ enum class TypeModifier : uint8_t { LLVM_MARK_AS_BITMASK_ENUM(LMUL1), }; -struct Policy { - bool IsUnspecified = false; +class Policy { +public: enum PolicyType { Undisturbed, Agnostic, }; - PolicyType TailPolicy = Agnostic; - PolicyType MaskPolicy = Agnostic; - bool HasTailPolicy, HasMaskPolicy; - Policy(bool HasTailPolicy, bool HasMaskPolicy) - : IsUnspecified(true), HasTailPolicy(HasTailPolicy), - HasMaskPolicy(HasMaskPolicy) {} - Policy(PolicyType TailPolicy, bool HasTailPolicy, bool HasMaskPolicy) - : TailPolicy(TailPolicy), HasTailPolicy(HasTailPolicy), - HasMaskPolicy(HasMaskPolicy) {} - Policy(PolicyType TailPolicy, PolicyType MaskPolicy, bool HasTailPolicy, - bool HasMaskPolicy) - : TailPolicy(TailPolicy), MaskPolicy(MaskPolicy), - HasTailPolicy(HasTailPolicy), HasMaskPolicy(HasMaskPolicy) {} + +private: + // The default assumption for an RVV instruction is TAMA, as an undisturbed + // policy generally will affect the performance of an out-of-order core. + const PolicyType TailPolicy = Agnostic; + const PolicyType MaskPolicy = Agnostic; + +public: + Policy() = default; + Policy(PolicyType TailPolicy) : TailPolicy(TailPolicy) {} + Policy(PolicyType TailPolicy, PolicyType MaskPolicy) + : TailPolicy(TailPolicy), MaskPolicy(MaskPolicy) {} bool isTAMAPolicy() const { return TailPolicy == Agnostic && MaskPolicy == Agnostic; @@ -136,17 +135,8 @@ struct Policy { bool isMUPolicy() const { return MaskPolicy == Undisturbed; } - bool hasTailPolicy() const { return HasTailPolicy; } - - bool hasMaskPolicy() const { return HasMaskPolicy; } - - bool isUnspecified() const { return IsUnspecified; } - bool operator==(const Policy &Other) const { - return IsUnspecified == Other.IsUnspecified && - TailPolicy == Other.TailPolicy && MaskPolicy == Other.MaskPolicy && - HasTailPolicy == Other.HasTailPolicy && - HasMaskPolicy == Other.HasMaskPolicy; + return TailPolicy == Other.TailPolicy && MaskPolicy == Other.MaskPolicy; } bool operator!=(const Policy &Other) const { return !(*this == Other); } @@ -422,7 +412,6 @@ public: return IntrinsicTypes; } Policy getPolicyAttrs() const { - assert(PolicyAttrs.IsUnspecified == false); return PolicyAttrs; } unsigned getPolicyAttrsBits() const { @@ -431,8 +420,6 @@ public: // The 1st bit simulates the `vma` of RVV // int PolicyAttrs = 0; - assert(PolicyAttrs.IsUnspecified == false); - if (PolicyAttrs.isTUMAPolicy()) return 2; if (PolicyAttrs.isTAMAPolicy()) @@ -459,8 +446,7 @@ public: unsigned NF, PolicyScheme DefaultScheme, Policy PolicyAttrs); - static llvm::SmallVector<Policy> - getSupportedUnMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy); + static llvm::SmallVector<Policy> getSupportedUnMaskedPolicies(); static llvm::SmallVector<Policy> getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy); diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index dfed95f0513f..997398da7972 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -687,9 +687,13 @@ void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, if (ArchInfo == llvm::AArch64::INVALID) return; // Not an architecure, nothing more to do. + // Disabling an architecture feature does not affect dependent features + if (!Enabled) + return; + for (const auto *OtherArch : llvm::AArch64::ArchInfos) if (ArchInfo.implies(*OtherArch)) - Features[OtherArch->getSubArch()] = Enabled; + Features[OtherArch->getSubArch()] = true; // Set any features implied by the architecture uint64_t Extensions = diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 25fda05da033..7c801657b6ac 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -197,8 +197,8 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, if (ISAInfo->hasExtension("zve32x")) { Builder.defineMacro("__riscv_vector"); - // Currently we support the v0.10 RISC-V V intrinsics. - Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 10))); + // Currently we support the v0.11 RISC-V V intrinsics. + Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 11))); } } diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index cb3171227530..490e20ce4514 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -795,13 +795,13 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasHRESET) Builder.defineMacro("__HRESET__"); if (HasAMXTILE) - Builder.defineMacro("__AMXTILE__"); + Builder.defineMacro("__AMX_TILE__"); if (HasAMXINT8) - Builder.defineMacro("__AMXINT8__"); + Builder.defineMacro("__AMX_INT8__"); if (HasAMXBF16) - Builder.defineMacro("__AMXBF16__"); + Builder.defineMacro("__AMX_BF16__"); if (HasAMXFP16) - Builder.defineMacro("__AMXFP16__"); + Builder.defineMacro("__AMX_FP16__"); if (HasCMPCCXADD) Builder.defineMacro("__CMPCCXADD__"); if (HasRAOINT) diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index be1dbe8480c6..a9119abad81d 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -7418,18 +7418,28 @@ public: }; class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { + ASTContext &Ctx; + + const SystemZABIInfo &getABIInfo() const { + return static_cast<const SystemZABIInfo&>(TargetCodeGenInfo::getABIInfo()); + } + // These are used for speeding up the search for a visible vector ABI. mutable bool HasVisibleVecABIFlag = false; mutable std::set<const Type *> SeenTypes; - // Returns true (the first time) if Ty is or found to make use of a vector - // type (e.g. as a function argument). - bool isVectorTypeBased(const Type *Ty) const; + // Returns true (the first time) if Ty is, or is found to include, a vector + // type that exposes the vector ABI. This is any vector >=16 bytes which + // with vector support are aligned to only 8 bytes. When IsParam is true, + // the type belongs to a value as passed between functions. If it is a + // vector <=16 bytes it will be passed in a vector register (if supported). + bool isVectorTypeBased(const Type *Ty, bool IsParam) const; public: SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI) : TargetCodeGenInfo( - std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)) { + std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)), + Ctx(CGT.getContext()) { SwiftInfo = std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false); } @@ -7439,9 +7449,9 @@ public: // indicating a visible vector ABI is added. Eventually this will result in // a GNU attribute indicating the vector ABI of the module. Ty is the type // of a variable or function parameter that is globally visible. - void handleExternallyVisibleObjABI(const Type *Ty, - CodeGen::CodeGenModule &M) const { - if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty)) { + void handleExternallyVisibleObjABI(const Type *Ty, CodeGen::CodeGenModule &M, + bool IsParam) const { + if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty, IsParam)) { M.getModule().addModuleFlag(llvm::Module::Warning, "s390x-visible-vector-ABI", 1); HasVisibleVecABIFlag = true; @@ -7457,11 +7467,13 @@ public: // variable or function. if (const auto *VD = dyn_cast<VarDecl>(D)) { if (VD->isExternallyVisible()) - handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M); + handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M, + /*IsParam*/false); } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isExternallyVisible()) - handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M); + handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M, + /*IsParam*/false); } } @@ -7571,17 +7583,18 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const { // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) - for (const auto &I : CXXRD->bases()) { - QualType Base = I.getType(); + if (CXXRD->hasDefinition()) + for (const auto &I : CXXRD->bases()) { + QualType Base = I.getType(); - // Empty bases don't affect things either way. - if (isEmptyRecord(getContext(), Base, true)) - continue; + // Empty bases don't affect things either way. + if (isEmptyRecord(getContext(), Base, true)) + continue; - if (!Found.isNull()) - return Ty; - Found = GetSingleElementType(Base); - } + if (!Found.isNull()) + return Ty; + Found = GetSingleElementType(Base); + } // Check the fields. for (const auto *FD : RD->fields()) { @@ -7635,7 +7648,8 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, bool IsVector = false; CharUnits UnpaddedSize; CharUnits DirectAlign; - SZCGI.handleExternallyVisibleObjABI(Ty.getTypePtr(), CGT.getCGM()); + SZCGI.handleExternallyVisibleObjABI(Ty.getTypePtr(), CGT.getCGM(), + /*IsParam*/true); if (IsIndirect) { DirectTy = llvm::PointerType::getUnqual(DirectTy); UnpaddedSize = DirectAlign = CharUnits::fromQuantity(8); @@ -7843,35 +7857,57 @@ void SystemZABIInfo::computeInfo(CGFunctionInfo &FI) const { // Check if a vararg vector argument is passed, in which case the // vector ABI becomes visible as the va_list could be passed on to // other functions. - SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM()); + SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM(), + /*IsParam*/true); } } -bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty) const { - while (Ty->isPointerType() || Ty->isArrayType()) - Ty = Ty->getPointeeOrArrayElementType(); +bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, + bool IsParam) const { if (!SeenTypes.insert(Ty).second) return false; - if (Ty->isVectorType()) - return true; + + if (IsParam) { + // A narrow (<16 bytes) vector will as a parameter also expose the ABI as + // it will be passed in a vector register. A wide (>16 bytes) vector will + // be passed via "hidden" pointer where any extra alignment is not + // required (per GCC). + const Type *SingleEltTy = + getABIInfo().GetSingleElementType(QualType(Ty, 0)).getTypePtr(); + bool SingleVecEltStruct = SingleEltTy != Ty && SingleEltTy->isVectorType() && + Ctx.getTypeSize(SingleEltTy) == Ctx.getTypeSize(Ty); + if (Ty->isVectorType() || SingleVecEltStruct) + return Ctx.getTypeSize(Ty) / 8 <= 16; + } + + // Assume pointers are dereferenced. + while (Ty->isPointerType() || Ty->isArrayType()) + Ty = Ty->getPointeeOrArrayElementType(); + + // Vectors >= 16 bytes expose the ABI through alignment requirements. + if (Ty->isVectorType() && Ctx.getTypeSize(Ty) / 8 >= 16) + return true; + if (const auto *RecordTy = Ty->getAs<RecordType>()) { const RecordDecl *RD = RecordTy->getDecl(); if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) if (CXXRD->hasDefinition()) for (const auto &I : CXXRD->bases()) - if (isVectorTypeBased(I.getType().getTypePtr())) + if (isVectorTypeBased(I.getType().getTypePtr(), /*IsParam*/false)) return true; for (const auto *FD : RD->fields()) - if (isVectorTypeBased(FD->getType().getTypePtr())) + if (isVectorTypeBased(FD->getType().getTypePtr(), /*IsParam*/false)) return true; } + if (const auto *FT = Ty->getAs<FunctionType>()) - if (isVectorTypeBased(FT->getReturnType().getTypePtr())) + if (isVectorTypeBased(FT->getReturnType().getTypePtr(), /*IsParam*/true)) return true; if (const FunctionProtoType *Proto = Ty->getAs<FunctionProtoType>()) for (auto ParamType : Proto->getParamTypes()) - if (isVectorTypeBased(ParamType.getTypePtr())) + if (isVectorTypeBased(ParamType.getTypePtr(), /*IsParam*/true)) return true; + return false; } diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 484c8c070264..9a231c06a074 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -443,7 +443,7 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--gpu-name"); CmdArgs.push_back(Args.MakeArgString(CudaArchToString(gpu_arch))); CmdArgs.push_back("--output-file"); - const char *OutputFileName = Args.MakeArgString(TC.getInputFilename(Output)); + std::string OutputFileName = TC.getInputFilename(Output); // If we are invoking `nvlink` internally we need to output a `.cubin` file. // Checking if the output is a temporary is the cleanest way to determine @@ -455,12 +455,12 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, C.getTempFiles().end()) { SmallString<256> Filename(Output.getFilename()); llvm::sys::path::replace_extension(Filename, "cubin"); - OutputFileName = Args.MakeArgString(Filename); + OutputFileName = Filename.str(); } if (Output.isFilename() && OutputFileName != Output.getFilename()) - C.addTempFile(OutputFileName); + C.addTempFile(Args.MakeArgString(OutputFileName)); - CmdArgs.push_back(OutputFileName); + CmdArgs.push_back(Args.MakeArgString(OutputFileName)); for (const auto &II : Inputs) CmdArgs.push_back(Args.MakeArgString(II.getFilename())); diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 49c30ca78deb..ca651eaa9440 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3833,6 +3833,9 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, return true; if (Style.isCpp()) { + // Space between UDL and dot: auto b = 4s .count(); + if (Right.is(tok::period) && Left.is(tok::numeric_constant)) + return true; // Space between import <iostream>. // or import .....; if (Left.is(Keywords.kw_import) && Right.isOneOf(tok::less, tok::ellipsis)) diff --git a/clang/lib/Headers/immintrin.h b/clang/lib/Headers/immintrin.h index 6967b46fdb24..0d2e8be6e486 100644 --- a/clang/lib/Headers/immintrin.h +++ b/clang/lib/Headers/immintrin.h @@ -524,7 +524,7 @@ _storebe_i64(void * __P, long long __D) { #include <invpcidintrin.h> #endif #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AMXFP16__) + defined(__AMX_FP16__) #include <amxfp16intrin.h> #endif @@ -534,7 +534,7 @@ _storebe_i64(void * __P, long long __D) { #endif #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AMXTILE__) || defined(__AMXINT8__) || defined(__AMXBF16__) + defined(__AMX_TILE__) || defined(__AMX_INT8__) || defined(__AMX_BF16__) #include <amxintrin.h> #endif diff --git a/clang/lib/Headers/smmintrin.h b/clang/lib/Headers/smmintrin.h index 2111c24f31a6..16d8855a1c0b 100644 --- a/clang/lib/Headers/smmintrin.h +++ b/clang/lib/Headers/smmintrin.h @@ -1145,7 +1145,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_testnzc_si128(__m128i __M, /// A 128-bit integer vector containing the bits to be tested. /// \returns TRUE if the bits specified in the operand are all set to 1; FALSE /// otherwise. -#define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_cmpeq_epi32((V), (V))) +#define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_set1_epi32(-1)) /// Tests whether the specified bits in a 128-bit integer vector are /// neither all zeros nor all ones. diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index c7fd1156928c..e6812ac72c88 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4965,7 +4965,6 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, bool IsDependent = false; const char *PrevSpec = nullptr; unsigned DiagID; - UsingShadowDecl* FoundUsing = nullptr; Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS, Name, NameLoc, attrs, AS, DS.getModulePrivateSpecLoc(), @@ -4974,7 +4973,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, BaseType, DSC == DeclSpecContext::DSC_type_specifier, DSC == DeclSpecContext::DSC_template_param || DSC == DeclSpecContext::DSC_template_type_arg, - OffsetOfState, FoundUsing, &SkipBody).get(); + OffsetOfState, &SkipBody).get(); if (SkipBody.ShouldSkip) { assert(TUK == Sema::TUK_Definition && "can only skip a definition"); @@ -4984,8 +4983,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, T.skipToEnd(); if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, - NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec, - DiagID, FoundUsing ? FoundUsing : TagDecl, Owned, + NameLoc.isValid() ? NameLoc : StartLoc, + PrevSpec, DiagID, TagDecl, Owned, Actions.getASTContext().getPrintingPolicy())) Diag(StartLoc, DiagID) << PrevSpec; return; @@ -5039,8 +5038,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, } if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, - NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec, - DiagID, FoundUsing ? FoundUsing : TagDecl, Owned, + NameLoc.isValid() ? NameLoc : StartLoc, + PrevSpec, DiagID, TagDecl, Owned, Actions.getASTContext().getPrintingPolicy())) Diag(StartLoc, DiagID) << PrevSpec; } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index b26ec00cfedf..227c1df2bddd 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1934,7 +1934,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // Create the tag portion of the class or class template. DeclResult TagOrTempResult = true; // invalid TypeResult TypeResult = true; // invalid - UsingShadowDecl *FoundUsing = nullptr; bool Owned = false; Sema::SkipBodyInfo SkipBody; @@ -2075,7 +2074,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, DSC == DeclSpecContext::DSC_type_specifier, DSC == DeclSpecContext::DSC_template_param || DSC == DeclSpecContext::DSC_template_type_arg, - OffsetOfState, FoundUsing, &SkipBody); + OffsetOfState, &SkipBody); // If ActOnTag said the type was dependent, try again with the // less common call. @@ -2134,7 +2133,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, } else if (!TagOrTempResult.isInvalid()) { Result = DS.SetTypeSpecType( TagType, StartLoc, NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec, - DiagID, FoundUsing ? FoundUsing : TagOrTempResult.get(), Owned, Policy); + DiagID, TagOrTempResult.get(), Owned, Policy); } else { DS.SetTypeSpecError(); return; diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 392ed29467a9..66d937ac5742 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2629,12 +2629,6 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); - enum class Kind { MemberAccess, ArraySubscript }; - auto DiagExt = [&](SourceLocation Loc, Kind K) { - Diag(Loc, diag::ext_offsetof_member_designator) - << (K == Kind::ArraySubscript) << (OOK == Sema::OOK_Macro); - }; - // FIXME: This loop leaks the index expressions on error. while (true) { if (Tok.is(tok::period)) { @@ -2648,7 +2642,6 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } - DiagExt(Comps.back().LocStart, Kind::MemberAccess); Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); Comps.back().LocEnd = ConsumeToken(); } else if (Tok.is(tok::l_square)) { @@ -2666,7 +2659,6 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { SkipUntil(tok::r_paren, StopAtSemi); return Res; } - DiagExt(Comps.back().LocStart, Kind::ArraySubscript); Comps.back().U.E = Res.get(); ST.consumeClose(); diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 4d4b2482d046..a92bbde113fc 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -150,11 +150,19 @@ bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression, namespace { struct SatisfactionStackRAII { Sema &SemaRef; - SatisfactionStackRAII(Sema &SemaRef, llvm::FoldingSetNodeID FSNID) + bool Inserted = false; + SatisfactionStackRAII(Sema &SemaRef, const NamedDecl *ND, + llvm::FoldingSetNodeID FSNID) : SemaRef(SemaRef) { - SemaRef.PushSatisfactionStackEntry(FSNID); + if (ND) { + SemaRef.PushSatisfactionStackEntry(ND, FSNID); + Inserted = true; + } + } + ~SatisfactionStackRAII() { + if (Inserted) + SemaRef.PopSatisfactionStackEntry(); } - ~SatisfactionStackRAII() { SemaRef.PopSatisfactionStackEntry(); } }; } // namespace @@ -273,7 +281,8 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr, } static bool -DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, const Expr *E, +DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, + const NamedDecl *Templ, const Expr *E, const MultiLevelTemplateArgumentList &MLTAL) { E->Profile(ID, S.Context, /*Canonical=*/true); for (const auto &List : MLTAL) @@ -286,7 +295,7 @@ DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, const Expr *E, // expression, or when trying to determine the constexpr-ness of special // members. Otherwise we could just use the // Sema::InstantiatingTemplate::isAlreadyBeingInstantiated function. - if (S.SatisfactionStackContains(ID)) { + if (S.SatisfactionStackContains(Templ, ID)) { S.Diag(E->getExprLoc(), diag::err_constraint_depends_on_self) << const_cast<Expr *>(E) << E->getSourceRange(); return true; @@ -317,13 +326,14 @@ static ExprResult calculateConstraintSatisfaction( return ExprError(); llvm::FoldingSetNodeID ID; - if (DiagRecursiveConstraintEval(S, ID, AtomicExpr, MLTAL)) { + if (Template && + DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, MLTAL)) { Satisfaction.IsSatisfied = false; Satisfaction.ContainsErrors = true; return ExprEmpty(); } - SatisfactionStackRAII StackRAII(S, ID); + SatisfactionStackRAII StackRAII(S, Template, ID); // We do not want error diagnostics escaping here. Sema::SFINAETrap Trap(S); @@ -1132,8 +1142,7 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N, Sema::InstantiatingTemplate Inst( S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(), Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept, - SourceRange(ArgsAsWritten->arguments()[0].getSourceRange().getBegin(), - ArgsAsWritten->arguments().back().getSourceRange().getEnd())); + ArgsAsWritten->arguments().front().getSourceRange()); if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs)) return true; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e2b921bfe78f..051fad04219f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -13088,9 +13088,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // C++ [module.import/6] external definitions are not permitted in header // units. if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() && - VDecl->isThisDeclarationADefinition() && + !VDecl->isInvalidDecl() && VDecl->isThisDeclarationADefinition() && VDecl->getFormalLinkage() == Linkage::ExternalLinkage && - !VDecl->isInline()) { + !VDecl->isInline() && !VDecl->isTemplated() && + !isa<VarTemplateSpecializationDecl>(VDecl)) { Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit); VDecl->setInvalidDecl(); } @@ -15259,9 +15260,10 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, // FIXME: Consider an alternate location for the test where the inlined() // state is complete. if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() && + !FD->isInvalidDecl() && !FD->isInlined() && + BodyKind != FnBodyKind::Delete && BodyKind != FnBodyKind::Default && FD->getFormalLinkage() == Linkage::ExternalLinkage && - !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete && - BodyKind != FnBodyKind::Default && !FD->isInlined()) { + !FD->isTemplated() && !FD->isTemplateInstantiation()) { assert(FD->isThisDeclarationADefinition()); Diag(FD->getLocation(), diag::err_extern_def_in_header_unit); FD->setInvalidDecl(); @@ -16616,8 +16618,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, - OffsetOfKind OOK, UsingShadowDecl *&FoundUsingShadow, - SkipBodyInfo *SkipBody) { + OffsetOfKind OOK, SkipBodyInfo *SkipBody) { // If this is not a definition, it must have a name. IdentifierInfo *OrigName = Name; assert((Name != nullptr || TUK == TUK_Definition) && @@ -17052,7 +17053,6 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // redefinition if either context is within the other. if (auto *Shadow = dyn_cast<UsingShadowDecl>(DirectPrevDecl)) { auto *OldTag = dyn_cast<TagDecl>(PrevDecl); - FoundUsingShadow = Shadow; if (SS.isEmpty() && TUK != TUK_Reference && TUK != TUK_Friend && isDeclInScope(Shadow, SearchDC, S, isMemberSpecialization) && !(OldTag && isAcceptableTagRedeclContext( @@ -18871,10 +18871,24 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, ProcessDeclAttributeList(S, Record, Attrs); // Check to see if a FieldDecl is a pointer to a function. - auto IsFunctionPointer = [&](const Decl *D) { + auto IsFunctionPointerOrForwardDecl = [&](const Decl *D) { const FieldDecl *FD = dyn_cast<FieldDecl>(D); - if (!FD) + if (!FD) { + // Check whether this is a forward declaration that was inserted by + // Clang. This happens when a non-forward declared / defined type is + // used, e.g.: + // + // struct foo { + // struct bar *(*f)(); + // struct bar *(*g)(); + // }; + // + // "struct bar" shows up in the decl AST as a "RecordDecl" with an + // incomplete definition. + if (const auto *TD = dyn_cast<TagDecl>(D)) + return !TD->isCompleteDefinition(); return false; + } QualType FieldType = FD->getType().getDesugaredType(Context); if (isa<PointerType>(FieldType)) { QualType PointeeType = cast<PointerType>(FieldType)->getPointeeType(); @@ -18888,7 +18902,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, if (!getLangOpts().CPlusPlus && (Record->hasAttr<RandomizeLayoutAttr>() || (!Record->hasAttr<NoRandomizeLayoutAttr>() && - llvm::all_of(Record->decls(), IsFunctionPointer))) && + llvm::all_of(Record->decls(), IsFunctionPointerOrForwardDecl))) && !Record->isUnion() && !getLangOpts().RandstructSeed.empty() && !Record->isRandomized()) { SmallVector<Decl *, 32> NewDeclOrdering; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 348092fc62e8..df83442a8cd1 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -16977,7 +16977,6 @@ DeclResult Sema::ActOnTemplatedFriendTag( if (SS.isEmpty()) { bool Owned = false; bool IsDependent = false; - UsingShadowDecl* FoundUsing = nullptr; return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, Attr, AS_public, /*ModulePrivateLoc=*/SourceLocation(), @@ -16986,7 +16985,7 @@ DeclResult Sema::ActOnTemplatedFriendTag( /*ScopedEnumUsesClassTag=*/false, /*UnderlyingType=*/TypeResult(), /*IsTypeSpecifier=*/false, - /*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside, FoundUsing); + /*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside); } NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index e3eef9323b2f..abf5a72e7308 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1483,13 +1483,14 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, // Otherwise, if the type contains a placeholder type, it is replaced by the // type determined by placeholder type deduction. DeducedType *Deduced = Ty->getContainedDeducedType(); - if (Deduced && isa<DeducedTemplateSpecializationType>(Deduced)) { + if (Deduced && !Deduced->isDeduced() && + isa<DeducedTemplateSpecializationType>(Deduced)) { Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity, Kind, Exprs); if (Ty.isNull()) return ExprError(); Entity = InitializedEntity::InitializeTemporary(TInfo, Ty); - } else if (Deduced) { + } else if (Deduced && !Deduced->isDeduced()) { MultiExprArg Inits = Exprs; if (ListInitialization) { auto *ILE = cast<InitListExpr>(Exprs[0]); @@ -2016,7 +2017,8 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for. auto *Deduced = AllocType->getContainedDeducedType(); - if (Deduced && isa<DeducedTemplateSpecializationType>(Deduced)) { + if (Deduced && !Deduced->isDeduced() && + isa<DeducedTemplateSpecializationType>(Deduced)) { if (ArraySize) return ExprError( Diag(*ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(), @@ -2030,7 +2032,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, AllocTypeInfo, Entity, Kind, Exprs); if (AllocType.isNull()) return ExprError(); - } else if (Deduced) { + } else if (Deduced && !Deduced->isDeduced()) { MultiExprArg Inits = Exprs; bool Braced = (initStyle == CXXNewExpr::ListInit); if (Braced) { diff --git a/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/clang/lib/Sema/SemaRISCVVectorLookup.cpp index 7716dfb15458..fedc314f2965 100644 --- a/clang/lib/Sema/SemaRISCVVectorLookup.cpp +++ b/clang/lib/Sema/SemaRISCVVectorLookup.cpp @@ -192,7 +192,7 @@ void RISCVIntrinsicManagerImpl::InitIntrinsicList() { PolicyScheme MaskedPolicyScheme = static_cast<PolicyScheme>(Record.MaskedPolicyScheme); - const Policy DefaultPolicy(Record.HasTailPolicy, Record.HasMaskPolicy); + const Policy DefaultPolicy; llvm::SmallVector<PrototypeDescriptor> ProtoSeq = RVVIntrinsic::computeBuiltinTypes(BasicProtoSeq, /*IsMasked=*/false, @@ -208,8 +208,7 @@ void RISCVIntrinsicManagerImpl::InitIntrinsicList() { bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone; bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone; SmallVector<Policy> SupportedUnMaskedPolicies = - RVVIntrinsic::getSupportedUnMaskedPolicies(Record.HasTailPolicy, - Record.HasMaskPolicy); + RVVIntrinsic::getSupportedUnMaskedPolicies(); SmallVector<Policy> SupportedMaskedPolicies = RVVIntrinsic::getSupportedMaskedPolicies(Record.HasTailPolicy, Record.HasMaskPolicy); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 4b144c239fa4..b40bd0978a8a 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -10181,14 +10181,11 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, bool Owned = false; bool IsDependent = false; - UsingShadowDecl* FoundUsing = nullptr; - Decl *TagD = - ActOnTag(S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, NameLoc, Attr, - AS_none, /*ModulePrivateLoc=*/SourceLocation(), + Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, + NameLoc, Attr, AS_none, /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned, IsDependent, SourceLocation(), false, TypeResult(), /*IsTypeSpecifier*/ false, - /*IsTemplateParamOrArg*/ false, /*OOK=*/OOK_Outside, FoundUsing) - .get(); + /*IsTemplateParamOrArg*/ false, /*OOK=*/OOK_Outside).get(); assert(!IsDependent && "explicit instantiation of dependent name not yet handled"); if (!TagD) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 89d819a77dcb..8cb1ed28fe3e 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1588,9 +1588,6 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { // TypeQuals handled by caller. Result = Context.getTypeDeclType(D); - if (const auto *Using = - dyn_cast_or_null<UsingShadowDecl>(DS.getRepAsFoundDecl())) - Result = Context.getUsingType(Using, Result); // In both C and C++, make an ElaboratedType. ElaboratedTypeKeyword Keyword @@ -6256,9 +6253,6 @@ namespace { void VisitTagTypeLoc(TagTypeLoc TL) { TL.setNameLoc(DS.getTypeSpecTypeNameLoc()); } - void VisitUsingTypeLoc(UsingTypeLoc TL) { - TL.setNameLoc(DS.getTypeSpecTypeNameLoc()); - } void VisitAtomicTypeLoc(AtomicTypeLoc TL) { // An AtomicTypeLoc can come from either an _Atomic(...) type specifier // or an _Atomic qualifier. diff --git a/clang/lib/Support/RISCVVIntrinsicUtils.cpp b/clang/lib/Support/RISCVVIntrinsicUtils.cpp index 25084dd98e5c..86da7e86f831 100644 --- a/clang/lib/Support/RISCVVIntrinsicUtils.cpp +++ b/clang/lib/Support/RISCVVIntrinsicUtils.cpp @@ -966,40 +966,26 @@ llvm::SmallVector<PrototypeDescriptor> RVVIntrinsic::computeBuiltinTypes( return NewPrototype; } -llvm::SmallVector<Policy> -RVVIntrinsic::getSupportedUnMaskedPolicies(bool HasTailPolicy, - bool HasMaskPolicy) { - return { - Policy(Policy::PolicyType::Undisturbed, HasTailPolicy, - HasMaskPolicy), // TU - Policy(Policy::PolicyType::Agnostic, HasTailPolicy, HasMaskPolicy)}; // TA +llvm::SmallVector<Policy> RVVIntrinsic::getSupportedUnMaskedPolicies() { + return {Policy(Policy::PolicyType::Undisturbed)}; // TU } llvm::SmallVector<Policy> RVVIntrinsic::getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy) { if (HasTailPolicy && HasMaskPolicy) - return { - Policy(Policy::PolicyType::Undisturbed, Policy::PolicyType::Agnostic, - HasTailPolicy, HasMaskPolicy), // TUMA - Policy(Policy::PolicyType::Agnostic, Policy::PolicyType::Agnostic, - HasTailPolicy, HasMaskPolicy), // TAMA - Policy(Policy::PolicyType::Undisturbed, Policy::PolicyType::Undisturbed, - HasTailPolicy, HasMaskPolicy), // TUMU - Policy(Policy::PolicyType::Agnostic, Policy::PolicyType::Undisturbed, - HasTailPolicy, HasMaskPolicy)}; // TAMU + return {Policy(Policy::PolicyType::Undisturbed, + Policy::PolicyType::Agnostic), // TUM + Policy(Policy::PolicyType::Undisturbed, + Policy::PolicyType::Undisturbed), // TUMU + Policy(Policy::PolicyType::Agnostic, + Policy::PolicyType::Undisturbed)}; // MU if (HasTailPolicy && !HasMaskPolicy) return {Policy(Policy::PolicyType::Undisturbed, - Policy::PolicyType::Agnostic, HasTailPolicy, - HasMaskPolicy), // TUM - Policy(Policy::PolicyType::Agnostic, Policy::PolicyType::Agnostic, - HasTailPolicy, HasMaskPolicy)}; // TAM + Policy::PolicyType::Agnostic)}; // TU if (!HasTailPolicy && HasMaskPolicy) - return {Policy(Policy::PolicyType::Agnostic, Policy::PolicyType::Agnostic, - HasTailPolicy, HasMaskPolicy), // MA - Policy(Policy::PolicyType::Agnostic, - Policy::PolicyType::Undisturbed, HasTailPolicy, - HasMaskPolicy)}; // MU + return {Policy(Policy::PolicyType::Agnostic, + Policy::PolicyType::Undisturbed)}; // MU llvm_unreachable("An RVV instruction should not be without both tail policy " "and mask policy"); } @@ -1016,46 +1002,34 @@ void RVVIntrinsic::updateNamesAndPolicy(bool IsMasked, bool HasPolicy, OverloadedName += suffix; }; - if (PolicyAttrs.isUnspecified()) { - PolicyAttrs.IsUnspecified = false; - if (IsMasked) { + // This follows the naming guideline under riscv-c-api-doc to add the + // `__riscv_` suffix for all RVV intrinsics. + Name = "__riscv_" + Name; + OverloadedName = "__riscv_" + OverloadedName; + + if (IsMasked) { + if (PolicyAttrs.isTUMUPolicy()) + appendPolicySuffix("_tumu"); + else if (PolicyAttrs.isTUMAPolicy()) + appendPolicySuffix("_tum"); + else if (PolicyAttrs.isTAMUPolicy()) + appendPolicySuffix("_mu"); + else if (PolicyAttrs.isTAMAPolicy()) { Name += "_m"; if (HasPolicy) BuiltinName += "_tama"; else BuiltinName += "_m"; - } else { + } else + llvm_unreachable("Unhandled policy condition"); + } else { + if (PolicyAttrs.isTUPolicy()) + appendPolicySuffix("_tu"); + else if (PolicyAttrs.isTAPolicy()) { if (HasPolicy) BuiltinName += "_ta"; - } - } else { - if (IsMasked) { - if (PolicyAttrs.isTUMAPolicy() && !PolicyAttrs.hasMaskPolicy()) - appendPolicySuffix("_tum"); - else if (PolicyAttrs.isTAMAPolicy() && !PolicyAttrs.hasMaskPolicy()) - appendPolicySuffix("_tam"); - else if (PolicyAttrs.isMUPolicy() && !PolicyAttrs.hasTailPolicy()) - appendPolicySuffix("_mu"); - else if (PolicyAttrs.isMAPolicy() && !PolicyAttrs.hasTailPolicy()) - appendPolicySuffix("_ma"); - else if (PolicyAttrs.isTUMUPolicy()) - appendPolicySuffix("_tumu"); - else if (PolicyAttrs.isTAMUPolicy()) - appendPolicySuffix("_tamu"); - else if (PolicyAttrs.isTUMAPolicy()) - appendPolicySuffix("_tuma"); - else if (PolicyAttrs.isTAMAPolicy()) - appendPolicySuffix("_tama"); - else - llvm_unreachable("Unhandled policy condition"); - } else { - if (PolicyAttrs.isTUPolicy()) - appendPolicySuffix("_tu"); - else if (PolicyAttrs.isTAPolicy()) - appendPolicySuffix("_ta"); - else - llvm_unreachable("Unhandled policy condition"); - } + } else + llvm_unreachable("Unhandled policy condition"); } } diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index 668e1072c065..6926bbdf8d0f 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -521,10 +521,9 @@ void RVVEmitter::createRVVIntrinsics( StringRef MaskedIRName = R->getValueAsString("MaskedIRName"); unsigned NF = R->getValueAsInt("NF"); - const Policy DefaultPolicy(HasTailPolicy, HasMaskPolicy); + const Policy DefaultPolicy; SmallVector<Policy> SupportedUnMaskedPolicies = - RVVIntrinsic::getSupportedUnMaskedPolicies(HasTailPolicy, - HasMaskPolicy); + RVVIntrinsic::getSupportedUnMaskedPolicies(); SmallVector<Policy> SupportedMaskedPolicies = RVVIntrinsic::getSupportedMaskedPolicies(HasTailPolicy, HasMaskPolicy); diff --git a/libcxx/include/__config b/libcxx/include/__config index b9203e640a3e..51b100fa5569 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -134,6 +134,15 @@ # define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON // According to the Standard, `bitset::operator[] const` returns bool # define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL +// Fix the implementation of CityHash used for std::hash<fundamental-type>. +// This is an ABI break because `std::hash` will return a different result, +// which means that hashing the same object in translation units built against +// different versions of libc++ can return inconsistent results. This is especially +// tricky since std::hash is used in the implementation of unordered containers. +// +// The incorrect implementation of CityHash has the problem that it drops some +// bits on the floor. +# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION // Remove the base 10 implementation of std::to_chars from the dylib. // The implementation moved to the header, but we still export the symbols from // the dylib for backwards compatibility. @@ -629,7 +638,11 @@ typedef __char32_t char32_t; # else # define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION # endif -# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION +# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION + +// This macro provides a HIDE_FROM_ABI equivalent that can be applied to extern +// "C" function, as those lack mangling. +# define _LIBCPP_HIDE_FROM_ABI_C _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION # ifdef _LIBCPP_BUILDING_LIBRARY # if _LIBCPP_ABI_VERSION > 1 @@ -1223,12 +1236,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD // functions are declared by the C library. # define _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8 // GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if -// __cpp_char8_t is defined or if C2X extensions are enabled. Unfortunately, -// determining the latter depends on internal GNU libc details. If the -// __cpp_char8_t feature test macro is not defined, then a char8_t typedef -// will be declared as well. -# if defined(_LIBCPP_GLIBC_PREREQ) && defined(__GLIBC_USE) -# if _LIBCPP_GLIBC_PREREQ(2, 36) && (defined(__cpp_char8_t) || __GLIBC_USE(ISOC2X)) +// __cpp_char8_t is defined or if C2X extensions are enabled. Determining +// the latter depends on internal GNU libc details that are not appropriate +// to depend on here, so any declarations present when __cpp_char8_t is not +// defined are ignored. +# if defined(_LIBCPP_GLIBC_PREREQ) +# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t) # undef _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8 # endif # endif diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h index 185148ccba53..0f0001272d40 100644 --- a/libcxx/include/__format/format_functions.h +++ b/libcxx/include/__format/format_functions.h @@ -258,10 +258,12 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end, if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) { __arg_t __type = __ctx.arg(__r.__value); - if (__type == __arg_t::__handle) + if (__type == __arg_t::__none) + std::__throw_format_error("Argument index out of bounds"); + else if (__type == __arg_t::__handle) __ctx.__handle(__r.__value).__parse(__parse_ctx); - else - __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type); + else if (__parse) + __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type); } else _VSTD::__visit_format_arg( [&](auto __arg) { diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h index dfd8ea2553dc..39382aa9bff4 100644 --- a/libcxx/include/__functional/hash.h +++ b/libcxx/include/__functional/hash.h @@ -140,7 +140,11 @@ struct __murmur2_or_cityhash<_Size, 64> if (__len >= 4) { const uint32_t __a = std::__loadword<uint32_t>(__s); const uint32_t __b = std::__loadword<uint32_t>(__s + __len - 4); +#ifdef _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION return __hash_len_16(__len + (static_cast<_Size>(__a) << 3), __b); +#else + return __hash_len_16(__len + (__a << 3), __b); +#endif } if (__len > 0) { const unsigned char __a = static_cast<unsigned char>(__s[0]); diff --git a/libcxx/include/__ranges/join_view.h b/libcxx/include/__ranges/join_view.h index 869540fc99c2..9d56e13b8439 100644 --- a/libcxx/include/__ranges/join_view.h +++ b/libcxx/include/__ranges/join_view.h @@ -40,7 +40,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if _LIBCPP_STD_VER > 17 +// Note: `join_view` is still marked experimental because there is an ABI-breaking change that affects `join_view` in +// the pipeline (https://isocpp.org/files/papers/D2770R0.html). +// TODO: make `join_view` non-experimental once D2770 is implemented. +#if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) namespace ranges { template<class> @@ -445,7 +448,7 @@ struct __segmented_iterator_traits<ranges::__join_view_iterator<_View, _Const>> } }; -#endif // _LIBCPP_STD_VER > 17 +#endif // #if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 1f1d67dbb7fc..8898e88156ef 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -755,13 +755,19 @@ module std [system] { module derived_from { private header "__concepts/derived_from.h" } module destructible { private header "__concepts/destructible.h" } module different_from { private header "__concepts/different_from.h" } - module equality_comparable { private header "__concepts/equality_comparable.h" } + module equality_comparable { + private header "__concepts/equality_comparable.h" + export type_traits.common_reference + } module invocable { private header "__concepts/invocable.h" } module movable { private header "__concepts/movable.h" } module predicate { private header "__concepts/predicate.h" } module regular { private header "__concepts/regular.h" } module relation { private header "__concepts/relation.h" } - module same_as { private header "__concepts/same_as.h" } + module same_as { + private header "__concepts/same_as.h" + export type_traits.is_same + } module semiregular { private header "__concepts/semiregular.h" } module swappable { private header "__concepts/swappable.h" } module totally_ordered { private header "__concepts/totally_ordered.h" } @@ -979,7 +985,11 @@ module std [system] { module back_insert_iterator { private header "__iterator/back_insert_iterator.h" } module bounded_iter { private header "__iterator/bounded_iter.h" } module common_iterator { private header "__iterator/common_iterator.h" } - module concepts { private header "__iterator/concepts.h" } + module concepts { + private header "__iterator/concepts.h" + export concepts.equality_comparable + export type_traits.common_reference + } module counted_iterator { private header "__iterator/counted_iterator.h" } module data { private header "__iterator/data.h" } module default_sentinel { private header "__iterator/default_sentinel.h" } diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 1368d9053125..aeba918292a7 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1079,7 +1079,15 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset, return; } - bool canWrite = (sec->flags & SHF_WRITE) || !config->zText; + // Use a simple -z notext rule that treats all sections except .eh_frame as + // writable. GNU ld does not produce dynamic relocations in .eh_frame (and our + // SectionBase::getOffset would incorrectly adjust the offset). + // + // For MIPS, we don't implement GNU ld's DW_EH_PE_absptr to DW_EH_PE_pcrel + // conversion. We still emit a dynamic relocation. + bool canWrite = (sec->flags & SHF_WRITE) || + !(config->zText || + (isa<EhInputSection>(sec) && config->emachine != EM_MIPS)); if (canWrite) { RelType rel = target->getDynRel(type); if (expr == R_GOT || (rel == target->symbolicRel && !sym.isPreemptible)) { diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index 00aaeff96d78..a450923cded9 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -26,6 +26,10 @@ Non-comprehensive list of changes in this release ELF Improvements ---------------- +* Link speed improved greatly compared with lld 15.0. Notably input section + initialization and relocation scanning are now parallel. + (`D130810 <https://reviews.llvm.org/D130810>`_) + (`D133003 <https://reviews.llvm.org/D133003>`_) * ``ELFCOMPRESS_ZSTD`` compressed input sections are now supported. (`D129406 <https://reviews.llvm.org/D129406>`_) * ``--compress-debug-sections=zstd`` is now available to compress debug @@ -36,12 +40,25 @@ ELF Improvements * ``DT_RISCV_VARIANT_CC`` is now produced if at least one ``R_RISCV_JUMP_SLOT`` relocation references a symbol with the ``STO_RISCV_VARIANT_CC`` bit. (`D107951 <https://reviews.llvm.org/D107951>`_) +* ``DT_STATIC_TLS`` is now set for AArch64/PPC32/PPC64 initial-exec TLS models + when producing a shared object. * ``--no-undefined-version`` is now the default; symbols named in version scripts that have no matching symbol in the output will be reported. Use ``--undefined-version`` to revert to the old behavior. + (`D135402 <https://reviews.llvm.org/D135402>`_) +* ``-V`` is now an alias for ``-v`` to support ``gcc -fuse-ld=lld -v`` on many targets. +* ``-r`` no longer defines ``__global_pointer$`` or ``_TLS_MODULE_BASE_``. +* A corner case of mixed GCC and Clang object files (``STB_WEAK`` and + ``STB_GNU_UNIQUE`` in different COMDATs) is now supported. + (`D136381 <https://reviews.llvm.org/D136381>`_) * The output ``SHT_RISCV_ATTRIBUTES`` section now merges all input components instead of picking the first input component. (`D138550 <https://reviews.llvm.org/D138550>`_) +* For x86-32, ``-fno-plt`` GD/LD TLS models ``call *___tls_get_addr@GOT(%reg)`` + are now supported. Previous output might have runtime crash. +* Armv4(T) thunks are now supported. + (`D139888 <https://reviews.llvm.org/D139888>`_) + (`D141272 <https://reviews.llvm.org/D141272>`_) Breaking changes ---------------- diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp index b8db7f2f3788..0349f13945e3 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp @@ -130,7 +130,7 @@ NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo *reg_info, return error; } - RegSetKind set = opt_set.getValue(); + RegSetKind set = *opt_set; error = ReadRegisterSet(set); if (error.Fail()) return error; @@ -164,7 +164,7 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegister( return error; } - RegSetKind set = opt_set.getValue(); + RegSetKind set = *opt_set; error = ReadRegisterSet(set); if (error.Fail()) return error; diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp index 7ad9e3c209df..bdb57251f706 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp @@ -181,7 +181,7 @@ NativeRegisterContextFreeBSD_powerpc::ReadRegister(const RegisterInfo *reg_info, return error; } - RegSetKind set = opt_set.getValue(); + RegSetKind set = *opt_set; error = ReadRegisterSet(set); if (error.Fail()) return error; @@ -215,7 +215,7 @@ Status NativeRegisterContextFreeBSD_powerpc::WriteRegister( return error; } - RegSetKind set = opt_set.getValue(); + RegSetKind set = *opt_set; error = ReadRegisterSet(set); if (error.Fail()) return error; diff --git a/llvm/include/llvm/Debuginfod/Debuginfod.h b/llvm/include/llvm/Debuginfod/Debuginfod.h index caece0e6fc19..ec7f5691dda4 100644 --- a/llvm/include/llvm/Debuginfod/Debuginfod.h +++ b/llvm/include/llvm/Debuginfod/Debuginfod.h @@ -38,9 +38,13 @@ namespace llvm { +/// Returns false if a debuginfod lookup can be determined to have no chance of +/// succeeding. +bool canUseDebuginfod(); + /// Finds default array of Debuginfod server URLs by checking DEBUGINFOD_URLS /// environment variable. -Expected<SmallVector<StringRef>> getDefaultDebuginfodUrls(); +SmallVector<StringRef> getDefaultDebuginfodUrls(); /// Finds a default local file caching directory for the debuginfod client, /// first checking DEBUGINFOD_CACHE_PATH. diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index b1f85563195f..92a198befbe4 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -1391,6 +1391,16 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.". let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.". +class AdvSIMD_SVE_2SVBoolArg_Intrinsic + : DefaultAttrsIntrinsic<[llvm_nxv16i1_ty], + [llvm_nxv16i1_ty], + [IntrNoMem]>; + +class AdvSIMD_SVE_3SVBoolArg_Intrinsic + : DefaultAttrsIntrinsic<[llvm_nxv16i1_ty], + [llvm_nxv16i1_ty, llvm_nxv16i1_ty], + [IntrNoMem]>; + class AdvSIMD_SVE_Reduce_Intrinsic : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, @@ -1836,22 +1846,43 @@ def int_aarch64_sve_sel : AdvSIMD_Pred2VectorArg_Intrinsic; def int_aarch64_sve_lasta : AdvSIMD_SVE_Reduce_Intrinsic; def int_aarch64_sve_lastb : AdvSIMD_SVE_Reduce_Intrinsic; def int_aarch64_sve_rev : AdvSIMD_1VectorArg_Intrinsic; +def int_aarch64_sve_rev_b16 : AdvSIMD_SVE_2SVBoolArg_Intrinsic; +def int_aarch64_sve_rev_b32 : AdvSIMD_SVE_2SVBoolArg_Intrinsic; +def int_aarch64_sve_rev_b64 : AdvSIMD_SVE_2SVBoolArg_Intrinsic; def int_aarch64_sve_splice : AdvSIMD_Pred2VectorArg_Intrinsic; def int_aarch64_sve_sunpkhi : AdvSIMD_SVE_Unpack_Intrinsic; def int_aarch64_sve_sunpklo : AdvSIMD_SVE_Unpack_Intrinsic; def int_aarch64_sve_tbl : AdvSIMD_SVE_TBL_Intrinsic; def int_aarch64_sve_trn1 : AdvSIMD_2VectorArg_Intrinsic; +def int_aarch64_sve_trn1_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_trn1_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_trn1_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; def int_aarch64_sve_trn2 : AdvSIMD_2VectorArg_Intrinsic; +def int_aarch64_sve_trn2_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_trn2_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_trn2_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; def int_aarch64_sve_trn1q : AdvSIMD_2VectorArg_Intrinsic; def int_aarch64_sve_trn2q : AdvSIMD_2VectorArg_Intrinsic; def int_aarch64_sve_uunpkhi : AdvSIMD_SVE_Unpack_Intrinsic; def int_aarch64_sve_uunpklo : AdvSIMD_SVE_Unpack_Intrinsic; def int_aarch64_sve_uzp1 : AdvSIMD_2VectorArg_Intrinsic; +def int_aarch64_sve_uzp1_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_uzp1_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_uzp1_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; def int_aarch64_sve_uzp2 : AdvSIMD_2VectorArg_Intrinsic; +def int_aarch64_sve_uzp2_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_uzp2_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_uzp2_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; def int_aarch64_sve_uzp1q : AdvSIMD_2VectorArg_Intrinsic; def int_aarch64_sve_uzp2q : AdvSIMD_2VectorArg_Intrinsic; def int_aarch64_sve_zip1 : AdvSIMD_2VectorArg_Intrinsic; +def int_aarch64_sve_zip1_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_zip1_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_zip1_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; def int_aarch64_sve_zip2 : AdvSIMD_2VectorArg_Intrinsic; +def int_aarch64_sve_zip2_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_zip2_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; +def int_aarch64_sve_zip2_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic; def int_aarch64_sve_zip1q : AdvSIMD_2VectorArg_Intrinsic; def int_aarch64_sve_zip2q : AdvSIMD_2VectorArg_Intrinsic; diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 4d48308d5509..bdb772862468 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -21,6 +21,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Object/BuildID.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Alignment.h" #include "llvm/Support/Compiler.h" @@ -42,6 +43,10 @@ namespace llvm { class IndexedInstrProfReader; +namespace object { +class BuildIDFetcher; +} // namespace object + namespace coverage { class CoverageMappingReader; @@ -579,6 +584,13 @@ class CoverageMapping { ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders, IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage); + // Load coverage records from file. + static Error + loadFromFile(StringRef Filename, StringRef Arch, StringRef CompilationDir, + IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage, + bool &DataFound, + SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr); + /// Add a function record corresponding to \p Record. Error loadFunctionRecord(const CoverageMappingRecord &Record, IndexedInstrProfReader &ProfileReader); @@ -604,8 +616,8 @@ public: /// Ignores non-instrumented object files unless all are not instrumented. static Expected<std::unique_ptr<CoverageMapping>> load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename, - ArrayRef<StringRef> Arches = std::nullopt, - StringRef CompilationDir = ""); + ArrayRef<StringRef> Arches = std::nullopt, StringRef CompilationDir = "", + const object::BuildIDFetcher *BIDFetcher = nullptr); /// The number of functions that couldn't have their profiles mapped. /// diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h index 39c0045369be..326c1b0d3338 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h @@ -205,7 +205,8 @@ public: static Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>> create(MemoryBufferRef ObjectBuffer, StringRef Arch, SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers, - StringRef CompilationDir = ""); + StringRef CompilationDir = "", + SmallVectorImpl<object::BuildIDRef> *BinaryIDs = nullptr); static Expected<std::unique_ptr<BinaryCoverageReader>> createCoverageReaderFromBuffer(StringRef Coverage, diff --git a/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h b/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h index bf08336663b6..73aee47bfef5 100644 --- a/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h +++ b/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h @@ -37,13 +37,25 @@ KernelSet getDeviceKernels(Module &M); /// OpenMP optimizations pass. class OpenMPOptPass : public PassInfoMixin<OpenMPOptPass> { public: + OpenMPOptPass() : LTOPhase(ThinOrFullLTOPhase::None) {} + OpenMPOptPass(ThinOrFullLTOPhase LTOPhase) : LTOPhase(LTOPhase) {} + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); + +private: + const ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None; }; class OpenMPOptCGSCCPass : public PassInfoMixin<OpenMPOptCGSCCPass> { public: + OpenMPOptCGSCCPass() : LTOPhase(ThinOrFullLTOPhase::None) {} + OpenMPOptCGSCCPass(ThinOrFullLTOPhase LTOPhase) : LTOPhase(LTOPhase) {} + PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR); + +private: + const ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None; }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 8c126d20fc9a..0b1e32c87fc3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2235,6 +2235,8 @@ bool AsmPrinter::doFinalization(Module &M) { SmallVector<const GlobalAlias *, 16> AliasStack; SmallPtrSet<const GlobalAlias *, 16> AliasVisited; for (const auto &Alias : M.aliases()) { + if (Alias.hasAvailableExternallyLinkage()) + continue; for (const GlobalAlias *Cur = &Alias; Cur; Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) { if (!AliasVisited.insert(Cur).second) diff --git a/llvm/lib/CodeGen/IfConversion.cpp b/llvm/lib/CodeGen/IfConversion.cpp index 105ab908d3fa..936de316e575 100644 --- a/llvm/lib/CodeGen/IfConversion.cpp +++ b/llvm/lib/CodeGen/IfConversion.cpp @@ -2244,6 +2244,15 @@ void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges) { assert(!FromMBB.hasAddressTaken() && "Removing a BB whose address is taken!"); + // If we're about to splice an INLINEASM_BR from FromBBI, we need to update + // ToBBI's successor list accordingly. + if (FromMBB.mayHaveInlineAsmBr()) + for (MachineInstr &MI : FromMBB) + if (MI.getOpcode() == TargetOpcode::INLINEASM_BR) + for (MachineOperand &MO : MI.operands()) + if (MO.isMBB() && !ToBBI.BB->isSuccessor(MO.getMBB())) + ToBBI.BB->addSuccessor(MO.getMBB(), BranchProbability::getZero()); + // In case FromMBB contains terminators (e.g. return instruction), // first move the non-terminator instructions, then the terminators. MachineBasicBlock::iterator FromTI = FromMBB.getFirstTerminator(); diff --git a/llvm/lib/Debuginfod/Debuginfod.cpp b/llvm/lib/Debuginfod/Debuginfod.cpp index 026f118bbf5b..2b0710b536ba 100644 --- a/llvm/lib/Debuginfod/Debuginfod.cpp +++ b/llvm/lib/Debuginfod/Debuginfod.cpp @@ -55,7 +55,11 @@ static std::string buildIDToString(BuildIDRef ID) { return llvm::toHex(ID, /*LowerCase=*/true); } -Expected<SmallVector<StringRef>> getDefaultDebuginfodUrls() { +bool canUseDebuginfod() { + return HTTPClient::isAvailable() && !getDefaultDebuginfodUrls().empty(); +} + +SmallVector<StringRef> getDefaultDebuginfodUrls() { const char *DebuginfodUrlsEnv = std::getenv("DEBUGINFOD_URLS"); if (DebuginfodUrlsEnv == nullptr) return SmallVector<StringRef>(); @@ -126,13 +130,8 @@ Expected<std::string> getCachedOrDownloadArtifact(StringRef UniqueKey, return CacheDirOrErr.takeError(); CacheDir = *CacheDirOrErr; - Expected<SmallVector<StringRef>> DebuginfodUrlsOrErr = - getDefaultDebuginfodUrls(); - if (!DebuginfodUrlsOrErr) - return DebuginfodUrlsOrErr.takeError(); - SmallVector<StringRef> &DebuginfodUrls = *DebuginfodUrlsOrErr; return getCachedOrDownloadArtifact(UniqueKey, UrlPath, CacheDir, - DebuginfodUrls, + getDefaultDebuginfodUrls(), getDefaultDebuginfodTimeout()); } @@ -159,7 +158,8 @@ public: Error StreamedHTTPResponseHandler::handleBodyChunk(StringRef BodyChunk) { if (!FileStream) { - if (Client.responseCode() != 200) + unsigned Code = Client.responseCode(); + if (Code && Code != 200) return Error::success(); Expected<std::unique_ptr<CachedFileStream>> FileStreamOrError = CreateStream(); @@ -259,7 +259,8 @@ Expected<std::string> getCachedOrDownloadArtifact( if (Err) return std::move(Err); - if (Client.responseCode() != 200) + unsigned Code = Client.responseCode(); + if (Code && Code != 200) continue; // Return the path to the artifact on disk. diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp index 95380d912392..3368d3276cb3 100644 --- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp @@ -125,6 +125,10 @@ void IRMaterializationUnit::discard(const JITDylib &JD, assert(!I->second->isDeclaration() && "Discard should only apply to definitions"); I->second->setLinkage(GlobalValue::AvailableExternallyLinkage); + // According to the IR verifier, "Declaration[s] may not be in a Comdat!" + // Remove it, if this is a GlobalObject. + if (auto *GO = dyn_cast<GlobalObject>(I->second)) + GO->setComdat(nullptr); SymbolToDefinition.erase(I); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 83e42bc184ff..2d62d31cf6b4 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -730,9 +730,6 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { GV.getName() == "llvm.global_dtors")) { Check(!GV.hasInitializer() || GV.hasAppendingLinkage(), "invalid linkage for intrinsic global variable", &GV); - Check(GV.materialized_use_empty(), - "invalid uses of intrinsic global variable", &GV); - // Don't worry about emitting an error for it not being an array, // visitGlobalValue will complain on appending non-array. if (ArrayType *ATy = dyn_cast<ArrayType>(GV.getValueType())) { @@ -759,9 +756,6 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { GV.getName() == "llvm.compiler.used")) { Check(!GV.hasInitializer() || GV.hasAppendingLinkage(), "invalid linkage for intrinsic global variable", &GV); - Check(GV.materialized_use_empty(), - "invalid uses of intrinsic global variable", &GV); - Type *GVType = GV.getValueType(); if (ArrayType *ATy = dyn_cast<ArrayType>(GVType)) { PointerType *PTy = dyn_cast<PointerType>(ATy->getElementType()); diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index 0762c535f7f5..eed29c25714b 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -1604,7 +1604,7 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, } // Try to run OpenMP optimizations, quick no-op if no OpenMP metadata present. - MPM.addPass(OpenMPOptPass()); + MPM.addPass(OpenMPOptPass(ThinOrFullLTOPhase::FullLTOPostLink)); // Remove unused virtual tables to improve the quality of code generated by // whole-program devirtualization and bitset lowering. @@ -1712,6 +1712,9 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, // Optimize globals again after we ran the inliner. MPM.addPass(GlobalOptPass()); + // Run the OpenMPOpt pass again after global optimizations. + MPM.addPass(OpenMPOptPass(ThinOrFullLTOPhase::FullLTOPostLink)); + // Garbage collect dead functions. MPM.addPass(GlobalDCEPass()); @@ -1808,7 +1811,8 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, addVectorPasses(Level, MainFPM, /* IsFullLTO */ true); // Run the OpenMPOpt CGSCC pass again late. - MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(OpenMPOptCGSCCPass())); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor( + OpenMPOptCGSCCPass(ThinOrFullLTOPhase::FullLTOPostLink))); invokePeepholeEPCallbacks(MainFPM, Level); MainFPM.addPass(JumpThreadingPass()); diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index ad44d86ea1a7..10af4160c545 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -44,6 +44,7 @@ MODULE_PASS("always-inline", AlwaysInlinerPass()) MODULE_PASS("attributor", AttributorPass()) MODULE_PASS("annotation2metadata", Annotation2MetadataPass()) MODULE_PASS("openmp-opt", OpenMPOptPass()) +MODULE_PASS("openmp-opt-postlink", OpenMPOptPass(ThinOrFullLTOPhase::FullLTOPostLink)) MODULE_PASS("called-value-propagation", CalledValuePropagationPass()) MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass()) MODULE_PASS("cg-profile", CGProfilePass()) diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 6113f78aeb4e..ce71eebd4fd3 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Object/BuildID.h" #include "llvm/ProfileData/Coverage/CoverageMappingReader.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/Debug.h" @@ -342,10 +343,49 @@ static Error handleMaybeNoDataFoundError(Error E) { }); } +Error CoverageMapping::loadFromFile( + StringRef Filename, StringRef Arch, StringRef CompilationDir, + IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage, + bool &DataFound, SmallVectorImpl<object::BuildID> *FoundBinaryIDs) { + auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN( + Filename, /*IsText=*/false, /*RequiresNullTerminator=*/false); + if (std::error_code EC = CovMappingBufOrErr.getError()) + return createFileError(Filename, errorCodeToError(EC)); + MemoryBufferRef CovMappingBufRef = + CovMappingBufOrErr.get()->getMemBufferRef(); + SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers; + + SmallVector<object::BuildIDRef> BinaryIDs; + auto CoverageReadersOrErr = BinaryCoverageReader::create( + CovMappingBufRef, Arch, Buffers, CompilationDir, + FoundBinaryIDs ? &BinaryIDs : nullptr); + if (Error E = CoverageReadersOrErr.takeError()) { + E = handleMaybeNoDataFoundError(std::move(E)); + if (E) + return createFileError(Filename, std::move(E)); + return E; + } + + SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers; + for (auto &Reader : CoverageReadersOrErr.get()) + Readers.push_back(std::move(Reader)); + if (FoundBinaryIDs && !Readers.empty()) { + llvm::append_range(*FoundBinaryIDs, + llvm::map_range(BinaryIDs, [](object::BuildIDRef BID) { + return object::BuildID(BID); + })); + } + DataFound |= !Readers.empty(); + if (Error E = loadFromReaders(Readers, ProfileReader, Coverage)) + return createFileError(Filename, std::move(E)); + return Error::success(); +} + Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename, ArrayRef<StringRef> Arches, - StringRef CompilationDir) { + StringRef CompilationDir, + const object::BuildIDFetcher *BIDFetcher) { auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename); if (Error E = ProfileReaderOrErr.takeError()) return createFileError(ProfileFilename, std::move(E)); @@ -353,35 +393,53 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames, auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping()); bool DataFound = false; + auto GetArch = [&](size_t Idx) { + if (Arches.empty()) + return StringRef(); + if (Arches.size() == 1) + return Arches.front(); + return Arches[Idx]; + }; + + SmallVector<object::BuildID> FoundBinaryIDs; for (const auto &File : llvm::enumerate(ObjectFilenames)) { - auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN( - File.value(), /*IsText=*/false, /*RequiresNullTerminator=*/false); - if (std::error_code EC = CovMappingBufOrErr.getError()) - return createFileError(File.value(), errorCodeToError(EC)); - StringRef Arch = Arches.empty() ? StringRef() : Arches[File.index()]; - MemoryBufferRef CovMappingBufRef = - CovMappingBufOrErr.get()->getMemBufferRef(); - SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers; - auto CoverageReadersOrErr = BinaryCoverageReader::create( - CovMappingBufRef, Arch, Buffers, CompilationDir); - if (Error E = CoverageReadersOrErr.takeError()) { - E = handleMaybeNoDataFoundError(std::move(E)); - if (E) - return createFileError(File.value(), std::move(E)); - // E == success (originally a no_data_found error). - continue; + if (Error E = + loadFromFile(File.value(), GetArch(File.index()), CompilationDir, + *ProfileReader, *Coverage, DataFound, &FoundBinaryIDs)) + return std::move(E); + } + + if (BIDFetcher) { + std::vector<object::BuildID> ProfileBinaryIDs; + if (Error E = ProfileReader->readBinaryIds(ProfileBinaryIDs)) + return createFileError(ProfileFilename, std::move(E)); + + SmallVector<object::BuildIDRef> BinaryIDsToFetch; + if (!ProfileBinaryIDs.empty()) { + const auto &Compare = [](object::BuildIDRef A, object::BuildIDRef B) { + return std::lexicographical_compare(A.begin(), A.end(), B.begin(), + B.end()); + }; + llvm::sort(FoundBinaryIDs, Compare); + std::set_difference( + ProfileBinaryIDs.begin(), ProfileBinaryIDs.end(), + FoundBinaryIDs.begin(), FoundBinaryIDs.end(), + std::inserter(BinaryIDsToFetch, BinaryIDsToFetch.end()), Compare); } - SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers; - for (auto &Reader : CoverageReadersOrErr.get()) - Readers.push_back(std::move(Reader)); - DataFound |= !Readers.empty(); - if (Error E = loadFromReaders(Readers, *ProfileReader, *Coverage)) - return createFileError(File.value(), std::move(E)); + for (object::BuildIDRef BinaryID : BinaryIDsToFetch) { + std::optional<std::string> PathOpt = BIDFetcher->fetch(BinaryID); + if (!PathOpt) + continue; + std::string Path = std::move(*PathOpt); + StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef(); + if (Error E = loadFromFile(Path, Arch, CompilationDir, *ProfileReader, + *Coverage, DataFound)) + return std::move(E); + } } - // If no readers were created, either no objects were provided or none of them - // had coverage data. Return an error in the latter case. - if (!DataFound && !ObjectFilenames.empty()) + + if (!DataFound) return createFileError( join(ObjectFilenames.begin(), ObjectFilenames.end(), ", "), make_error<CoverageMapError>(coveragemap_error::no_data_found)); diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp index 41962ab24ff9..d313864e2ddb 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -954,7 +954,8 @@ static Expected<std::vector<SectionRef>> lookupSections(ObjectFile &OF, static Expected<std::unique_ptr<BinaryCoverageReader>> loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch, - StringRef CompilationDir = "") { + StringRef CompilationDir = "", + std::optional<object::BuildIDRef> *BinaryID = nullptr) { std::unique_ptr<ObjectFile> OF; if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) { // If we have a universal binary, try to look up the object for the @@ -1052,6 +1053,9 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch, FuncRecords = std::move(WritableBuffer); } + if (BinaryID) + *BinaryID = getBuildID(OF.get()); + return BinaryCoverageReader::createCoverageReaderFromBuffer( CoverageMapping, std::move(FuncRecords), std::move(ProfileNames), BytesInAddress, Endian, CompilationDir); @@ -1074,7 +1078,7 @@ Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>> BinaryCoverageReader::create( MemoryBufferRef ObjectBuffer, StringRef Arch, SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers, - StringRef CompilationDir) { + StringRef CompilationDir, SmallVectorImpl<object::BuildIDRef> *BinaryIDs) { std::vector<std::unique_ptr<BinaryCoverageReader>> Readers; if (ObjectBuffer.getBuffer().startswith(TestingFormatMagic)) { @@ -1114,7 +1118,7 @@ BinaryCoverageReader::create( return BinaryCoverageReader::create( ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers, - CompilationDir); + CompilationDir, BinaryIDs); } } @@ -1127,7 +1131,8 @@ BinaryCoverageReader::create( return ChildBufOrErr.takeError(); auto ChildReadersOrErr = BinaryCoverageReader::create( - ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir); + ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir, + BinaryIDs); if (!ChildReadersOrErr) return ChildReadersOrErr.takeError(); for (auto &Reader : ChildReadersOrErr.get()) @@ -1146,10 +1151,14 @@ BinaryCoverageReader::create( return std::move(Readers); } - auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir); + std::optional<object::BuildIDRef> BinaryID; + auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir, + BinaryIDs ? &BinaryID : nullptr); if (!ReaderOrErr) return ReaderOrErr.takeError(); Readers.push_back(std::move(ReaderOrErr.get())); + if (BinaryID) + BinaryIDs->push_back(*BinaryID); return std::move(Readers); } diff --git a/llvm/lib/Support/Parallel.cpp b/llvm/lib/Support/Parallel.cpp index 23ed9d813548..c256d256be4f 100644 --- a/llvm/lib/Support/Parallel.cpp +++ b/llvm/lib/Support/Parallel.cpp @@ -214,8 +214,12 @@ void llvm::parallelFor(size_t Begin, size_t End, Fn(I); }); } - for (; Begin != End; ++Begin) - Fn(Begin); + if (Begin != End) { + TG.spawn([=, &Fn] { + for (size_t I = Begin; I != End; ++I) + Fn(I); + }); + } return; } #endif diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp index 92b15f14c62f..8943c4478c7f 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -802,8 +802,6 @@ uint64_t raw_fd_ostream::seek(uint64_t off) { flush(); #ifdef _WIN32 pos = ::_lseeki64(FD, off, SEEK_SET); -#elif defined(HAVE_LSEEK64) - pos = ::lseek64(FD, off, SEEK_SET); #else pos = ::lseek(FD, off, SEEK_SET); #endif diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 6a42c4ff31dc..12dc30a2818b 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -839,7 +839,7 @@ let Predicates = [HasSVEorSME] in { defm REVH_ZPmZ : sve_int_perm_rev_revh<"revh", AArch64revh_mt>; defm REVW_ZPmZ : sve_int_perm_rev_revw<"revw", AArch64revw_mt>; - defm REV_PP : sve_int_perm_reverse_p<"rev", vector_reverse>; + defm REV_PP : sve_int_perm_reverse_p<"rev", vector_reverse, int_aarch64_sve_rev_b16, int_aarch64_sve_rev_b32, int_aarch64_sve_rev_b64>; defm REV_ZZ : sve_int_perm_reverse_z<"rev", vector_reverse>; defm SUNPKLO_ZZ : sve_int_perm_unpk<0b00, "sunpklo", AArch64sunpklo>; @@ -1672,12 +1672,12 @@ let Predicates = [HasSVEorSME] in { defm TRN1_ZZZ : sve_int_perm_bin_perm_zz<0b100, "trn1", AArch64trn1>; defm TRN2_ZZZ : sve_int_perm_bin_perm_zz<0b101, "trn2", AArch64trn2>; - defm ZIP1_PPP : sve_int_perm_bin_perm_pp<0b000, "zip1", AArch64zip1>; - defm ZIP2_PPP : sve_int_perm_bin_perm_pp<0b001, "zip2", AArch64zip2>; - defm UZP1_PPP : sve_int_perm_bin_perm_pp<0b010, "uzp1", AArch64uzp1>; - defm UZP2_PPP : sve_int_perm_bin_perm_pp<0b011, "uzp2", AArch64uzp2>; - defm TRN1_PPP : sve_int_perm_bin_perm_pp<0b100, "trn1", AArch64trn1>; - defm TRN2_PPP : sve_int_perm_bin_perm_pp<0b101, "trn2", AArch64trn2>; + defm ZIP1_PPP : sve_int_perm_bin_perm_pp<0b000, "zip1", AArch64zip1, int_aarch64_sve_zip1_b16, int_aarch64_sve_zip1_b32, int_aarch64_sve_zip1_b64>; + defm ZIP2_PPP : sve_int_perm_bin_perm_pp<0b001, "zip2", AArch64zip2, int_aarch64_sve_zip2_b16, int_aarch64_sve_zip2_b32, int_aarch64_sve_zip2_b64>; + defm UZP1_PPP : sve_int_perm_bin_perm_pp<0b010, "uzp1", AArch64uzp1, int_aarch64_sve_uzp1_b16, int_aarch64_sve_uzp1_b32, int_aarch64_sve_uzp1_b64>; + defm UZP2_PPP : sve_int_perm_bin_perm_pp<0b011, "uzp2", AArch64uzp2, int_aarch64_sve_uzp2_b16, int_aarch64_sve_uzp2_b32, int_aarch64_sve_uzp2_b64>; + defm TRN1_PPP : sve_int_perm_bin_perm_pp<0b100, "trn1", AArch64trn1, int_aarch64_sve_trn1_b16, int_aarch64_sve_trn1_b32, int_aarch64_sve_trn1_b64>; + defm TRN2_PPP : sve_int_perm_bin_perm_pp<0b101, "trn2", AArch64trn2, int_aarch64_sve_trn2_b16, int_aarch64_sve_trn2_b32, int_aarch64_sve_trn2_b64>; // Extract lo/hi halves of legal predicate types. def : Pat<(nxv1i1 (extract_subvector (nxv2i1 PPR:$Ps), (i64 0))), diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index cef8d41218e8..1f0626191c0d 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -1448,11 +1448,12 @@ multiclass sve_int_perm_reverse_z<string asm, SDPatternOperator op> { def : SVE_1_Op_Pat<nxv8bf16, op, nxv8bf16, !cast<Instruction>(NAME # _H)>; } -class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty> +class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty, + SDPatternOperator op> : I<(outs pprty:$Pd), (ins pprty:$Pn), asm, "\t$Pd, $Pn", "", - []>, Sched<[]> { + [(set nxv16i1:$Pd, (op nxv16i1:$Pn))]>, Sched<[]> { bits<4> Pd; bits<4> Pn; let Inst{31-24} = 0b00000101; @@ -1463,16 +1464,18 @@ class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty> let Inst{3-0} = Pd; } -multiclass sve_int_perm_reverse_p<string asm, SDPatternOperator op> { - def _B : sve_int_perm_reverse_p<0b00, asm, PPR8>; - def _H : sve_int_perm_reverse_p<0b01, asm, PPR16>; - def _S : sve_int_perm_reverse_p<0b10, asm, PPR32>; - def _D : sve_int_perm_reverse_p<0b11, asm, PPR64>; +multiclass sve_int_perm_reverse_p<string asm, SDPatternOperator ir_op, + SDPatternOperator op_b16, + SDPatternOperator op_b32, + SDPatternOperator op_b64> { + def _B : sve_int_perm_reverse_p<0b00, asm, PPR8, ir_op>; + def _H : sve_int_perm_reverse_p<0b01, asm, PPR16, op_b16>; + def _S : sve_int_perm_reverse_p<0b10, asm, PPR32, op_b32>; + def _D : sve_int_perm_reverse_p<0b11, asm, PPR64, op_b64>; - def : SVE_1_Op_Pat<nxv16i1, op, nxv16i1, !cast<Instruction>(NAME # _B)>; - def : SVE_1_Op_Pat<nxv8i1, op, nxv8i1, !cast<Instruction>(NAME # _H)>; - def : SVE_1_Op_Pat<nxv4i1, op, nxv4i1, !cast<Instruction>(NAME # _S)>; - def : SVE_1_Op_Pat<nxv2i1, op, nxv2i1, !cast<Instruction>(NAME # _D)>; + def : SVE_1_Op_Pat<nxv8i1, ir_op, nxv8i1, !cast<Instruction>(NAME # _H)>; + def : SVE_1_Op_Pat<nxv4i1, ir_op, nxv4i1, !cast<Instruction>(NAME # _S)>; + def : SVE_1_Op_Pat<nxv2i1, ir_op, nxv2i1, !cast<Instruction>(NAME # _D)>; } class sve_int_perm_unpk<bits<2> sz16_64, bits<2> opc, string asm, @@ -6327,10 +6330,11 @@ multiclass sve_mem_p_spill<string asm> { //===----------------------------------------------------------------------===// class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm, - PPRRegOp pprty> + PPRRegOp pprty, SDPatternOperator op> : I<(outs pprty:$Pd), (ins pprty:$Pn, pprty:$Pm), asm, "\t$Pd, $Pn, $Pm", - "", []>, Sched<[]> { + "", + [(set nxv16i1:$Pd, (op nxv16i1:$Pn, nxv16i1:$Pm))]>, Sched<[]> { bits<4> Pd; bits<4> Pm; bits<4> Pn; @@ -6347,16 +6351,18 @@ class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm, } multiclass sve_int_perm_bin_perm_pp<bits<3> opc, string asm, - SDPatternOperator op> { - def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8>; - def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16>; - def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32>; - def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64>; - - def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>; - def : SVE_2_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>; - def : SVE_2_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>; - def : SVE_2_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>; + SDPatternOperator ir_op, + SDPatternOperator op_b16, + SDPatternOperator op_b32, + SDPatternOperator op_b64> { + def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8, ir_op>; + def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16, op_b16>; + def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32, op_b32>; + def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64, op_b64>; + + def : SVE_2_Op_Pat<nxv8i1, ir_op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>; + def : SVE_2_Op_Pat<nxv4i1, ir_op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>; + def : SVE_2_Op_Pat<nxv2i1, ir_op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>; } class sve_int_perm_punpk<bit opc, string asm> diff --git a/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp b/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp index 2ee228d72825..a26a3f2411f8 100644 --- a/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp +++ b/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp @@ -175,8 +175,9 @@ static bool isSignExtendedW(Register SrcReg, const MachineRegisterInfo &MRI, const AttributeSet &Attrs = CalleeFn->getAttributes().getRetAttrs(); unsigned BitWidth = IntTy->getBitWidth(); - return (BitWidth <= 32 && Attrs.hasAttribute(Attribute::SExt)) || - (BitWidth < 32 && Attrs.hasAttribute(Attribute::ZExt)); + if ((BitWidth <= 32 && Attrs.hasAttribute(Attribute::SExt)) || + (BitWidth < 32 && Attrs.hasAttribute(Attribute::ZExt))) + continue; } if (!AddRegDefToWorkList(CopySrcReg)) diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td index c92a30804014..4dd8a6cdd898 100644 --- a/llvm/lib/Target/X86/X86CallingConv.td +++ b/llvm/lib/Target/X86/X86CallingConv.td @@ -1154,11 +1154,11 @@ def CSR_64_CXX_TLS_Darwin_PE : CalleeSavedRegs<(add RBP)>; // CSRs that are handled explicitly via copies. def CSR_64_CXX_TLS_Darwin_ViaCopy : CalleeSavedRegs<(sub CSR_64_TLS_Darwin, RBP)>; -// All GPRs - except r11 and return registers. +// All GPRs - except r11 def CSR_64_RT_MostRegs : CalleeSavedRegs<(add CSR_64, RAX, RCX, RDX, RSI, RDI, R8, R9, R10)>; -// All registers - except r11 and return registers. +// All registers - except r11 def CSR_64_RT_AllRegs : CalleeSavedRegs<(add CSR_64_RT_MostRegs, (sequence "XMM%u", 0, 15))>; def CSR_64_RT_AllRegs_AVX : CalleeSavedRegs<(add CSR_64_RT_MostRegs, diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a33ee63c877e..cf17c51b04fc 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -104,20 +104,6 @@ static void errorUnsupported(SelectionDAG &DAG, const SDLoc &dl, DiagnosticInfoUnsupported(MF.getFunction(), Msg, dl.getDebugLoc())); } -/// Returns true if a CC can dynamically exclude a register from the list of -/// callee-saved-registers (TargetRegistryInfo::getCalleeSavedRegs()) based on -/// params/returns. -static bool shouldDisableCalleeSavedRegisterCC(CallingConv::ID CC) { - switch (CC) { - default: - return false; - case CallingConv::X86_RegCall: - case CallingConv::PreserveMost: - case CallingConv::PreserveAll: - return true; - } -} - X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, const X86Subtarget &STI) : TargetLowering(TM), Subtarget(STI) { @@ -3181,7 +3167,7 @@ X86TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, // In some cases we need to disable registers from the default CSR list. // For example, when they are used for argument passing. bool ShouldDisableCalleeSavedRegister = - shouldDisableCalleeSavedRegisterCC(CallConv) || + CallConv == CallingConv::X86_RegCall || MF.getFunction().hasFnAttribute("no_caller_saved_registers"); if (CallConv == CallingConv::X86_INTR && !Outs.empty()) @@ -4333,7 +4319,7 @@ SDValue X86TargetLowering::LowerFormalArguments( } } - if (shouldDisableCalleeSavedRegisterCC(CallConv) || + if (CallConv == CallingConv::X86_RegCall || F.hasFnAttribute("no_caller_saved_registers")) { MachineRegisterInfo &MRI = MF.getRegInfo(); for (std::pair<Register, Register> Pair : MRI.liveins()) @@ -4894,7 +4880,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // In some calling conventions we need to remove the used physical registers // from the reg mask. - if (shouldDisableCalleeSavedRegisterCC(CallConv) || HasNCSR) { + if (CallConv == CallingConv::X86_RegCall || HasNCSR) { const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); // Allocate a new Reg Mask and copy Mask. @@ -22000,15 +21986,25 @@ SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op, // Extend everything to 80 bits to force it to be done on x87. // TODO: Are there any fast-math-flags to propagate here? if (IsStrict) { - SDValue Add = DAG.getNode(ISD::STRICT_FADD, dl, {MVT::f80, MVT::Other}, - {Chain, Fild, Fudge}); + unsigned Opc = ISD::STRICT_FADD; + // Windows needs the precision control changed to 80bits around this add. + if (Subtarget.isOSWindows() && DstVT == MVT::f32) + Opc = X86ISD::STRICT_FP80_ADD; + + SDValue Add = + DAG.getNode(Opc, dl, {MVT::f80, MVT::Other}, {Chain, Fild, Fudge}); // STRICT_FP_ROUND can't handle equal types. if (DstVT == MVT::f80) return Add; return DAG.getNode(ISD::STRICT_FP_ROUND, dl, {DstVT, MVT::Other}, {Add.getValue(1), Add, DAG.getIntPtrConstant(0, dl)}); } - SDValue Add = DAG.getNode(ISD::FADD, dl, MVT::f80, Fild, Fudge); + unsigned Opc = ISD::FADD; + // Windows needs the precision control changed to 80bits around this add. + if (Subtarget.isOSWindows() && DstVT == MVT::f32) + Opc = X86ISD::FP80_ADD; + + SDValue Add = DAG.getNode(Opc, dl, MVT::f80, Fild, Fudge); return DAG.getNode(ISD::FP_ROUND, dl, DstVT, Add, DAG.getIntPtrConstant(0, dl, /*isTarget=*/true)); } @@ -34804,6 +34800,8 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { NODE_NAME_CASE(AESDECWIDE256KL) NODE_NAME_CASE(CMPCCXADD) NODE_NAME_CASE(TESTUI) + NODE_NAME_CASE(FP80_ADD) + NODE_NAME_CASE(STRICT_FP80_ADD) } return nullptr; #undef NODE_NAME_CASE @@ -37314,6 +37312,69 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, return BB; } + case X86::FP80_ADDr: + case X86::FP80_ADDm32: { + // Change the floating point control register to use double extended + // precision when performing the addition. + int OrigCWFrameIdx = + MF->getFrameInfo().CreateStackObject(2, Align(2), false); + addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::FNSTCW16m)), + OrigCWFrameIdx); + + // Load the old value of the control word... + Register OldCW = MF->getRegInfo().createVirtualRegister(&X86::GR32RegClass); + addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::MOVZX32rm16), OldCW), + OrigCWFrameIdx); + + // OR 0b11 into bit 8 and 9. 0b11 is the encoding for double extended + // precision. + Register NewCW = MF->getRegInfo().createVirtualRegister(&X86::GR32RegClass); + BuildMI(*BB, MI, DL, TII->get(X86::OR32ri), NewCW) + .addReg(OldCW, RegState::Kill) + .addImm(0x300); + + // Extract to 16 bits. + Register NewCW16 = + MF->getRegInfo().createVirtualRegister(&X86::GR16RegClass); + BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), NewCW16) + .addReg(NewCW, RegState::Kill, X86::sub_16bit); + + // Prepare memory for FLDCW. + int NewCWFrameIdx = + MF->getFrameInfo().CreateStackObject(2, Align(2), false); + addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::MOV16mr)), + NewCWFrameIdx) + .addReg(NewCW16, RegState::Kill); + + // Reload the modified control word now... + addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::FLDCW16m)), + NewCWFrameIdx); + + // Do the addition. + if (MI.getOpcode() == X86::FP80_ADDr) { + BuildMI(*BB, MI, DL, TII->get(X86::ADD_Fp80)) + .add(MI.getOperand(0)) + .add(MI.getOperand(1)) + .add(MI.getOperand(2)); + } else { + BuildMI(*BB, MI, DL, TII->get(X86::ADD_Fp80m32)) + .add(MI.getOperand(0)) + .add(MI.getOperand(1)) + .add(MI.getOperand(2)) + .add(MI.getOperand(3)) + .add(MI.getOperand(4)) + .add(MI.getOperand(5)) + .add(MI.getOperand(6)); + } + + // Reload the original control word now. + addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::FLDCW16m)), + OrigCWFrameIdx); + + MI.eraseFromParent(); // The pseudo instruction is gone now. + return BB; + } + case X86::FP32_TO_INT16_IN_MEM: case X86::FP32_TO_INT32_IN_MEM: case X86::FP32_TO_INT64_IN_MEM: diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index c5c115047271..d802d5f53aa2 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -740,6 +740,9 @@ namespace llvm { // User level interrupts - testui TESTUI, + // Perform an FP80 add after changing precision control in FPCW. + FP80_ADD, + /// X86 strict FP compare instructions. STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE, STRICT_FCMPS, @@ -779,6 +782,9 @@ namespace llvm { STRICT_CVTPS2PH, STRICT_CVTPH2PS, + // Perform an FP80 add after changing precision control in FPCW. + STRICT_FP80_ADD, + // WARNING: Only add nodes here if they are strict FP nodes. Non-memory and // non-strict FP nodes should be above FIRST_TARGET_STRICTFP_OPCODE. diff --git a/llvm/lib/Target/X86/X86InstrFPStack.td b/llvm/lib/Target/X86/X86InstrFPStack.td index a68d61043c5c..fbbd3c83dc5c 100644 --- a/llvm/lib/Target/X86/X86InstrFPStack.td +++ b/llvm/lib/Target/X86/X86InstrFPStack.td @@ -26,6 +26,13 @@ def SDTX86Fist : SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>; def SDTX86CwdStore : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; def SDTX86CwdLoad : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; +def X86fp80_add : SDNode<"X86ISD::FP80_ADD", SDTFPBinOp, [SDNPCommutative]>; +def X86strict_fp80_add : SDNode<"X86ISD::STRICT_FP80_ADD", SDTFPBinOp, + [SDNPHasChain,SDNPCommutative]>; +def any_X86fp80_add : PatFrags<(ops node:$lhs, node:$rhs), + [(X86strict_fp80_add node:$lhs, node:$rhs), + (X86fp80_add node:$lhs, node:$rhs)]>; + def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, @@ -141,6 +148,14 @@ let usesCustomInserter = 1, hasNoSchedulingInfo = 1, Defs = [EFLAGS] in { [(X86fp_to_i32mem RFP80:$src, addr:$dst)]>; def FP80_TO_INT64_IN_MEM : PseudoI<(outs), (ins i64mem:$dst, RFP80:$src), [(X86fp_to_i64mem RFP80:$src, addr:$dst)]>; + + def FP80_ADDr : PseudoI<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), + [(set RFP80:$dst, + (any_X86fp80_add RFP80:$src1, RFP80:$src2))]>; + def FP80_ADDm32 : PseudoI<(outs RFP80:$dst), (ins RFP80:$src1, f32mem:$src2), + [(set RFP80:$dst, + (any_X86fp80_add RFP80:$src1, + (f80 (extloadf32 addr:$src2))))]>; } // All FP Stack operations are represented with four instructions here. The diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 001ef55ba472..42158e4e05dd 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -1043,12 +1043,14 @@ struct AAPointerInfoImpl const auto &NoSyncAA = A.getAAFor<AANoSync>( QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL); const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( - IRPosition::function(Scope), &QueryingAA, DepClassTy::OPTIONAL); + IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE); bool AllInSameNoSyncFn = NoSyncAA.isAssumedNoSync(); bool InstIsExecutedByInitialThreadOnly = ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I); bool InstIsExecutedInAlignedRegion = ExecDomainAA && ExecDomainAA->isExecutedInAlignedRegion(A, I); + if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly) + A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); InformationCache &InfoCache = A.getInfoCache(); bool IsThreadLocalObj = @@ -1063,14 +1065,24 @@ struct AAPointerInfoImpl auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool { if (IsThreadLocalObj || AllInSameNoSyncFn) return true; - if (!ExecDomainAA) + const auto *FnExecDomainAA = + I.getFunction() == &Scope + ? ExecDomainAA + : A.lookupAAFor<AAExecutionDomain>( + IRPosition::function(*I.getFunction()), &QueryingAA, + DepClassTy::NONE); + if (!FnExecDomainAA) return false; if (InstIsExecutedInAlignedRegion || - ExecDomainAA->isExecutedInAlignedRegion(A, I)) + FnExecDomainAA->isExecutedInAlignedRegion(A, I)) { + A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); return true; + } if (InstIsExecutedByInitialThreadOnly && - ExecDomainAA->isExecutedByInitialThreadOnly(I)) + FnExecDomainAA->isExecutedByInitialThreadOnly(I)) { + A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); return true; + } return false; }; @@ -4161,12 +4173,14 @@ struct AAIsDeadFloating : public AAIsDeadValueImpl { return true; if (auto *LI = dyn_cast<LoadInst>(V)) { if (llvm::all_of(LI->uses(), [&](const Use &U) { - return InfoCache.isOnlyUsedByAssume( - cast<Instruction>(*U.getUser())) || - A.isAssumedDead(U, this, nullptr, UsedAssumedInformation); + auto &UserI = cast<Instruction>(*U.getUser()); + if (InfoCache.isOnlyUsedByAssume(UserI)) { + if (AssumeOnlyInst) + AssumeOnlyInst->insert(&UserI); + return true; + } + return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation); })) { - if (AssumeOnlyInst) - AssumeOnlyInst->insert(LI); return true; } } diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp index bee154dab10f..eb499a1aa912 100644 --- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp +++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp @@ -188,9 +188,9 @@ struct AAICVTracker; struct OMPInformationCache : public InformationCache { OMPInformationCache(Module &M, AnalysisGetter &AG, BumpPtrAllocator &Allocator, SetVector<Function *> *CGSCC, - KernelSet &Kernels) + KernelSet &Kernels, bool OpenMPPostLink) : InformationCache(M, AG, Allocator, CGSCC), OMPBuilder(M), - Kernels(Kernels) { + Kernels(Kernels), OpenMPPostLink(OpenMPPostLink) { OMPBuilder.initialize(); initializeRuntimeFunctions(M); @@ -448,6 +448,24 @@ struct OMPInformationCache : public InformationCache { CI->setCallingConv(Fn->getCallingConv()); } + // Helper function to determine if it's legal to create a call to the runtime + // functions. + bool runtimeFnsAvailable(ArrayRef<RuntimeFunction> Fns) { + // We can always emit calls if we haven't yet linked in the runtime. + if (!OpenMPPostLink) + return true; + + // Once the runtime has been already been linked in we cannot emit calls to + // any undefined functions. + for (RuntimeFunction Fn : Fns) { + RuntimeFunctionInfo &RFI = RFIs[Fn]; + + if (RFI.Declaration && RFI.Declaration->isDeclaration()) + return false; + } + return true; + } + /// Helper to initialize all runtime function information for those defined /// in OpenMPKinds.def. void initializeRuntimeFunctions(Module &M) { @@ -523,6 +541,9 @@ struct OMPInformationCache : public InformationCache { /// Collection of known OpenMP runtime functions.. DenseSet<const Function *> RTLFunctions; + + /// Indicates if we have already linked in the OpenMP device library. + bool OpenMPPostLink = false; }; template <typename Ty, bool InsertInvalidates = true> @@ -1412,7 +1433,10 @@ private: Changed |= WasSplit; return WasSplit; }; - RFI.foreachUse(SCC, SplitMemTransfers); + if (OMPInfoCache.runtimeFnsAvailable( + {OMPRTL___tgt_target_data_begin_mapper_issue, + OMPRTL___tgt_target_data_begin_mapper_wait})) + RFI.foreachUse(SCC, SplitMemTransfers); return Changed; } @@ -2656,7 +2680,9 @@ struct AAExecutionDomainFunction : public AAExecutionDomain { bool isExecutedInAlignedRegion(Attributor &A, const Instruction &I) const override { - if (!isValidState() || isa<CallBase>(I)) + assert(I.getFunction() == getAnchorScope() && + "Instruction is out of scope!"); + if (!isValidState()) return false; const Instruction *CurI; @@ -2667,14 +2693,18 @@ struct AAExecutionDomainFunction : public AAExecutionDomain { auto *CB = dyn_cast<CallBase>(CurI); if (!CB) continue; + if (CB != &I && AlignedBarriers.contains(const_cast<CallBase *>(CB))) { + break; + } const auto &It = CEDMap.find(CB); if (It == CEDMap.end()) continue; - if (!It->getSecond().IsReachedFromAlignedBarrierOnly) + if (!It->getSecond().IsReachingAlignedBarrierOnly) return false; + break; } while ((CurI = CurI->getNextNonDebugInstruction())); - if (!CurI && !BEDMap.lookup(I.getParent()).IsReachedFromAlignedBarrierOnly) + if (!CurI && !BEDMap.lookup(I.getParent()).IsReachingAlignedBarrierOnly) return false; // Check backward until a call or the block beginning is reached. @@ -2683,12 +2713,16 @@ struct AAExecutionDomainFunction : public AAExecutionDomain { auto *CB = dyn_cast<CallBase>(CurI); if (!CB) continue; + if (CB != &I && AlignedBarriers.contains(const_cast<CallBase *>(CB))) { + break; + } const auto &It = CEDMap.find(CB); if (It == CEDMap.end()) continue; if (!AA::isNoSyncInst(A, *CB, *this)) { - if (It->getSecond().IsReachedFromAlignedBarrierOnly) + if (It->getSecond().IsReachedFromAlignedBarrierOnly) { break; + } return false; } @@ -2984,7 +3018,8 @@ ChangeStatus AAExecutionDomainFunction::updateImpl(Attributor &A) { if (EDAA.getState().isValidState()) { const auto &CalleeED = EDAA.getFunctionExecutionDomain(); ED.IsReachedFromAlignedBarrierOnly = - CalleeED.IsReachedFromAlignedBarrierOnly; + CallED.IsReachedFromAlignedBarrierOnly = + CalleeED.IsReachedFromAlignedBarrierOnly; AlignedBarrierLastInBlock = ED.IsReachedFromAlignedBarrierOnly; if (IsNoSync || !CalleeED.IsReachedFromAlignedBarrierOnly) ED.EncounteredNonLocalSideEffect |= @@ -2999,8 +3034,9 @@ ChangeStatus AAExecutionDomainFunction::updateImpl(Attributor &A) { continue; } } - ED.IsReachedFromAlignedBarrierOnly = - IsNoSync && ED.IsReachedFromAlignedBarrierOnly; + if (!IsNoSync) + ED.IsReachedFromAlignedBarrierOnly = + CallED.IsReachedFromAlignedBarrierOnly = false; AlignedBarrierLastInBlock &= ED.IsReachedFromAlignedBarrierOnly; ED.EncounteredNonLocalSideEffect |= !CB->doesNotAccessMemory(); if (!IsNoSync) @@ -3914,6 +3950,12 @@ struct AAKernelInfoFunction : AAKernelInfo { bool changeToSPMDMode(Attributor &A, ChangeStatus &Changed) { auto &OMPInfoCache = static_cast<OMPInformationCache &>(A.getInfoCache()); + // We cannot change to SPMD mode if the runtime functions aren't availible. + if (!OMPInfoCache.runtimeFnsAvailable( + {OMPRTL___kmpc_get_hardware_thread_id_in_block, + OMPRTL___kmpc_barrier_simple_spmd})) + return false; + if (!SPMDCompatibilityTracker.isAssumed()) { for (Instruction *NonCompatibleI : SPMDCompatibilityTracker) { if (!NonCompatibleI) @@ -4021,6 +4063,13 @@ struct AAKernelInfoFunction : AAKernelInfo { if (!ReachedKnownParallelRegions.isValidState()) return ChangeStatus::UNCHANGED; + auto &OMPInfoCache = static_cast<OMPInformationCache &>(A.getInfoCache()); + if (!OMPInfoCache.runtimeFnsAvailable( + {OMPRTL___kmpc_get_hardware_num_threads_in_block, + OMPRTL___kmpc_get_warp_size, OMPRTL___kmpc_barrier_simple_generic, + OMPRTL___kmpc_kernel_parallel, OMPRTL___kmpc_kernel_end_parallel})) + return ChangeStatus::UNCHANGED; + const int InitModeArgNo = 1; const int InitUseStateMachineArgNo = 2; @@ -4167,7 +4216,6 @@ struct AAKernelInfoFunction : AAKernelInfo { BranchInst::Create(IsWorkerCheckBB, UserCodeEntryBB, IsWorker, InitBB); Module &M = *Kernel->getParent(); - auto &OMPInfoCache = static_cast<OMPInformationCache &>(A.getInfoCache()); FunctionCallee BlockHwSizeFn = OMPInfoCache.OMPBuilder.getOrCreateRuntimeFunction( M, OMPRTL___kmpc_get_hardware_num_threads_in_block); @@ -5343,7 +5391,10 @@ PreservedAnalyses OpenMPOptPass::run(Module &M, ModuleAnalysisManager &AM) { BumpPtrAllocator Allocator; CallGraphUpdater CGUpdater; - OMPInformationCache InfoCache(M, AG, Allocator, /*CGSCC*/ nullptr, Kernels); + bool PostLink = LTOPhase == ThinOrFullLTOPhase::FullLTOPostLink || + LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink; + OMPInformationCache InfoCache(M, AG, Allocator, /*CGSCC*/ nullptr, Kernels, + PostLink); unsigned MaxFixpointIterations = (isOpenMPDevice(M)) ? SetFixpointIterations : 32; @@ -5417,9 +5468,11 @@ PreservedAnalyses OpenMPOptCGSCCPass::run(LazyCallGraph::SCC &C, CallGraphUpdater CGUpdater; CGUpdater.initialize(CG, C, AM, UR); + bool PostLink = LTOPhase == ThinOrFullLTOPhase::FullLTOPostLink || + LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink; SetVector<Function *> Functions(SCC.begin(), SCC.end()); OMPInformationCache InfoCache(*(Functions.back()->getParent()), AG, Allocator, - /*CGSCC*/ &Functions, Kernels); + /*CGSCC*/ &Functions, Kernels, PostLink); unsigned MaxFixpointIterations = (isOpenMPDevice(M)) ? SetFixpointIterations : 32; diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index 2b2eda5d8587..7366059cd242 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -23,6 +23,10 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/Debuginfod/BuildIDFetcher.h" +#include "llvm/Debuginfod/Debuginfod.h" +#include "llvm/Debuginfod/HTTPClient.h" +#include "llvm/Object/BuildID.h" #include "llvm/ProfileData/Coverage/CoverageMapping.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/CommandLine.h" @@ -179,6 +183,8 @@ private: /// Allowlist from -name-allowlist to be used for filtering. std::unique_ptr<SpecialCaseList> NameAllowlist; + + std::unique_ptr<object::BuildIDFetcher> BIDFetcher; }; } @@ -435,7 +441,7 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() { ObjectFilename); auto CoverageOrErr = CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches, - ViewOpts.CompilationDirectory); + ViewOpts.CompilationDirectory, BIDFetcher.get()); if (Error E = CoverageOrErr.takeError()) { error("Failed to load coverage: " + toString(std::move(E))); return nullptr; @@ -647,6 +653,14 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { cl::opt<bool> DebugDump("dump", cl::Optional, cl::desc("Show internal debug dump")); + cl::list<std::string> DebugFileDirectory( + "debug-file-directory", + cl::desc("Directories to search for object files by build ID")); + cl::opt<bool> Debuginfod( + "debuginfod", cl::ZeroOrMore, + cl::desc("Use debuginfod to look up object files from profile"), + cl::init(canUseDebuginfod())); + cl::opt<CoverageViewOptions::OutputFormat> Format( "format", cl::desc("Output format for line-based coverage reports"), cl::values(clEnumValN(CoverageViewOptions::OutputFormat::Text, "text", @@ -749,12 +763,18 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { auto commandLineParser = [&, this](int argc, const char **argv) -> int { cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); ViewOpts.Debug = DebugDump; + if (Debuginfod) { + HTTPClient::initialize(); + BIDFetcher = std::make_unique<DebuginfodFetcher>(DebugFileDirectory); + } else { + BIDFetcher = std::make_unique<object::BuildIDFetcher>(DebugFileDirectory); + } if (!CovFilename.empty()) ObjectFilenames.emplace_back(CovFilename); for (const std::string &Filename : CovFilenames) ObjectFilenames.emplace_back(Filename); - if (ObjectFilenames.empty()) { + if (ObjectFilenames.empty() && !Debuginfod && DebugFileDirectory.empty()) { errs() << "No filenames specified!\n"; ::exit(1); } @@ -867,10 +887,8 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { } CoverageArches.emplace_back(Arch); } - if (CoverageArches.size() == 1) - CoverageArches.insert(CoverageArches.end(), ObjectFilenames.size() - 1, - CoverageArches[0]); - if (CoverageArches.size() != ObjectFilenames.size()) { + if (CoverageArches.size() != 1 && + CoverageArches.size() != ObjectFilenames.size()) { error("Number of architectures doesn't match the number of objects"); return 1; } diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 930b132533cd..9979a26cf115 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -3198,9 +3198,7 @@ int main(int argc, char **argv) { // Initialize debuginfod. const bool ShouldUseDebuginfodByDefault = - InputArgs.hasArg(OBJDUMP_build_id) || - (HTTPClient::isAvailable() && - !ExitOnErr(getDefaultDebuginfodUrls()).empty()); + InputArgs.hasArg(OBJDUMP_build_id) || canUseDebuginfod(); std::vector<std::string> DebugFileDirectories = InputArgs.getAllArgValues(OBJDUMP_debug_file_directory); if (InputArgs.hasFlag(OBJDUMP_debuginfod, OBJDUMP_no_debuginfod, diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp index 1b86134dda51..ed24e8550291 100644 --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -443,13 +443,7 @@ int main(int argc, char **argv) { LLVMSymbolizer Symbolizer(Opts); - // A debuginfod lookup could succeed if a HTTP client is available and at - // least one backing URL is configured. - bool ShouldUseDebuginfodByDefault = - HTTPClient::isAvailable() && - !ExitOnErr(getDefaultDebuginfodUrls()).empty(); - if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod, - ShouldUseDebuginfodByDefault)) + if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod, canUseDebuginfod())) enableDebuginfod(Symbolizer, Args); if (Args.hasArg(OPT_filter_markup)) { |