Vendor import of llvm-project branch release/16.x llvmorg-16.0.0-rc2-10-g073506d8c15c.

This commit is contained in:
Dimitry Andric 2023-02-11 13:53:39 +01:00
parent e3b5578096
commit 11edbfca22
64 changed files with 830 additions and 441 deletions

View file

@ -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))

View file

@ -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<

View file

@ -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

View file

@ -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 __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 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 __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 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_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 __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 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_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 __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 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_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

View file

@ -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 {

View file

@ -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);
}

View file

@ -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);

View file

@ -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 =

View file

@ -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)));
}
}

View file

@ -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)

View file

@ -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;
}

View file

@ -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()));

View file

@ -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))

View file

@ -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

View file

@ -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.

View file

@ -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;
}

View file

@ -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;

View file

@ -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();

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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);

View file

@ -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)

View file

@ -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.

View file

@ -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");
}
}

View file

@ -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);

View file

@ -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

View file

@ -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) {

View file

@ -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]);

View file

@ -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

View file

@ -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" }

View file

@ -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)) {

View file

@ -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
----------------

View file

@ -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;

View file

@ -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;

View file

@ -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.

View file

@ -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;

View file

@ -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.
///

View file

@ -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,

View file

@ -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

View file

@ -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)

View file

@ -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();

View file

@ -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.

View file

@ -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);
}

View file

@ -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());

View file

@ -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());

View file

@ -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())

View file

@ -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));

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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))),

View file

@ -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>;
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<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)>;
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>

View file

@ -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))

View file

@ -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,

View file

@ -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:

View file

@ -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.

View file

@ -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

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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,

View file

@ -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)) {