From 3b922bd9516f6dc5146815ed8d4363fcbe97997f Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 4 Jun 2023 21:00:19 +0200 Subject: [PATCH] Vendor import of llvm-project branch release/16.x llvmorg-16.0.5-0-g185b81e034ba (aka 16.0.5 release). --- clang/include/clang/AST/ExprConcepts.h | 8 + .../clang/Basic/DiagnosticSemaKinds.td | 3 +- clang/include/clang/Sema/Initialization.h | 18 +- clang/include/clang/Sema/Sema.h | 3 + clang/lib/AST/ASTContext.cpp | 3 +- clang/lib/AST/ExprConcepts.cpp | 19 +- clang/lib/Driver/ToolChains/Clang.cpp | 1 + .../Format/IntegerLiteralSeparatorFixer.cpp | 6 +- clang/lib/Sema/SemaAccess.cpp | 3 +- clang/lib/Sema/SemaDecl.cpp | 2 +- clang/lib/Sema/SemaExpr.cpp | 26 +- clang/lib/Sema/SemaInit.cpp | 335 +++++++++++------- libcxx/include/__config | 2 +- lld/docs/WebAssembly.rst | 33 ++ llvm/include/llvm/Analysis/AliasAnalysis.h | 9 + .../include/llvm/Analysis/TargetLibraryInfo.h | 12 +- .../Target/Hexagon/HexagonISelLowering.cpp | 7 +- llvm/lib/Target/Hexagon/HexagonPatterns.td | 24 +- llvm/lib/Target/X86/X86ISelLowering.cpp | 27 +- llvm/lib/Target/X86/X86InstrAVX512.td | 21 ++ llvm/tools/llvm-mca/llvm-mca.cpp | 19 +- 21 files changed, 403 insertions(+), 178 deletions(-) diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h index f02c140c14c1..746a5b2fbfc6 100644 --- a/clang/include/clang/AST/ExprConcepts.h +++ b/clang/include/clang/AST/ExprConcepts.h @@ -64,6 +64,7 @@ class ConceptSpecializationExpr final : public Expr, public ConceptReference { const ConstraintSatisfaction *Satisfaction); ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept, + const ASTTemplateArgumentListInfo *ArgsAsWritten, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction, bool Dependent, @@ -85,6 +86,13 @@ class ConceptSpecializationExpr final : public Expr, public ConceptReference { const ConstraintSatisfaction *Satisfaction, bool Dependent, bool ContainsUnexpandedParameterPack); + static ConceptSpecializationExpr * + Create(const ASTContext &C, ConceptDecl *NamedConcept, + const ASTTemplateArgumentListInfo *ArgsAsWritten, + ImplicitConceptSpecializationDecl *SpecDecl, + const ConstraintSatisfaction *Satisfaction, bool Dependent, + bool ContainsUnexpandedParameterPack); + ArrayRef getTemplateArguments() const { return SpecDecl->getTemplateArguments(); } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index bfe582d8252f..6d72040c4b87 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2124,7 +2124,8 @@ def err_init_conversion_failed : Error< "exception object|a member subobject|an array element|a new value|a value|a " "base class|a constructor delegation|a vector element|a block element|a " "block element|a complex element|a lambda capture|a compound literal " - "initializer|a related result|a parameter of CF audited function}0 " + "initializer|a related result|a parameter of CF audited function|a " + "structured binding|a member subobject}0 " "%diff{of type $ with an %select{rvalue|lvalue}2 of type $|" "with an %select{rvalue|lvalue}2 of incompatible type}1,3" "%select{|: different classes%diff{ ($ vs $)|}5,6" diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index e5a98ba97f4f..e1bbea0d118d 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -123,6 +123,10 @@ class alignas(8) InitializedEntity { /// decomposition declaration. EK_Binding, + /// The entity being initialized is a non-static data member subobject of an + /// object initialized via parenthesized aggregate initialization. + EK_ParenAggInitMember, + // Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this // enum as an index for its first %select. When modifying this list, // that diagnostic text needs to be updated as well. @@ -227,8 +231,10 @@ class alignas(8) InitializedEntity { /// Create the initialization entity for a member subobject. InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent, - bool Implicit, bool DefaultMemberInit) - : Kind(EK_Member), Parent(Parent), Type(Member->getType()), + bool Implicit, bool DefaultMemberInit, + bool IsParenAggInit = false) + : Kind(IsParenAggInit ? EK_ParenAggInitMember : EK_Member), + Parent(Parent), Type(Member->getType()), Variable{Member, Implicit, DefaultMemberInit} {} /// Create the initialization entity for an array element. @@ -388,6 +394,14 @@ class alignas(8) InitializedEntity { return InitializedEntity(Member->getAnonField(), Parent, Implicit, false); } + /// Create the initialization entity for a member subobject initialized via + /// parenthesized aggregate init. + static InitializedEntity InitializeMemberFromParenAggInit(FieldDecl *Member) { + return InitializedEntity(Member, /*Parent=*/nullptr, /*Implicit=*/false, + /*DefaultMemberInit=*/false, + /*IsParenAggInit=*/true); + } + /// Create the initialization entity for a default member initializer. static InitializedEntity InitializeMemberFromDefaultMemberInitializer(FieldDecl *Member) { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d40dacb5aa0f..e57955f16bdd 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1394,6 +1394,9 @@ class Sema final { /// A stack of expression evaluation contexts. SmallVector ExprEvalContexts; + // Set of failed immediate invocations to avoid double diagnosing. + llvm::SmallPtrSet FailedImmediateInvocations; + /// Emit a warning for all pending noderef expressions that we recorded. void WarnOnPendingNoDerefs(ExpressionEvaluationContextRecord &Rec); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 2884fe660422..8054eb2e12d3 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -765,7 +765,8 @@ canonicalizeImmediatelyDeclaredConstraint(const ASTContext &C, Expr *IDC, CSE->getNamedConcept()->getLocation(), NewConverted); Expr *NewIDC = ConceptSpecializationExpr::Create( - C, CSE->getNamedConcept(), CSD, nullptr, CSE->isInstantiationDependent(), + C, CSE->getNamedConcept(), CSE->getTemplateArgsAsWritten(), CSD, + /*Satisfaction=*/nullptr, CSE->isInstantiationDependent(), CSE->containsUnexpandedParameterPack()); if (auto *OrigFold = dyn_cast(IDC)) diff --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp index fc8f1eb2abf1..cdc13c2d3969 100644 --- a/clang/lib/AST/ExprConcepts.cpp +++ b/clang/lib/AST/ExprConcepts.cpp @@ -58,6 +58,15 @@ ConceptSpecializationExpr::ConceptSpecializationExpr( ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty) : Expr(ConceptSpecializationExprClass, Empty) {} +ConceptSpecializationExpr *ConceptSpecializationExpr::Create( + const ASTContext &C, ConceptDecl *NamedConcept, + ImplicitConceptSpecializationDecl *SpecDecl, + const ConstraintSatisfaction *Satisfaction, bool Dependent, + bool ContainsUnexpandedParameterPack) { + return Create(C, NamedConcept, /*ArgsAsWritten*/ nullptr, SpecDecl, Satisfaction, + Dependent, ContainsUnexpandedParameterPack); +} + ConceptSpecializationExpr *ConceptSpecializationExpr::Create( const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, @@ -72,13 +81,14 @@ ConceptSpecializationExpr *ConceptSpecializationExpr::Create( ConceptSpecializationExpr::ConceptSpecializationExpr( const ASTContext &C, ConceptDecl *NamedConcept, + const ASTTemplateArgumentListInfo *ArgsAsWritten, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction, bool Dependent, bool ContainsUnexpandedParameterPack) : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary), ConceptReference(NestedNameSpecifierLoc(), SourceLocation(), DeclarationNameInfo(), NamedConcept, NamedConcept, - nullptr), + ArgsAsWritten), SpecDecl(SpecDecl), Satisfaction(Satisfaction ? ASTConstraintSatisfaction::Create(C, *Satisfaction) @@ -95,12 +105,13 @@ ConceptSpecializationExpr::ConceptSpecializationExpr( ConceptSpecializationExpr *ConceptSpecializationExpr::Create( const ASTContext &C, ConceptDecl *NamedConcept, + const ASTTemplateArgumentListInfo *ArgsAsWritten, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction, bool Dependent, bool ContainsUnexpandedParameterPack) { - return new (C) - ConceptSpecializationExpr(C, NamedConcept, SpecDecl, Satisfaction, - Dependent, ContainsUnexpandedParameterPack); + return new (C) ConceptSpecializationExpr(C, NamedConcept, ArgsAsWritten, + SpecDecl, Satisfaction, Dependent, + ContainsUnexpandedParameterPack); } const TypeConstraint * diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 238507e06335..77554aa2c462 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -7801,6 +7801,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, } else { D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << GuardArgs; } + A->claim(); } } diff --git a/clang/lib/Format/IntegerLiteralSeparatorFixer.cpp b/clang/lib/Format/IntegerLiteralSeparatorFixer.cpp index 44034e44adec..3cc68673cd13 100644 --- a/clang/lib/Format/IntegerLiteralSeparatorFixer.cpp +++ b/clang/lib/Format/IntegerLiteralSeparatorFixer.cpp @@ -113,7 +113,11 @@ IntegerLiteralSeparatorFixer::process(const Environment &Env, continue; } if (Style.isCpp()) { - if (const auto Pos = Text.find_first_of("_i"); Pos != StringRef::npos) { + // Hex alpha digits a-f/A-F must be at the end of the string literal. + StringRef Suffixes = "_himnsuyd"; + if (const auto Pos = + Text.find_first_of(IsBase16 ? Suffixes.drop_back() : Suffixes); + Pos != StringRef::npos) { Text = Text.substr(0, Pos); Length = Pos; } diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index cbda62497e6a..4a39c2d065e6 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -1651,7 +1651,8 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor); break; - case InitializedEntity::EK_Member: { + case InitializedEntity::EK_Member: + case InitializedEntity::EK_ParenAggInitMember: { const FieldDecl *Field = cast(Entity.getDecl()); PD = PDiag(diag::err_access_field_ctor); PD << Field->getType() << getSpecialMember(Constructor); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 051fad04219f..0fbef1cc8b52 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8693,7 +8693,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { } // Check that SVE types are only used in functions with SVE available. - if (T->isSVESizelessBuiltinType() && CurContext->isFunctionOrMethod()) { + if (T->isSVESizelessBuiltinType() && isa(CurContext)) { const FunctionDecl *FD = cast(CurContext); llvm::StringMap CallerFeatureMap; Context.getFunctionFeatureMap(CallerFeatureMap, FD); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2842add2cc4a..9d865f487098 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -17805,6 +17805,7 @@ static void EvaluateAndDiagnoseImmediateInvocation( bool Result = CE->EvaluateAsConstantExpr( Eval, SemaRef.getASTContext(), ConstantExprKind::ImmediateInvocation); if (!Result || !Notes.empty()) { + SemaRef.FailedImmediateInvocations.insert(CE); Expr *InnerExpr = CE->getSubExpr()->IgnoreImplicit(); if (auto *FunctionalCast = dyn_cast(InnerExpr)) InnerExpr = FunctionalCast->getSubExpr(); @@ -17849,10 +17850,16 @@ static void RemoveNestedImmediateInvocation( [E](Sema::ImmediateInvocationCandidate Elem) { return Elem.getPointer() == E; }); - assert(It != IISet.rend() && - "ConstantExpr marked IsImmediateInvocation should " - "be present"); - It->setInt(1); // Mark as deleted + // It is possible that some subexpression of the current immediate + // invocation was handled from another expression evaluation context. Do + // not handle the current immediate invocation if some of its + // subexpressions failed before. + if (It == IISet.rend()) { + if (SemaRef.FailedImmediateInvocations.contains(E)) + CurrentII->setInt(1); + } else { + It->setInt(1); // Mark as deleted + } } ExprResult TransformConstantExpr(ConstantExpr *E) { if (!E->isImmediateInvocation()) @@ -17925,10 +17932,13 @@ HandleImmediateInvocations(Sema &SemaRef, SemaRef.RebuildingImmediateInvocation) return; - /// When we have more then 1 ImmediateInvocationCandidates we need to check - /// for nested ImmediateInvocationCandidates. when we have only 1 we only - /// need to remove ReferenceToConsteval in the immediate invocation. - if (Rec.ImmediateInvocationCandidates.size() > 1) { + /// When we have more than 1 ImmediateInvocationCandidates or previously + /// failed immediate invocations, we need to check for nested + /// ImmediateInvocationCandidates in order to avoid duplicate diagnostics. + /// Otherwise we only need to remove ReferenceToConsteval in the immediate + /// invocation. + if (Rec.ImmediateInvocationCandidates.size() > 1 || + !SemaRef.FailedImmediateInvocations.empty()) { /// Prevent sema calls during the tree transform from adding pointers that /// are already in the sets. diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 44adb167dcc0..cc8d1405ec55 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1152,6 +1152,7 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity, case InitializedEntity::EK_Parameter_CF_Audited: case InitializedEntity::EK_TemplateParameter: case InitializedEntity::EK_Result: + case InitializedEntity::EK_ParenAggInitMember: // Extra braces here are suspicious. DiagID = diag::warn_braces_around_init; break; @@ -3348,6 +3349,7 @@ DeclarationName InitializedEntity::getName() const { case EK_Variable: case EK_Member: + case EK_ParenAggInitMember: case EK_Binding: case EK_TemplateParameter: return Variable.VariableOrMember->getDeclName(); @@ -3379,6 +3381,7 @@ ValueDecl *InitializedEntity::getDecl() const { switch (getKind()) { case EK_Variable: case EK_Member: + case EK_ParenAggInitMember: case EK_Binding: case EK_TemplateParameter: return Variable.VariableOrMember; @@ -3420,6 +3423,7 @@ bool InitializedEntity::allowsNRVO() const { case EK_Parameter_CF_Audited: case EK_TemplateParameter: case EK_Member: + case EK_ParenAggInitMember: case EK_Binding: case EK_New: case EK_Temporary: @@ -3454,7 +3458,10 @@ unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const { case EK_Result: OS << "Result"; break; case EK_StmtExprResult: OS << "StmtExprResult"; break; case EK_Exception: OS << "Exception"; break; - case EK_Member: OS << "Member"; break; + case EK_Member: + case EK_ParenAggInitMember: + OS << "Member"; + break; case EK_Binding: OS << "Binding"; break; case EK_New: OS << "New"; break; case EK_Temporary: OS << "Temporary"; break; @@ -5274,179 +5281,224 @@ static void TryOrBuildParenListInitialization( Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, ArrayRef Args, InitializationSequence &Sequence, bool VerifyOnly, ExprResult *Result = nullptr) { - unsigned ArgIndexToProcess = 0; + unsigned EntityIndexToProcess = 0; SmallVector InitExprs; QualType ResultType; Expr *ArrayFiller = nullptr; FieldDecl *InitializedFieldInUnion = nullptr; - // Process entities (i.e. array members, base classes, or class fields) by - // adding an initialization expression to InitExprs for each entity to - // initialize. - auto ProcessEntities = [&](auto Range) -> bool { - bool IsUnionType = Entity.getType()->isUnionType(); - for (InitializedEntity SubEntity : Range) { - // Unions should only have one initializer expression. - // If there are more initializers than it will be caught when we check - // whether Index equals Args.size(). - if (ArgIndexToProcess == 1 && IsUnionType) - return true; + auto HandleInitializedEntity = [&](const InitializedEntity &SubEntity, + const InitializationKind &SubKind, + Expr *Arg, Expr **InitExpr = nullptr) { + InitializationSequence IS = [&]() { + if (Arg) + return InitializationSequence(S, SubEntity, SubKind, Arg); + return InitializationSequence(S, SubEntity, SubKind, std::nullopt); + }(); - bool IsMember = SubEntity.getKind() == InitializedEntity::EK_Member; - - // Unnamed bitfields should not be initialized at all, either with an arg - // or by default. - if (IsMember && cast(SubEntity.getDecl())->isUnnamedBitfield()) - continue; - - if (ArgIndexToProcess < Args.size()) { - // There are still expressions in Args that haven't been processed. - // Let's match them to the current entity to initialize. - Expr *E = Args[ArgIndexToProcess++]; - - // Incomplete array types indicate flexible array members. Do not allow - // paren list initializations of structs with these members, as GCC - // doesn't either. - if (IsMember) { - auto *FD = cast(SubEntity.getDecl()); - if (FD->getType()->isIncompleteArrayType()) { - if (!VerifyOnly) { - S.Diag(E->getBeginLoc(), diag::err_flexible_array_init) - << SourceRange(E->getBeginLoc(), E->getEndLoc()); - S.Diag(FD->getLocation(), diag::note_flexible_array_member) << FD; - } - Sequence.SetFailed( - InitializationSequence::FK_ParenthesizedListInitFailed); - return false; - } - } - - InitializationKind SubKind = InitializationKind::CreateForInit( - E->getExprLoc(), /*isDirectInit=*/false, E); - InitializationSequence SubSeq(S, SubEntity, SubKind, E); - - if (SubSeq.Failed()) { - if (!VerifyOnly) - SubSeq.Diagnose(S, SubEntity, SubKind, E); - else - Sequence.SetFailed( - InitializationSequence::FK_ParenthesizedListInitFailed); - - return false; - } - if (!VerifyOnly) { - ExprResult ER = SubSeq.Perform(S, SubEntity, SubKind, E); - InitExprs.push_back(ER.get()); - if (IsMember && IsUnionType) - InitializedFieldInUnion = cast(SubEntity.getDecl()); - } + if (IS.Failed()) { + if (!VerifyOnly) { + if (Arg) + IS.Diagnose(S, SubEntity, SubKind, Arg); + else + IS.Diagnose(S, SubEntity, SubKind, std::nullopt); } else { - // We've processed all of the args, but there are still entities that - // have to be initialized. - if (IsMember) { - // C++ [dcl.init]p17.6.2.2 - // The remaining elements are initialized with their default member - // initializers, if any - auto *FD = cast(SubEntity.getDecl()); - if (FD->hasInClassInitializer()) { - if (!VerifyOnly) { - ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD); - if (DIE.isInvalid()) - return false; - S.checkInitializerLifetime(SubEntity, DIE.get()); - InitExprs.push_back(DIE.get()); - } - continue; - } - } - // Remaining class elements without default member initializers and - // array elements are value initialized: - // - // C++ [dcl.init]p17.6.2.2 - // The remaining elements...otherwise are value initialzed - // - // C++ [dcl.init]p17.5 - // if the destination type is an array, the object is initialized as - // . follows. Let x1, . . . , xk be the elements of the expression-list - // ...Let n denote the array size...the ith array element is...value- - // initialized for each k < i <= n. - InitializationKind SubKind = InitializationKind::CreateValue( - Kind.getLocation(), Kind.getLocation(), Kind.getLocation(), true); - InitializationSequence SubSeq(S, SubEntity, SubKind, std::nullopt); - if (SubSeq.Failed()) { - if (!VerifyOnly) - SubSeq.Diagnose(S, SubEntity, SubKind, std::nullopt); - return false; - } - if (!VerifyOnly) { - ExprResult ER = SubSeq.Perform(S, SubEntity, SubKind, std::nullopt); - if (SubEntity.getKind() == InitializedEntity::EK_ArrayElement) { - ArrayFiller = ER.get(); - return true; - } - InitExprs.push_back(ER.get()); - } + Sequence.SetFailed( + InitializationSequence::FK_ParenthesizedListInitFailed); } + + return false; + } + if (!VerifyOnly) { + ExprResult ER; + if (Arg) + ER = IS.Perform(S, SubEntity, SubKind, Arg); + else + ER = IS.Perform(S, SubEntity, SubKind, std::nullopt); + if (InitExpr) + *InitExpr = ER.get(); + else + InitExprs.push_back(ER.get()); } return true; }; if (const ArrayType *AT = S.getASTContext().getAsArrayType(Entity.getType())) { - SmallVector ElementEntities; uint64_t ArrayLength; - // C++ [dcl.init]p17.5 + // C++ [dcl.init]p16.5 // if the destination type is an array, the object is initialized as // follows. Let x1, . . . , xk be the elements of the expression-list. If - // the destination type is an array of unknown bound, it is define as + // the destination type is an array of unknown bound, it is defined as // having k elements. if (const ConstantArrayType *CAT = - S.getASTContext().getAsConstantArrayType(Entity.getType())) + S.getASTContext().getAsConstantArrayType(Entity.getType())) { ArrayLength = CAT->getSize().getZExtValue(); - else + ResultType = Entity.getType(); + } else if (const VariableArrayType *VAT = + S.getASTContext().getAsVariableArrayType(Entity.getType())) { + // Braced-initialization of variable array types is not allowed, even if + // the size is greater than or equal to the number of args, so we don't + // allow them to be initialized via parenthesized aggregate initialization + // either. + const Expr *SE = VAT->getSizeExpr(); + S.Diag(SE->getBeginLoc(), diag::err_variable_object_no_init) + << SE->getSourceRange(); + return; + } else { + assert(isa(Entity.getType())); ArrayLength = Args.size(); + } + EntityIndexToProcess = ArrayLength; - if (ArrayLength >= Args.size()) { - for (uint64_t I = 0; I < ArrayLength; ++I) - ElementEntities.push_back( - InitializedEntity::InitializeElement(S.getASTContext(), I, Entity)); - - if (!ProcessEntities(ElementEntities)) + // ...the ith array element is copy-initialized with xi for each + // 1 <= i <= k + for (Expr *E : Args) { + InitializedEntity SubEntity = InitializedEntity::InitializeElement( + S.getASTContext(), EntityIndexToProcess, Entity); + InitializationKind SubKind = InitializationKind::CreateForInit( + E->getExprLoc(), /*isDirectInit=*/false, E); + if (!HandleInitializedEntity(SubEntity, SubKind, E)) return; + } + // ...and value-initialized for each k < i <= n; + if (ArrayLength > Args.size()) { + InitializedEntity SubEntity = InitializedEntity::InitializeElement( + S.getASTContext(), Args.size(), Entity); + InitializationKind SubKind = InitializationKind::CreateValue( + Kind.getLocation(), Kind.getLocation(), Kind.getLocation(), true); + if (!HandleInitializedEntity(SubEntity, SubKind, nullptr, &ArrayFiller)) + return; + } + if (ResultType.isNull()) { ResultType = S.Context.getConstantArrayType( AT->getElementType(), llvm::APInt(/*numBits=*/32, ArrayLength), - nullptr, ArrayType::Normal, 0); + /*SizeExpr=*/nullptr, ArrayType::Normal, 0); } } else if (auto *RT = Entity.getType()->getAs()) { + bool IsUnion = RT->isUnionType(); const CXXRecordDecl *RD = cast(RT->getDecl()); - auto BaseRange = map_range(RD->bases(), [&](auto &base) { - return InitializedEntity::InitializeBase(S.getASTContext(), &base, false, - &Entity); - }); - auto FieldRange = map_range(RD->fields(), [](auto *field) { - return InitializedEntity::InitializeMember(field); - }); + if (!IsUnion) { + for (const CXXBaseSpecifier &Base : RD->bases()) { + InitializedEntity SubEntity = InitializedEntity::InitializeBase( + S.getASTContext(), &Base, false, &Entity); + if (EntityIndexToProcess < Args.size()) { + // C++ [dcl.init]p16.6.2.2. + // ...the object is initialized is follows. Let e1, ..., en be the + // elements of the aggregate([dcl.init.aggr]). Let x1, ..., xk be + // the elements of the expression-list...The element ei is + // copy-initialized with xi for 1 <= i <= k. + Expr *E = Args[EntityIndexToProcess]; + InitializationKind SubKind = InitializationKind::CreateForInit( + E->getExprLoc(), /*isDirectInit=*/false, E); + if (!HandleInitializedEntity(SubEntity, SubKind, E)) + return; + } else { + // We've processed all of the args, but there are still base classes + // that have to be initialized. + // C++ [dcl.init]p17.6.2.2 + // The remaining elements...otherwise are value initialzed + InitializationKind SubKind = InitializationKind::CreateValue( + Kind.getLocation(), Kind.getLocation(), Kind.getLocation(), + /*IsImplicit=*/true); + if (!HandleInitializedEntity(SubEntity, SubKind, nullptr)) + return; + } + EntityIndexToProcess++; + } + } - if (!ProcessEntities(BaseRange)) - return; + for (FieldDecl *FD : RD->fields()) { + // Unnamed bitfields should not be initialized at all, either with an arg + // or by default. + if (FD->isUnnamedBitfield()) + continue; - if (!ProcessEntities(FieldRange)) - return; + InitializedEntity SubEntity = + InitializedEntity::InitializeMemberFromParenAggInit(FD); + if (EntityIndexToProcess < Args.size()) { + // ...The element ei is copy-initialized with xi for 1 <= i <= k. + Expr *E = Args[EntityIndexToProcess]; + + // Incomplete array types indicate flexible array members. Do not allow + // paren list initializations of structs with these members, as GCC + // doesn't either. + if (FD->getType()->isIncompleteArrayType()) { + if (!VerifyOnly) { + S.Diag(E->getBeginLoc(), diag::err_flexible_array_init) + << SourceRange(E->getBeginLoc(), E->getEndLoc()); + S.Diag(FD->getLocation(), diag::note_flexible_array_member) << FD; + } + Sequence.SetFailed( + InitializationSequence::FK_ParenthesizedListInitFailed); + return; + } + + InitializationKind SubKind = InitializationKind::CreateForInit( + E->getExprLoc(), /*isDirectInit=*/false, E); + if (!HandleInitializedEntity(SubEntity, SubKind, E)) + return; + + // Unions should have only one initializer expression, so we bail out + // after processing the first field. If there are more initializers then + // it will be caught when we later check whether EntityIndexToProcess is + // less than Args.size(); + if (IsUnion) { + InitializedFieldInUnion = FD; + EntityIndexToProcess = 1; + break; + } + } else { + // We've processed all of the args, but there are still members that + // have to be initialized. + if (FD->hasInClassInitializer()) { + if (!VerifyOnly) { + // C++ [dcl.init]p16.6.2.2 + // The remaining elements are initialized with their default + // member initializers, if any + ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD); + if (DIE.isInvalid()) + return; + S.checkInitializerLifetime(SubEntity, DIE.get()); + InitExprs.push_back(DIE.get()); + } + } else { + // C++ [dcl.init]p17.6.2.2 + // The remaining elements...otherwise are value initialzed + if (FD->getType()->isReferenceType()) { + Sequence.SetFailed( + InitializationSequence::FK_ParenthesizedListInitFailed); + if (!VerifyOnly) { + SourceRange SR = Kind.getParenOrBraceRange(); + S.Diag(SR.getEnd(), diag::err_init_reference_member_uninitialized) + << FD->getType() << SR; + S.Diag(FD->getLocation(), diag::note_uninit_reference_member); + } + return; + } + InitializationKind SubKind = InitializationKind::CreateValue( + Kind.getLocation(), Kind.getLocation(), Kind.getLocation(), true); + if (!HandleInitializedEntity(SubEntity, SubKind, nullptr)) + return; + } + } + EntityIndexToProcess++; + } ResultType = Entity.getType(); } // Not all of the args have been processed, so there must've been more args - // then were required to initialize the element. - if (ArgIndexToProcess < Args.size()) { + // than were required to initialize the element. + if (EntityIndexToProcess < Args.size()) { Sequence.SetFailed(InitializationSequence::FK_ParenthesizedListInitFailed); if (!VerifyOnly) { QualType T = Entity.getType(); int InitKind = T->isArrayType() ? 0 : T->isUnionType() ? 3 : 4; - SourceRange ExcessInitSR(Args[ArgIndexToProcess]->getBeginLoc(), + SourceRange ExcessInitSR(Args[EntityIndexToProcess]->getBeginLoc(), Args.back()->getEndLoc()); S.Diag(Kind.getLocation(), diag::err_excess_initializers) << InitKind << ExcessInitSR; @@ -6412,6 +6464,7 @@ getAssignmentAction(const InitializedEntity &Entity, bool Diagnose = false) { return Sema::AA_Converting; case InitializedEntity::EK_Member: + case InitializedEntity::EK_ParenAggInitMember: case InitializedEntity::EK_Binding: case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_VectorElement: @@ -6432,6 +6485,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) { switch (Entity.getKind()) { case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_Member: + case InitializedEntity::EK_ParenAggInitMember: case InitializedEntity::EK_Result: case InitializedEntity::EK_StmtExprResult: case InitializedEntity::EK_New: @@ -6476,6 +6530,7 @@ static bool shouldDestroyEntity(const InitializedEntity &Entity) { return false; case InitializedEntity::EK_Member: + case InitializedEntity::EK_ParenAggInitMember: case InitializedEntity::EK_Binding: case InitializedEntity::EK_Variable: case InitializedEntity::EK_Parameter: @@ -6512,6 +6567,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity, case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_Member: + case InitializedEntity::EK_ParenAggInitMember: case InitializedEntity::EK_Parameter: case InitializedEntity::EK_Parameter_CF_Audited: case InitializedEntity::EK_TemplateParameter: @@ -7080,7 +7136,15 @@ static LifetimeResult getEntityLifetime( case InitializedEntity::EK_Exception: // FIXME: Can we diagnose lifetime problems with exceptions? return {nullptr, LK_FullExpression}; + + case InitializedEntity::EK_ParenAggInitMember: + // -- A temporary object bound to a reference element of an aggregate of + // class type initialized from a parenthesized expression-list + // [dcl.init, 9.3] persists until the completion of the full-expression + // containing the expression-list. + return {nullptr, LK_FullExpression}; } + llvm_unreachable("unknown entity kind"); } @@ -9196,7 +9260,9 @@ ExprResult InitializationSequence::Perform(Sema &S, S.checkInitializerLifetime(Entity, Init); // Diagnose non-fatal problems with the completed initialization. - if (Entity.getKind() == InitializedEntity::EK_Member && + if (InitializedEntity::EntityKind EK = Entity.getKind(); + (EK == InitializedEntity::EK_Member || + EK == InitializedEntity::EK_ParenAggInitMember) && cast(Entity.getDecl())->isBitField()) S.CheckBitFieldInitialization(Kind.getLocation(), cast(Entity.getDecl()), @@ -9650,7 +9716,8 @@ bool InitializationSequence::Diagnose(Sema &S, case OR_No_Viable_Function: if (Kind.getKind() == InitializationKind::IK_Default && (Entity.getKind() == InitializedEntity::EK_Base || - Entity.getKind() == InitializedEntity::EK_Member) && + Entity.getKind() == InitializedEntity::EK_Member || + Entity.getKind() == InitializedEntity::EK_ParenAggInitMember) && isa(S.CurContext)) { // This is implicit default initialization of a member or // base within a constructor. If no viable function was diff --git a/libcxx/include/__config b/libcxx/include/__config index 9009b9014abb..d7ba71906e26 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -38,7 +38,7 @@ // _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM. // Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 16.0.1 == 16.00.01), _LIBCPP_VERSION is // defined to XXYYZZ. -# define _LIBCPP_VERSION 160004 +# define _LIBCPP_VERSION 160005 # define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y # define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y) diff --git a/lld/docs/WebAssembly.rst b/lld/docs/WebAssembly.rst index c40d4b322080..dad3177e2c7d 100644 --- a/lld/docs/WebAssembly.rst +++ b/lld/docs/WebAssembly.rst @@ -75,6 +75,11 @@ WebAssembly-specific options: flag which corresponds to ``--unresolve-symbols=ignore`` + ``--import-undefined``. +.. option:: --allow-undefined-file= + + Like ``--allow-undefined``, but the filename specified a flat list of + symbols, one per line, which are allowed to be undefined. + .. option:: --unresolved-symbols= This is a more full featured version of ``--allow-undefined``. @@ -182,11 +187,39 @@ Imports By default no undefined symbols are allowed in the final binary. The flag ``--allow-undefined`` results in a WebAssembly import being defined for each undefined symbol. It is then up to the runtime to provide such symbols. +``--allow-undefined-file`` is the same but allows a list of symbols to be +specified. Alternatively symbols can be marked in the source code as with the ``import_name`` and/or ``import_module`` clang attributes which signals that they are expected to be undefined at static link time. +Stub Libraries +~~~~~~~~~~~~~~ + +Another way to specify imports and exports is via a "stub library". This +feature is inspired by the ELF stub objects which are supported by the Solaris +linker. Stub libraries are text files that can be passed as normal linker +inputs, similar to how linker scripts can be passed to the ELF linker. The stub +library is a stand-in for a set of symbols that will be available at runtime, +but doesn't contain any actual code or data. Instead it contains just a list of +symbols, one per line. Each symbol can specify zero or more dependencies. +These dependencies are symbols that must be defined, and exported, by the output +module if the symbol is question is imported/required by the output module. + +For example, imagine the runtime provides an external symbol ``foo`` that +depends on the ``malloc`` and ``free``. This can be expressed simply as:: + + #STUB + foo: malloc,free + +Here we are saying that ``foo`` is allowed to be imported (undefined) but that +if it is imported, then the output module must also export ``malloc`` and +``free`` to the runtime. If ``foo`` is imported (undefined), but the output +module does not define ``malloc`` and ``free`` then the link will fail. + +Stub libraries must begin with ``#STUB`` on a line by itself. + Garbage Collection ~~~~~~~~~~~~~~~~~~ diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h index 953e15e358f1..8ac6e7dac63e 100644 --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -116,6 +116,15 @@ class AliasResult { operator Kind() const { return static_cast(Alias); } + bool operator==(const AliasResult &Other) const { + return Alias == Other.Alias && HasOffset == Other.HasOffset && + Offset == Other.Offset; + } + bool operator!=(const AliasResult &Other) const { return !(*this == Other); } + + bool operator==(Kind K) const { return Alias == K; } + bool operator!=(Kind K) const { return !(*this == K); } + constexpr bool hasOffset() const { return HasOffset; } constexpr int32_t getOffset() const { assert(HasOffset && "No offset!"); diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h index 8fcfbdbd6665..951945f7b765 100644 --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h @@ -408,14 +408,14 @@ class TargetLibraryInfo { ShouldExtI32Param = true; ShouldExtI32Return = true; } - // Mips and riscv64, on the other hand, needs signext on i32 parameters - // corresponding to both signed and unsigned ints. - if (T.isMIPS() || T.isRISCV64()) { + // LoongArch, Mips, and riscv64, on the other hand, need signext on i32 + // parameters corresponding to both signed and unsigned ints. + if (T.isLoongArch() || T.isMIPS() || T.isRISCV64()) { ShouldSignExtI32Param = true; } - // riscv64 needs signext on i32 returns corresponding to both signed and - // unsigned ints. - if (T.isRISCV64()) { + // LoongArch and riscv64 need signext on i32 returns corresponding to both + // signed and unsigned ints. + if (T.isLoongArch() || T.isRISCV64()) { ShouldSignExtI32Return = true; } } diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 202fc473f9e4..609a383426d6 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -1628,7 +1628,7 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, ISD::UADDO, ISD::SSUBO, ISD::USUBO, ISD::SMUL_LOHI, ISD::UMUL_LOHI, // Logical/bit: ISD::AND, ISD::OR, ISD::XOR, ISD::ROTL, ISD::ROTR, - ISD::CTPOP, ISD::CTLZ, ISD::CTTZ, + ISD::CTPOP, ISD::CTLZ, ISD::CTTZ, ISD::BSWAP, ISD::BITREVERSE, // Floating point arithmetic/math functions: ISD::FADD, ISD::FSUB, ISD::FMUL, ISD::FMA, ISD::FDIV, ISD::FREM, ISD::FNEG, ISD::FABS, ISD::FSQRT, ISD::FSIN, @@ -1701,8 +1701,11 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setOperationAction(ISD::OR, NativeVT, Legal); setOperationAction(ISD::XOR, NativeVT, Legal); - if (NativeVT.getVectorElementType() != MVT::i1) + if (NativeVT.getVectorElementType() != MVT::i1) { setOperationAction(ISD::SPLAT_VECTOR, NativeVT, Legal); + setOperationAction(ISD::BSWAP, NativeVT, Legal); + setOperationAction(ISD::BITREVERSE, NativeVT, Legal); + } } for (MVT VT : {MVT::v8i8, MVT::v4i16, MVT::v2i32}) { diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td index a75ac0e1378e..375e519a6848 100644 --- a/llvm/lib/Target/Hexagon/HexagonPatterns.td +++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td @@ -117,8 +117,8 @@ def usat: PatFrag<(ops node:$V, node:$Ty), (HexagonUSAT node:$V, node:$Ty)>; // Pattern fragments to extract the low and high subregisters from a // 64-bit value. -def LoReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_lo)>; -def HiReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_hi)>; +def LoReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG $Rs, isub_lo)>; +def HiReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG $Rs, isub_hi)>; def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{ return isOrEquivalentToAdd(N); @@ -1123,6 +1123,12 @@ def: Pat<(bswap I32:$Rs), (A2_swiz I32:$Rs)>; def: Pat<(bswap I64:$Rss), (Combinew (A2_swiz (LoReg $Rss)), (A2_swiz (HiReg $Rss)))>; +def: Pat<(bswap V2I16:$Rs), (A2_combine_lh (A2_swiz $Rs), (A2_swiz $Rs))>; +def: Pat<(bswap V2I32:$Rs), (Combinew (A2_swiz (HiReg $Rs)), + (A2_swiz (LoReg $Rs)))>; +def: Pat<(bswap V4I16:$Rs), (A2_orp (S2_lsr_i_vh $Rs, 8), + (S2_asl_i_vh $Rs, 8))>; + def: Pat<(shl s6_0ImmPred:$s6, I32:$Rt), (S4_lsli imm:$s6, I32:$Rt)>; def: Pat<(shl I32:$Rs, (i32 16)), (A2_aslh I32:$Rs)>; def: Pat<(sra I32:$Rs, (i32 16)), (A2_asrh I32:$Rs)>; @@ -1854,6 +1860,20 @@ def: Pat<(i32 (ctpop I32:$Rs)), (S5_popcountp (A4_combineir 0, I32:$Rs))>; def: Pat<(bitreverse I32:$Rs), (S2_brev I32:$Rs)>; def: Pat<(bitreverse I64:$Rss), (S2_brevp I64:$Rss)>; +def: Pat<(bitreverse V4I8:$Rs), (A2_swiz (S2_brev $Rs))>; +def: Pat<(bitreverse V8I8:$Rs), (Combinew (A2_swiz (LoReg (S2_brevp $Rs))), + (A2_swiz (HiReg (S2_brevp $Rs))))>; +def: Pat<(bitreverse V2I16:$Rs), (A2_combine_lh (S2_brev $Rs), + (S2_brev $Rs))>; +def: Pat<(bitreverse V4I16:$Rs), + (Combinew (A2_combine_lh (LoReg (S2_brevp $Rs)), + (LoReg (S2_brevp $Rs))), + (A2_combine_lh (HiReg (S2_brevp $Rs)), + (HiReg (S2_brevp $Rs))))>; +def: Pat<(bitreverse V2I32:$Rs), + (Combinew (i32 (LoReg (S2_brevp $Rs))), + (i32 (HiReg (S2_brevp $Rs))))>; + let AddedComplexity = 20 in { // Complexity greater than and/or/xor def: Pat<(and I32:$Rs, IsNPow2_32:$V), (S2_clrbit_i IntRegs:$Rs, (LogN2_32 $V))>; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index cf17c51b04fc..e43b33eed470 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -499,7 +499,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, } if (Subtarget.hasSSEPrefetch() || Subtarget.hasThreeDNow()) - setOperationAction(ISD::PREFETCH , MVT::Other, Legal); + setOperationAction(ISD::PREFETCH , MVT::Other, Custom); setOperationAction(ISD::ATOMIC_FENCE , MVT::Other, Custom); @@ -2195,6 +2195,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::FMUL, VT, Expand); setOperationAction(ISD::FDIV, VT, Expand); setOperationAction(ISD::BUILD_VECTOR, VT, Custom); + setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom); } addLegalFPImmediate(APFloat::getZero(APFloat::BFloat())); } @@ -2207,6 +2208,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::FMUL, MVT::v32bf16, Expand); setOperationAction(ISD::FDIV, MVT::v32bf16, Expand); setOperationAction(ISD::BUILD_VECTOR, MVT::v32bf16, Custom); + setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v32bf16, Custom); } if (!Subtarget.useSoftFloat() && Subtarget.hasVLX()) { @@ -18773,11 +18775,11 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef Mask, MVT VT, return DAG.getBitcast(VT, DAG.getVectorShuffle(FpVT, DL, V1, V2, Mask)); } - if (VT == MVT::v16f16) { - V1 = DAG.getBitcast(MVT::v16i16, V1); - V2 = DAG.getBitcast(MVT::v16i16, V2); - return DAG.getBitcast(MVT::v16f16, - DAG.getVectorShuffle(MVT::v16i16, DL, V1, V2, Mask)); + if (VT == MVT::v16f16 || VT.getVectorElementType() == MVT::bf16) { + MVT IVT = VT.changeVectorElementTypeToInteger(); + V1 = DAG.getBitcast(IVT, V1); + V2 = DAG.getBitcast(IVT, V2); + return DAG.getBitcast(VT, DAG.getVectorShuffle(IVT, DL, V1, V2, Mask)); } switch (VT.SimpleTy) { @@ -33093,6 +33095,18 @@ static SDValue LowerCVTPS2PH(SDValue Op, SelectionDAG &DAG) { return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lo, Hi); } +static SDValue LowerPREFETCH(SDValue Op, const X86Subtarget &Subtarget, + SelectionDAG &DAG) { + unsigned IsData = cast(Op.getOperand(4))->getZExtValue(); + + // We don't support non-data prefetch without PREFETCHI. + // Just preserve the chain. + if (!IsData && !Subtarget.hasPREFETCHI()) + return Op.getOperand(0); + + return Op; +} + static StringRef getInstrStrFromOpNo(const SmallVectorImpl &AsmStrs, unsigned OpNo) { const APInt Operand(32, OpNo); @@ -33294,6 +33308,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::GC_TRANSITION_END: return LowerGC_TRANSITION(Op, DAG); case ISD::ADDRSPACECAST: return LowerADDRSPACECAST(Op, DAG); case X86ISD::CVTPS2PH: return LowerCVTPS2PH(Op, DAG); + case ISD::PREFETCH: return LowerPREFETCH(Op, Subtarget, DAG); } } diff --git a/llvm/lib/Target/X86/X86InstrAVX512.td b/llvm/lib/Target/X86/X86InstrAVX512.td index 6da4dd2b942c..888e69ac4ac0 100644 --- a/llvm/lib/Target/X86/X86InstrAVX512.td +++ b/llvm/lib/Target/X86/X86InstrAVX512.td @@ -12969,6 +12969,27 @@ let Predicates = [HasBF16, HasVLX] in { (VCVTNEPS2BF16Z256rr VR256X:$src)>; def : Pat<(v8bf16 (int_x86_vcvtneps2bf16256 (loadv8f32 addr:$src))), (VCVTNEPS2BF16Z256rm addr:$src)>; + + def : Pat<(v8bf16 (X86VBroadcastld16 addr:$src)), + (VPBROADCASTWZ128rm addr:$src)>; + def : Pat<(v16bf16 (X86VBroadcastld16 addr:$src)), + (VPBROADCASTWZ256rm addr:$src)>; + + def : Pat<(v8bf16 (X86VBroadcast (v8bf16 VR128X:$src))), + (VPBROADCASTWZ128rr VR128X:$src)>; + def : Pat<(v16bf16 (X86VBroadcast (v8bf16 VR128X:$src))), + (VPBROADCASTWZ256rr VR128X:$src)>; + + // TODO: No scalar broadcast due to we don't support legal scalar bf16 so far. +} + +let Predicates = [HasBF16] in { + def : Pat<(v32bf16 (X86VBroadcastld16 addr:$src)), + (VPBROADCASTWZrm addr:$src)>; + + def : Pat<(v32bf16 (X86VBroadcast (v8bf16 VR128X:$src))), + (VPBROADCASTWZrr VR128X:$src)>; + // TODO: No scalar broadcast due to we don't support legal scalar bf16 so far. } let Constraints = "$src1 = $dst" in { diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp index 73c341891ab7..33adf15fccaf 100644 --- a/llvm/tools/llvm-mca/llvm-mca.cpp +++ b/llvm/tools/llvm-mca/llvm-mca.cpp @@ -401,11 +401,6 @@ int main(int argc, char **argv) { // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(std::move(*BufferPtr), SMLoc()); - MCContext Ctx(TheTriple, MAI.get(), MRI.get(), STI.get(), &SrcMgr); - std::unique_ptr MOFI( - TheTarget->createMCObjectFileInfo(Ctx, /*PIC=*/false)); - Ctx.setObjectFileInfo(MOFI.get()); - std::unique_ptr BOS; std::unique_ptr MCII(TheTarget->createMCInstrInfo()); @@ -433,7 +428,11 @@ int main(int argc, char **argv) { } // Parse the input and create CodeRegions that llvm-mca can analyze. - mca::AsmAnalysisRegionGenerator CRG(*TheTarget, SrcMgr, Ctx, *MAI, *STI, + MCContext ACtx(TheTriple, MAI.get(), MRI.get(), STI.get(), &SrcMgr); + std::unique_ptr AMOFI( + TheTarget->createMCObjectFileInfo(ACtx, /*PIC=*/false)); + ACtx.setObjectFileInfo(AMOFI.get()); + mca::AsmAnalysisRegionGenerator CRG(*TheTarget, SrcMgr, ACtx, *MAI, *STI, *MCII); Expected RegionsOrErr = CRG.parseAnalysisRegions(std::move(IPtemp)); @@ -471,7 +470,11 @@ int main(int argc, char **argv) { // Parse the input and create InstrumentRegion that llvm-mca // can use to improve analysis. - mca::AsmInstrumentRegionGenerator IRG(*TheTarget, SrcMgr, Ctx, *MAI, *STI, + MCContext ICtx(TheTriple, MAI.get(), MRI.get(), STI.get(), &SrcMgr); + std::unique_ptr IMOFI( + TheTarget->createMCObjectFileInfo(ICtx, /*PIC=*/false)); + ICtx.setObjectFileInfo(IMOFI.get()); + mca::AsmInstrumentRegionGenerator IRG(*TheTarget, SrcMgr, ICtx, *MAI, *STI, *MCII, *IM); Expected InstrumentRegionsOrErr = IRG.parseInstrumentRegions(std::move(IPtemp)); @@ -547,7 +550,7 @@ int main(int argc, char **argv) { unsigned RegionIdx = 0; std::unique_ptr MCE( - TheTarget->createMCCodeEmitter(*MCII, Ctx)); + TheTarget->createMCCodeEmitter(*MCII, ACtx)); assert(MCE && "Unable to create code emitter!"); std::unique_ptr MAB(TheTarget->createMCAsmBackend(