From 7f04c68256951282ce8e0136371ef97410ed7db6 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 15 Oct 2022 17:58:31 +0200 Subject: [PATCH 1/3] Vendor import of llvm-project branch release/15.x llvmorg-15.0.1-0-gb73d2c8c720a. --- .../clang/Basic/DiagnosticSemaKinds.td | 8 ++-- clang/lib/CodeGen/CoverageMappingGen.cpp | 32 +++++++------ .../InterpolatingCompilationDatabase.cpp | 4 +- libcxx/include/__config | 2 +- libcxx/include/atomic | 46 ++++--------------- libcxx/include/version | 2 +- lld/COFF/Symbols.h | 5 +- lld/COFF/Writer.cpp | 2 +- lld/MachO/InputFiles.cpp | 9 ++++ lld/MachO/UnwindInfoSection.cpp | 45 +++++++++++++----- llvm/include/llvm/Object/ELF.h | 2 +- llvm/lib/CodeGen/DwarfEHPrepare.cpp | 8 ++++ llvm/lib/CodeGen/PrologEpilogInserter.cpp | 7 +-- .../Transforms/Vectorize/LoopVectorize.cpp | 14 ++++-- llvm/lib/Transforms/Vectorize/VPlan.cpp | 2 +- llvm/lib/Transforms/Vectorize/VPlan.h | 10 ++-- .../lib/Transforms/Vectorize/VPlanRecipes.cpp | 7 +-- llvm/tools/llvm-objdump/ELFDump.cpp | 39 ++++++++-------- 18 files changed, 136 insertions(+), 108 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6ff5b8de57fd..cb460401eb47 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -419,7 +419,7 @@ def warn_implicit_function_decl : Warning< InGroup, DefaultIgnore; def ext_implicit_function_decl_c99 : ExtWarn< "call to undeclared function %0; ISO C99 and later do not support implicit " - "function declarations">, InGroup, DefaultError; + "function declarations">, InGroup; def note_function_suggestion : Note<"did you mean %0?">; def err_ellipsis_first_param : Error< @@ -705,7 +705,7 @@ def ext_implicit_lib_function_decl : ExtWarn< def ext_implicit_lib_function_decl_c99 : ExtWarn< "call to undeclared library function '%0' with type %1; ISO C99 and later " "do not support implicit function declarations">, - InGroup, DefaultError; + InGroup; def note_include_header_or_declare : Note< "include the header <%0> or explicitly provide a declaration for '%1'">; def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">; @@ -4359,7 +4359,7 @@ def err_ident_list_in_fn_declaration : Error< "a parameter list without types is only allowed in a function definition">; def ext_param_not_declared : ExtWarn< "parameter %0 was not declared, defaults to 'int'; ISO C99 and later do not " - "support implicit int">, InGroup, DefaultError; + "support implicit int">, InGroup; def err_param_default_argument : Error< "C does not support default arguments">; def err_param_default_argument_redefinition : Error< @@ -10029,7 +10029,7 @@ def warn_receiver_forward_class : Warning< def note_method_sent_forward_class : Note<"method %0 is used for the forward class">; def ext_missing_type_specifier : ExtWarn< "type specifier missing, defaults to 'int'; ISO C99 and later do not support " - "implicit int">, InGroup, DefaultError; + "implicit int">, InGroup; def err_missing_type_specifier : Error< "a type specifier is required for all declarations">; def err_decimal_unsupported : Error< diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 0fe084b628da..836aabf80179 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1377,19 +1377,23 @@ struct CounterCoverageMappingBuilder // Extend into the condition before we propagate through it below - this is // needed to handle macros that generate the "if" but not the condition. - extendRegion(S->getCond()); + if (!S->isConsteval()) + extendRegion(S->getCond()); Counter ParentCount = getRegion().getCounter(); Counter ThenCount = getRegionCounter(S); - // Emitting a counter for the condition makes it easier to interpret the - // counter for the body when looking at the coverage. - propagateCounts(ParentCount, S->getCond()); + if (!S->isConsteval()) { + // Emitting a counter for the condition makes it easier to interpret the + // counter for the body when looking at the coverage. + propagateCounts(ParentCount, S->getCond()); - // The 'then' count applies to the area immediately after the condition. - auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getThen())); - if (Gap) - fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ThenCount); + // The 'then' count applies to the area immediately after the condition. + Optional Gap = + findGapAreaBetween(S->getRParenLoc(), getStart(S->getThen())); + if (Gap) + fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ThenCount); + } extendRegion(S->getThen()); Counter OutCount = propagateCounts(ThenCount, S->getThen()); @@ -1398,9 +1402,9 @@ struct CounterCoverageMappingBuilder if (const Stmt *Else = S->getElse()) { bool ThenHasTerminateStmt = HasTerminateStmt; HasTerminateStmt = false; - // The 'else' count applies to the area immediately after the 'then'. - Gap = findGapAreaBetween(getEnd(S->getThen()), getStart(Else)); + Optional Gap = + findGapAreaBetween(getEnd(S->getThen()), getStart(Else)); if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount); extendRegion(Else); @@ -1416,9 +1420,11 @@ struct CounterCoverageMappingBuilder GapRegionCounter = OutCount; } - // Create Branch Region around condition. - createBranchRegion(S->getCond(), ThenCount, - subtractCounters(ParentCount, ThenCount)); + if (!S->isConsteval()) { + // Create Branch Region around condition. + createBranchRegion(S->getCond(), ThenCount, + subtractCounters(ParentCount, ThenCount)); + } } void VisitCXXTryStmt(const CXXTryStmt *S) { diff --git a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp index 0143b5f8df6b..655be20572b6 100644 --- a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp @@ -165,8 +165,8 @@ struct TransferableCommand { const unsigned OldPos = Pos; std::unique_ptr Arg(OptTable.ParseOneArg( ArgList, Pos, - /* Include */ ClangCLMode ? CoreOption | CLOption : 0, - /* Exclude */ ClangCLMode ? 0 : CLOption)); + /* Include */ ClangCLMode ? CoreOption | CLOption | CLDXCOption : 0, + /* Exclude */ ClangCLMode ? 0 : CLOption | CLDXCOption)); if (!Arg) continue; diff --git a/libcxx/include/__config b/libcxx/include/__config index 8c2f7614af53..2f80df35f909 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -24,7 +24,7 @@ #ifdef __cplusplus -# define _LIBCPP_VERSION 15000 +# define _LIBCPP_VERSION 15001 # define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y # define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y) diff --git a/libcxx/include/atomic b/libcxx/include/atomic index 92da4820e928..3a93b9b0a108 100644 --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -1113,6 +1113,12 @@ _Tp kill_dependency(_Tp __y) _NOEXCEPT # define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE #endif +template +struct __libcpp_is_always_lock_free { + // __atomic_always_lock_free is available in all Standard modes + static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0); +}; + #ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS template @@ -1404,42 +1410,8 @@ _Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, return __old; } -#ifdef __cpp_lib_atomic_is_always_lock_free - -template struct __cxx_is_always_lock_free { - enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; }; - -#else - -template struct __cxx_is_always_lock_free { enum { __value = false }; }; -// Implementations must match the C ATOMIC_*_LOCK_FREE macro values. -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; }; -#ifndef _LIBCPP_HAS_NO_CHAR8_T -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; }; -#endif -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; }; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; }; -#endif -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; }; -template struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; }; - -#endif //__cpp_lib_atomic_is_always_lock_free - template ::__value, + typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value, __cxx_atomic_base_impl<_Tp>, __cxx_atomic_lock_impl<_Tp> >::type> #else @@ -1561,7 +1533,7 @@ struct __atomic_base // false mutable __cxx_atomic_impl<_Tp> __a_; #if defined(__cpp_lib_atomic_is_always_lock_free) - static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0); + static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; #endif _LIBCPP_INLINE_VISIBILITY @@ -2664,7 +2636,7 @@ typedef atomic atomic_uintmax_t; // atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type #ifdef __cpp_lib_atomic_is_always_lock_free -# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0) +# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value #else # define _LIBCPP_CONTENTION_LOCK_FREE false #endif diff --git a/libcxx/include/version b/libcxx/include/version index 8ffb1747eb27..d0c6fe466e70 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -332,7 +332,7 @@ __cpp_lib_void_t 201411L # undef __cpp_lib_execution // # define __cpp_lib_execution 201902L # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) -# define __cpp_lib_format 202106L +// # define __cpp_lib_format 202106L # endif # define __cpp_lib_generic_unordered_lookup 201811L # define __cpp_lib_int_pow2 202002L diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index c8865d128fb8..a4c6f893f10c 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -106,7 +106,10 @@ class Symbol { : symbolKind(k), isExternal(true), isCOMDAT(false), writtenToSymtab(false), pendingArchiveLoad(false), isGCRoot(false), isRuntimePseudoReloc(false), deferUndefined(false), canInline(true), - nameSize(n.size()), nameData(n.empty() ? nullptr : n.data()) {} + nameSize(n.size()), nameData(n.empty() ? nullptr : n.data()) { + assert((!n.empty() || k <= LastDefinedCOFFKind) && + "If the name is empty, the Symbol must be a DefinedCOFF."); + } const unsigned symbolKind : 8; unsigned isExternal : 1; diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index df60c9032b2d..f39697d5d381 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -395,7 +395,7 @@ getThunk(DenseMap &lastThunks, Defined *target, uint64_t p, default: llvm_unreachable("Unexpected architecture"); } - Defined *d = make("", c); + Defined *d = make("range_extension_thunk", c); lastThunk = d; return {d, true}; } diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index fd0e4ec8834c..87034d41e87d 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -1587,6 +1587,15 @@ void ObjFile::registerEhFrames(Section &ehFrameSection) { funcSym->unwindEntry = isec; ehRelocator.commit(); } + + // __eh_frame is marked as S_ATTR_LIVE_SUPPORT in input files, because FDEs + // are normally required to be kept alive if they reference a live symbol. + // However, we've explicitly created a dependency from a symbol to its FDE, so + // dead-stripping will just work as usual, and S_ATTR_LIVE_SUPPORT will only + // serve to incorrectly prevent us from dead-stripping duplicate FDEs for a + // live symbol (e.g. if there were multiple weak copies). Remove this flag to + // let dead-stripping proceed correctly. + ehFrameSection.flags &= ~S_ATTR_LIVE_SUPPORT; } std::string ObjFile::sourceFile() const { diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp index c3f563d5572b..ca6cbdfbb8bb 100644 --- a/lld/MachO/UnwindInfoSection.cpp +++ b/lld/MachO/UnwindInfoSection.cpp @@ -196,13 +196,13 @@ UnwindInfoSection::UnwindInfoSection() // Record function symbols that may need entries emitted in __unwind_info, which // stores unwind data for address ranges. // -// Note that if several adjacent functions have the same unwind encoding, LSDA, -// and personality function, they share one unwind entry. For this to work, -// functions without unwind info need explicit "no unwind info" unwind entries -// -- else the unwinder would think they have the unwind info of the closest -// function with unwind info right before in the image. Thus, we add function -// symbols for each unique address regardless of whether they have associated -// unwind info. +// Note that if several adjacent functions have the same unwind encoding and +// personality function and no LSDA, they share one unwind entry. For this to +// work, functions without unwind info need explicit "no unwind info" unwind +// entries -- else the unwinder would think they have the unwind info of the +// closest function with unwind info right before in the image. Thus, we add +// function symbols for each unique address regardless of whether they have +// associated unwind info. void UnwindInfoSection::addSymbol(const Defined *d) { if (d->unwindEntry) allEntriesAreOmitted = false; @@ -427,9 +427,9 @@ void UnwindInfoSectionImpl::finalize() { // assigned, so we can relocate the __LD,__compact_unwind entries // into a temporary buffer. Relocation is necessary in order to sort // the CU entries by function address. Sorting is necessary so that - // we can fold adjacent CU entries with identical - // encoding+personality+lsda. Folding is necessary because it reduces - // the number of CU entries by as much as 3 orders of magnitude! + // we can fold adjacent CU entries with identical encoding+personality + // and without any LSDA. Folding is necessary because it reduces the + // number of CU entries by as much as 3 orders of magnitude! cuEntries.resize(symbols.size()); // The "map" part of the symbols MapVector was only needed for deduplication // in addSymbol(). Now that we are done adding, move the contents to a plain @@ -445,7 +445,7 @@ void UnwindInfoSectionImpl::finalize() { return cuEntries[a].functionAddress < cuEntries[b].functionAddress; }); - // Fold adjacent entries with matching encoding+personality+lsda + // Fold adjacent entries with matching encoding+personality and without LSDA // We use three iterators on the same cuIndices to fold in-situ: // (1) `foldBegin` is the first of a potential sequence of matching entries // (2) `foldEnd` is the first non-matching entry after `foldBegin`. @@ -455,11 +455,32 @@ void UnwindInfoSectionImpl::finalize() { auto foldWrite = cuIndices.begin(); for (auto foldBegin = cuIndices.begin(); foldBegin < cuIndices.end();) { auto foldEnd = foldBegin; + // Common LSDA encodings (e.g. for C++ and Objective-C) contain offsets from + // a base address. The base address is normally not contained directly in + // the LSDA, and in that case, the personality function treats the starting + // address of the function (which is computed by the unwinder) as the base + // address and interprets the LSDA accordingly. The unwinder computes the + // starting address of a function as the address associated with its CU + // entry. For this reason, we cannot fold adjacent entries if they have an + // LSDA, because folding would make the unwinder compute the wrong starting + // address for the functions with the folded entries, which in turn would + // cause the personality function to misinterpret the LSDA for those + // functions. In the very rare case where the base address is encoded + // directly in the LSDA, two functions at different addresses would + // necessarily have different LSDAs, so their CU entries would not have been + // folded anyway. while (++foldEnd < cuIndices.end() && cuEntries[*foldBegin].encoding == cuEntries[*foldEnd].encoding && + !cuEntries[*foldBegin].lsda && !cuEntries[*foldEnd].lsda && + // If we've gotten to this point, we don't have an LSDA, which should + // also imply that we don't have a personality function, since in all + // likelihood a personality function needs the LSDA to do anything + // useful. It can be technically valid to have a personality function + // and no LSDA though (e.g. the C++ personality __gxx_personality_v0 + // is just a no-op without LSDA), so we still check for personality + // function equivalence to handle that case. cuEntries[*foldBegin].personality == cuEntries[*foldEnd].personality && - cuEntries[*foldBegin].lsda == cuEntries[*foldEnd].lsda && canFoldEncoding(cuEntries[*foldEnd].encoding)) ; *foldWrite++ = *foldBegin; diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index 794d29fd9913..5eb43777a951 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -1028,7 +1028,7 @@ ELFFile::getVersionDependencies(const Elf_Shdr &Sec, VN.Offset = VerneedBuf - Start; if (Verneed->vn_file < StrTab.size()) - VN.File = std::string(StrTab.drop_front(Verneed->vn_file)); + VN.File = std::string(StrTab.data() + Verneed->vn_file); else VN.File = ("vn_file) + ">").str(); diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp index fb8a3e383950..aa81f618dc59 100644 --- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp +++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp @@ -25,6 +25,7 @@ #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" @@ -247,6 +248,13 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() { // Call the rewind function. CallInst *CI = CallInst::Create(RewindFunction, RewindFunctionArgs, "", UnwindBB); + // The verifier requires that all calls of debug-info-bearing functions + // from debug-info-bearing functions have a debug location (for inlining + // purposes). Assign a dummy location to satisfy the constraint. + Function *RewindFn = dyn_cast(RewindFunction.getCallee()); + if (RewindFn && RewindFn->getSubprogram()) + if (DISubprogram *SP = F.getSubprogram()) + CI->setDebugLoc(DILocation::get(SP->getContext(), 0, 0, SP)); CI->setCallingConv(RewindFunctionCallingConv); // We never expect _Unwind_Resume to return. diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 89a43c4f57f6..85d051cfdbe7 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1262,9 +1262,10 @@ void PEI::insertZeroCallUsedRegs(MachineFunction &MF) { } } - // Don't clear registers that are reset before exiting. - for (const CalleeSavedInfo &CSI : MF.getFrameInfo().getCalleeSavedInfo()) - for (MCRegister Reg : TRI.sub_and_superregs_inclusive(CSI.getReg())) + // Don't clear registers that must be preserved. + for (const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF); + MCPhysReg CSReg = *CSRegs; ++CSRegs) + for (MCRegister Reg : TRI.sub_and_superregs_inclusive(CSReg)) RegsToZero.reset(Reg); const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering(); diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 91bc7dbad1d0..2cdae028ec7d 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8149,9 +8149,15 @@ VPRecipeBase *VPRecipeBuilder::tryToOptimizeInductionPHI( *PSE.getSE(), *OrigLoop, Range); // Check if this is pointer induction. If so, build the recipe for it. - if (auto *II = Legal->getPointerInductionDescriptor(Phi)) - return new VPWidenPointerInductionRecipe(Phi, Operands[0], *II, - *PSE.getSE()); + if (auto *II = Legal->getPointerInductionDescriptor(Phi)) { + return new VPWidenPointerInductionRecipe( + Phi, Operands[0], *II, *PSE.getSE(), + LoopVectorizationPlanner::getDecisionAndClampRange( + [&](ElementCount VF) { + return !VF.isScalable() && CM.isScalarAfterVectorization(Phi, VF); + }, + Range)); + } return nullptr; } @@ -9332,7 +9338,7 @@ void VPWidenPointerInductionRecipe::execute(VPTransformState &State) { auto *IVR = getParent()->getPlan()->getCanonicalIV(); PHINode *CanonicalIV = cast(State.get(IVR, 0)); - if (onlyScalarsGenerated(State.VF)) { + if (onlyScalarsGenerated()) { // This is the normalized GEP that starts counting at zero. Value *PtrInd = State.Builder.CreateSExtOrTrunc( CanonicalIV, IndDesc.getStep()->getType()); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index 30032dda7f60..0662ca883252 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -698,7 +698,7 @@ void VPlan::execute(VPTransformState *State) { auto *WidenPhi = cast(&R); // TODO: Split off the case that all users of a pointer phi are scalar // from the VPWidenPointerInductionRecipe. - if (WidenPhi->onlyScalarsGenerated(State->VF)) + if (WidenPhi->onlyScalarsGenerated()) continue; auto *GEP = cast(State->get(WidenPhi, 0)); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index f009a7ee6b4b..329843bf977d 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1187,15 +1187,19 @@ class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe { /// explicitly. ScalarEvolution &SE; + bool IsScalarAfterVectorization; + public: /// Create a new VPWidenPointerInductionRecipe for \p Phi with start value \p /// Start. VPWidenPointerInductionRecipe(PHINode *Phi, VPValue *Start, const InductionDescriptor &IndDesc, - ScalarEvolution &SE) + ScalarEvolution &SE, + bool IsScalarAfterVectorization) : VPHeaderPHIRecipe(VPVWidenPointerInductionSC, VPWidenPointerInductionSC, Phi), - IndDesc(IndDesc), SE(SE) { + IndDesc(IndDesc), SE(SE), + IsScalarAfterVectorization(IsScalarAfterVectorization) { addOperand(Start); } @@ -1216,7 +1220,7 @@ class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe { void execute(VPTransformState &State) override; /// Returns true if only scalar values will be generated. - bool onlyScalarsGenerated(ElementCount VF); + bool onlyScalarsGenerated(); #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) /// Print the recipe. diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index cb7507264667..f214563af6cc 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -982,11 +982,8 @@ void VPCanonicalIVPHIRecipe::print(raw_ostream &O, const Twine &Indent, } #endif -bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(ElementCount VF) { - bool IsUniform = vputils::onlyFirstLaneUsed(this); - return all_of(users(), - [&](const VPUser *U) { return U->usesScalars(this); }) && - (IsUniform || !VF.isScalable()); +bool VPWidenPointerInductionRecipe::onlyScalarsGenerated() { + return IsScalarAfterVectorization; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp index ca73dafe2b8e..61676b4323d2 100644 --- a/llvm/tools/llvm-objdump/ELFDump.cpp +++ b/llvm/tools/llvm-objdump/ELFDump.cpp @@ -282,27 +282,28 @@ static void printProgramHeaders(const ELFFile &Obj, StringRef FileName) { } template -static void printSymbolVersionDependency(ArrayRef Contents, - StringRef StrTab) { +static void printSymbolVersionDependency(StringRef FileName, + const ELFFile &Obj, + const typename ELFT::Shdr &Sec) { outs() << "\nVersion References:\n"; - const uint8_t *Buf = Contents.data(); - while (Buf) { - auto *Verneed = reinterpret_cast(Buf); - outs() << " required from " - << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n"; + auto WarningHandler = [&](const Twine &Msg) { + reportWarning(Msg, FileName); + return Error::success(); + }; + Expected> V = + Obj.getVersionDependencies(Sec, WarningHandler); + if (!V) { + reportWarning(toString(V.takeError()), FileName); + return; + } - const uint8_t *BufAux = Buf + Verneed->vn_aux; - while (BufAux) { - auto *Vernaux = reinterpret_cast(BufAux); - outs() << " " - << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash) - << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags) - << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other) - << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n'; - BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr; - } - Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr; + raw_fd_ostream &OS = outs(); + for (const VerNeed &VN : *V) { + OS << " required from " << VN.File << ":\n"; + for (const VernAux &Aux : VN.AuxV) + OS << format(" 0x%08x 0x%02x %02u %s\n", Aux.Hash, Aux.Flags, + Aux.Other, Aux.Name.c_str()); } } @@ -355,7 +356,7 @@ static void printSymbolVersionInfo(const ELFFile &Elf, StringRef StrTab = unwrapOrError(Elf.getStringTable(*StrTabSec), FileName); if (Shdr.sh_type == ELF::SHT_GNU_verneed) - printSymbolVersionDependency(Contents, StrTab); + printSymbolVersionDependency(FileName, Elf, Shdr); else printSymbolVersionDefinition(Shdr, Contents, StrTab); } From 6befc758a38754c930daf51e1094f210afb70f25 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 15 Oct 2022 18:01:12 +0200 Subject: [PATCH 2/3] Vendor import of llvm-project branch release/15.x llvmorg-15.0.2-0-g4bd3f3759259. --- clang/lib/AST/StmtPrinter.cpp | 2 +- clang/lib/CodeGen/CGStmt.cpp | 15 +++++++++ clang/lib/Sema/SemaInit.cpp | 8 ++--- libcxx/include/__config | 33 +++++++++++-------- libcxx/include/stdatomic.h | 4 +-- lld/ELF/Arch/RISCV.cpp | 9 ++--- llvm/include/llvm/ADT/GenericCycleImpl.h | 29 +++++++++++----- llvm/include/llvm/ADT/GenericCycleInfo.h | 19 ++++++----- llvm/lib/Analysis/ValueTracking.cpp | 13 ++++++-- .../Target/Hexagon/HexagonVectorCombine.cpp | 3 ++ .../Target/SPIRV/SPIRVDuplicatesTracker.cpp | 2 ++ .../Transforms/Vectorize/LoopVectorize.cpp | 4 +-- llvm/lib/Transforms/Vectorize/VPlan.cpp | 2 +- llvm/lib/Transforms/Vectorize/VPlan.h | 2 +- .../lib/Transforms/Vectorize/VPlanRecipes.cpp | 5 +-- 15 files changed, 102 insertions(+), 48 deletions(-) diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 8d778500d103..625048c69a86 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1993,7 +1993,7 @@ void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { cast(DRE->getDecl())->getTemplateSpecializationArgs(); assert(Args); - if (Args->size() != 1) { + if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) { const TemplateParameterList *TPL = nullptr; if (!DRE->hadMultipleCandidates()) if (const auto *TD = dyn_cast(DRE->getDecl())) diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 481438de0e53..9935fcc0d3ea 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -1509,6 +1509,21 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S, llvm::ConstantInt *CaseVal = Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext())); + + // Emit debuginfo for the case value if it is an enum value. + const ConstantExpr *CE; + if (auto ICE = dyn_cast(S.getLHS())) + CE = dyn_cast(ICE->getSubExpr()); + else + CE = dyn_cast(S.getLHS()); + if (CE) { + if (auto DE = dyn_cast(CE->getSubExpr())) + if (CGDebugInfo *Dbg = getDebugInfo()) + if (CGM.getCodeGenOpts().hasReducedDebugInfo()) + Dbg->EmitGlobalVariable(DE->getDecl(), + APValue(llvm::APSInt(CaseVal->getValue()))); + } + if (SwitchLikelihood) SwitchLikelihood->push_back(Stmt::getLikelihood(Attrs)); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index d3b454843234..bf7ca718a36b 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -695,10 +695,10 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, // member of reference type uninitialized, the program is // ill-formed. SemaRef.Diag(Loc, diag::err_init_reference_member_uninitialized) - << Field->getType() - << ILE->getSyntacticForm()->getSourceRange(); - SemaRef.Diag(Field->getLocation(), - diag::note_uninit_reference_member); + << Field->getType() + << (ILE->isSyntacticForm() ? ILE : ILE->getSyntacticForm()) + ->getSourceRange(); + SemaRef.Diag(Field->getLocation(), diag::note_uninit_reference_member); } hadError = true; return; diff --git a/libcxx/include/__config b/libcxx/include/__config index 2f80df35f909..01377a9617ea 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -22,9 +22,21 @@ # pragma GCC system_header #endif +#if defined(__apple_build_version__) +# define _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000) +#elif defined(__clang__) +# define _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__) +#elif defined(__GNUC__) +# define _LIBCPP_COMPILER_GCC +#elif defined(_MSC_VER) +# define _LIBCPP_COMPILER_MSVC +#endif + #ifdef __cplusplus -# define _LIBCPP_VERSION 15001 +# define _LIBCPP_VERSION 15002 # define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y # define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y) @@ -198,18 +210,6 @@ # define __has_include(...) 0 # endif -# if defined(__apple_build_version__) -# define _LIBCPP_COMPILER_CLANG_BASED -# define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000) -# elif defined(__clang__) -# define _LIBCPP_COMPILER_CLANG_BASED -# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__) -# elif defined(__GNUC__) -# define _LIBCPP_COMPILER_GCC -# elif defined(_MSC_VER) -# define _LIBCPP_COMPILER_MSVC -# endif - # if !defined(_LIBCPP_COMPILER_CLANG_BASED) && __cplusplus < 201103L # error "libc++ only supports C++03 with Clang-based compilers. Please enable C++11" # endif @@ -1101,6 +1101,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION # endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES +// Leave the deprecation notices in by default, but don't remove unary_function and +// binary_function entirely just yet. That way, folks will have one release to act +// on the deprecation warnings. +# ifndef _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION +# define _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION +# endif + # if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES) # define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS # define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION diff --git a/libcxx/include/stdatomic.h b/libcxx/include/stdatomic.h index d9550c44061c..ff2a5682f5bb 100644 --- a/libcxx/include/stdatomic.h +++ b/libcxx/include/stdatomic.h @@ -121,7 +121,7 @@ using std::atomic_signal_fence // see below # pragma GCC system_header #endif -#if _LIBCPP_STD_VER > 20 +#if defined(__cplusplus) && _LIBCPP_STD_VER > 20 #include #include @@ -230,6 +230,6 @@ using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS; # include_next # endif -#endif // _LIBCPP_STD_VER > 20 +#endif // defined(__cplusplus) && _LIBCPP_STD_VER > 20 #endif // _LIBCPP_STDATOMIC_H diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index 8fca1a686a79..56a516f9cdc1 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -750,12 +750,13 @@ void elf::riscvFinalizeRelax(int passes) { p += size; // For R_RISCV_ALIGN, we will place `offset` in a location (among NOPs) - // to satisfy the alignment requirement. If `remove` is a multiple of 4, - // it is as if we have skipped some NOPs. Otherwise we are in the middle - // of a 4-byte NOP, and we need to rewrite the NOP sequence. + // to satisfy the alignment requirement. If both `remove` and r.addend + // are multiples of 4, it is as if we have skipped some NOPs. Otherwise + // we are in the middle of a 4-byte NOP, and we need to rewrite the NOP + // sequence. int64_t skip = 0; if (r.type == R_RISCV_ALIGN) { - if (remove % 4 != 0) { + if (remove % 4 || r.addend % 4) { skip = r.addend - remove; int64_t j = 0; for (; j + 4 <= skip; j += 4) diff --git a/llvm/include/llvm/ADT/GenericCycleImpl.h b/llvm/include/llvm/ADT/GenericCycleImpl.h index ea2847f8c8ee..07ac1768ea27 100644 --- a/llvm/include/llvm/ADT/GenericCycleImpl.h +++ b/llvm/include/llvm/ADT/GenericCycleImpl.h @@ -144,8 +144,12 @@ template class GenericCycleInfoCompute { }; template -auto GenericCycleInfo::getTopLevelParentCycle( - const BlockT *Block) const -> CycleT * { +auto GenericCycleInfo::getTopLevelParentCycle(BlockT *Block) + -> CycleT * { + auto Cycle = BlockMapTopLevel.find(Block); + if (Cycle != BlockMapTopLevel.end()) + return Cycle->second; + auto MapIt = BlockMap.find(Block); if (MapIt == BlockMap.end()) return nullptr; @@ -153,12 +157,15 @@ auto GenericCycleInfo::getTopLevelParentCycle( auto *C = MapIt->second; while (C->ParentCycle) C = C->ParentCycle; + BlockMapTopLevel.try_emplace(Block, C); return C; } template -void GenericCycleInfo::moveToNewParent(CycleT *NewParent, - CycleT *Child) { +void GenericCycleInfo::moveTopLevelCycleToNewParent(CycleT *NewParent, + CycleT *Child) { + assert((!Child->ParentCycle && !NewParent->ParentCycle) && + "NewParent and Child must be both top level cycle!\n"); auto &CurrentContainer = Child->ParentCycle ? Child->ParentCycle->Children : TopLevelCycles; auto Pos = llvm::find_if(CurrentContainer, [=](const auto &Ptr) -> bool { @@ -169,6 +176,13 @@ void GenericCycleInfo::moveToNewParent(CycleT *NewParent, *Pos = std::move(CurrentContainer.back()); CurrentContainer.pop_back(); Child->ParentCycle = NewParent; + + NewParent->Blocks.insert(NewParent->Blocks.end(), Child->block_begin(), + Child->block_end()); + + for (auto &It : BlockMapTopLevel) + if (It.second == Child) + It.second = NewParent; } /// \brief Main function of the cycle info computations. @@ -240,10 +254,7 @@ void GenericCycleInfoCompute::run(BlockT *EntryBlock) { << "discovered child cycle " << Info.Context.print(BlockParent->getHeader()) << "\n"); // Make BlockParent the child of NewCycle. - Info.moveToNewParent(NewCycle.get(), BlockParent); - NewCycle->Blocks.insert(NewCycle->Blocks.end(), - BlockParent->block_begin(), - BlockParent->block_end()); + Info.moveTopLevelCycleToNewParent(NewCycle.get(), BlockParent); for (auto *ChildEntry : BlockParent->entries()) ProcessPredecessors(ChildEntry); @@ -257,6 +268,7 @@ void GenericCycleInfoCompute::run(BlockT *EntryBlock) { assert(!is_contained(NewCycle->Blocks, Block)); NewCycle->Blocks.push_back(Block); ProcessPredecessors(Block); + Info.BlockMapTopLevel.try_emplace(Block, NewCycle.get()); } } while (!Worklist.empty()); @@ -336,6 +348,7 @@ void GenericCycleInfoCompute::dfs(BlockT *EntryBlock) { template void GenericCycleInfo::clear() { TopLevelCycles.clear(); BlockMap.clear(); + BlockMapTopLevel.clear(); } /// \brief Compute the cycle info for a function. diff --git a/llvm/include/llvm/ADT/GenericCycleInfo.h b/llvm/include/llvm/ADT/GenericCycleInfo.h index 970664b85715..5f851b795cbc 100644 --- a/llvm/include/llvm/ADT/GenericCycleInfo.h +++ b/llvm/include/llvm/ADT/GenericCycleInfo.h @@ -232,15 +232,24 @@ template class GenericCycleInfo { private: ContextT Context; - /// Map basic blocks to their inner-most containing loop. + /// Map basic blocks to their inner-most containing cycle. DenseMap BlockMap; + /// Map basic blocks to their top level containing cycle. + DenseMap BlockMapTopLevel; + /// Outermost cycles discovered by any DFS. /// /// Note: The implementation treats the nullptr as the parent of /// every top-level cycle. See \ref contains for an example. std::vector> TopLevelCycles; + /// Move \p Child to \p NewParent by manipulating Children vectors. + /// + /// Note: This is an incomplete operation that does not update the depth of + /// the subtree. + void moveTopLevelCycleToNewParent(CycleT *NewParent, CycleT *Child); + public: GenericCycleInfo() = default; GenericCycleInfo(GenericCycleInfo &&) = default; @@ -254,13 +263,7 @@ template class GenericCycleInfo { CycleT *getCycle(const BlockT *Block) const; unsigned getCycleDepth(const BlockT *Block) const; - CycleT *getTopLevelParentCycle(const BlockT *Block) const; - - /// Move \p Child to \p NewParent by manipulating Children vectors. - /// - /// Note: This is an incomplete operation that does not update the - /// list of blocks in the new parent or the depth of the subtree. - void moveToNewParent(CycleT *NewParent, CycleT *Child); + CycleT *getTopLevelParentCycle(BlockT *Block); /// Methods for debug and self-test. //@{ diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 2dd671b4ab9e..569ee6b3ea86 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3593,14 +3593,23 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V, // Unsigned integers are always nonnegative. case Instruction::UIToFP: return true; - case Instruction::FMul: case Instruction::FDiv: - // X * X is always non-negative or a NaN. // X / X is always exactly 1.0 or a NaN. if (I->getOperand(0) == I->getOperand(1) && (!SignBitOnly || cast(I)->hasNoNaNs())) return true; + // Set SignBitOnly for RHS, because X / -0.0 is -Inf (or NaN). + return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, + Depth + 1) && + cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI, + /*SignBitOnly*/ true, Depth + 1); + case Instruction::FMul: + // X * X is always non-negative or a NaN. + if (I->getOperand(0) == I->getOperand(1) && + (!SignBitOnly || cast(I)->hasNoNaNs())) + return true; + LLVM_FALLTHROUGH; case Instruction::FAdd: case Instruction::FRem: diff --git a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp index bd0232c71d48..f37c50900adb 100644 --- a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp @@ -149,6 +149,7 @@ class AlignVectors { Align H) : Inst(I), Addr(A), ValTy(T), HaveAlign(H), NeedAlign(HVC.getTypeAlignment(ValTy)) {} + AddrInfo &operator=(const AddrInfo &) = default; // XXX: add Size member? Instruction *Inst; @@ -185,6 +186,7 @@ class AlignVectors { Segment(Value *Val, int Begin, int Len) : Val(Val), Start(Begin), Size(Len) {} Segment(const Segment &Seg) = default; + Segment &operator=(const Segment &Seg) = default; Value *Val; // Value representable as a sequence of bytes. int Start; // First byte of the value that belongs to the segment. int Size; // Number of bytes in the segment. @@ -195,6 +197,7 @@ class AlignVectors { Block(Value *Val, int Off, int Len, int Pos) : Seg(Val, Off, Len), Pos(Pos) {} Block(const Block &Blk) = default; + Block &operator=(const Block &Blk) = default; Segment Seg; // Value segment. int Pos; // Position (offset) of the segment in the Block. }; diff --git a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp index 1926977ea66e..2e426bb79cae 100644 --- a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp @@ -70,6 +70,7 @@ void SPIRVGeneralDuplicatesTracker::buildDepsGraph( } } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) if (MMI) { const Module *M = MMI->getModule(); for (auto F = M->begin(), E = M->end(); F != E; ++F) { @@ -92,4 +93,5 @@ void SPIRVGeneralDuplicatesTracker::buildDepsGraph( } } } +#endif } diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 2cdae028ec7d..5fd4e45d80fb 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8154,7 +8154,7 @@ VPRecipeBase *VPRecipeBuilder::tryToOptimizeInductionPHI( Phi, Operands[0], *II, *PSE.getSE(), LoopVectorizationPlanner::getDecisionAndClampRange( [&](ElementCount VF) { - return !VF.isScalable() && CM.isScalarAfterVectorization(Phi, VF); + return CM.isScalarAfterVectorization(Phi, VF); }, Range)); } @@ -9338,7 +9338,7 @@ void VPWidenPointerInductionRecipe::execute(VPTransformState &State) { auto *IVR = getParent()->getPlan()->getCanonicalIV(); PHINode *CanonicalIV = cast(State.get(IVR, 0)); - if (onlyScalarsGenerated()) { + if (onlyScalarsGenerated(State.VF)) { // This is the normalized GEP that starts counting at zero. Value *PtrInd = State.Builder.CreateSExtOrTrunc( CanonicalIV, IndDesc.getStep()->getType()); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index 0662ca883252..30032dda7f60 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -698,7 +698,7 @@ void VPlan::execute(VPTransformState *State) { auto *WidenPhi = cast(&R); // TODO: Split off the case that all users of a pointer phi are scalar // from the VPWidenPointerInductionRecipe. - if (WidenPhi->onlyScalarsGenerated()) + if (WidenPhi->onlyScalarsGenerated(State->VF)) continue; auto *GEP = cast(State->get(WidenPhi, 0)); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index 329843bf977d..7a6bc48e2aee 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1220,7 +1220,7 @@ class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe { void execute(VPTransformState &State) override; /// Returns true if only scalar values will be generated. - bool onlyScalarsGenerated(); + bool onlyScalarsGenerated(ElementCount VF); #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) /// Print the recipe. diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index f214563af6cc..9a404640b4b8 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -982,8 +982,9 @@ void VPCanonicalIVPHIRecipe::print(raw_ostream &O, const Twine &Indent, } #endif -bool VPWidenPointerInductionRecipe::onlyScalarsGenerated() { - return IsScalarAfterVectorization; +bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(ElementCount VF) { + return IsScalarAfterVectorization && + (!VF.isScalable() || vputils::onlyFirstLaneUsed(this)); } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) From dafdd7863e9eeed3a714329b8758451cbcfc33bf Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 15 Oct 2022 18:03:32 +0200 Subject: [PATCH 3/3] Vendor import of llvm-project branch release/15.x llvmorg-15.0.2-10-gf3c5289e7846. --- clang/lib/Tooling/Syntax/Tokens.cpp | 220 +++++++++++++------ libcxx/include/__config | 2 +- llvm/lib/Analysis/ScalarEvolution.cpp | 7 +- llvm/lib/Support/X86TargetParser.cpp | 10 +- llvm/lib/Target/X86/X86.td | 1 - llvm/lib/Transforms/Utils/LoopVersioning.cpp | 4 +- 6 files changed, 172 insertions(+), 72 deletions(-) diff --git a/clang/lib/Tooling/Syntax/Tokens.cpp b/clang/lib/Tooling/Syntax/Tokens.cpp index e2014f965c90..1fa73c667b7f 100644 --- a/clang/lib/Tooling/Syntax/Tokens.cpp +++ b/clang/lib/Tooling/Syntax/Tokens.cpp @@ -55,45 +55,140 @@ getTokensCovering(llvm::ArrayRef Toks, SourceRange R, return {Begin, End}; } -// Finds the smallest expansion range that contains expanded tokens First and -// Last, e.g.: +// Finds the range within FID corresponding to expanded tokens [First, Last]. +// Prev precedes First and Next follows Last, these must *not* be included. +// If no range satisfies the criteria, returns an invalid range. +// // #define ID(x) x // ID(ID(ID(a1) a2)) // ~~ -> a1 // ~~ -> a2 // ~~~~~~~~~ -> a1 a2 -SourceRange findCommonRangeForMacroArgs(const syntax::Token &First, - const syntax::Token &Last, - const SourceManager &SM) { - SourceRange Res; - auto FirstLoc = First.location(), LastLoc = Last.location(); - // Keep traversing up the spelling chain as longs as tokens are part of the - // same expansion. - while (!FirstLoc.isFileID() && !LastLoc.isFileID()) { - auto ExpInfoFirst = SM.getSLocEntry(SM.getFileID(FirstLoc)).getExpansion(); - auto ExpInfoLast = SM.getSLocEntry(SM.getFileID(LastLoc)).getExpansion(); - // Stop if expansions have diverged. - if (ExpInfoFirst.getExpansionLocStart() != - ExpInfoLast.getExpansionLocStart()) +SourceRange spelledForExpandedSlow(SourceLocation First, SourceLocation Last, + SourceLocation Prev, SourceLocation Next, + FileID TargetFile, + const SourceManager &SM) { + // There are two main parts to this algorithm: + // - identifying which spelled range covers the expanded tokens + // - validating that this range doesn't cover any extra tokens (First/Last) + // + // We do these in order. However as we transform the expanded range into the + // spelled one, we adjust First/Last so the validation remains simple. + + assert(SM.getSLocEntry(TargetFile).isFile()); + // In most cases, to select First and Last we must return their expansion + // range, i.e. the whole of any macros they are included in. + // + // When First and Last are part of the *same macro arg* of a macro written + // in TargetFile, we that slice of the arg, i.e. their spelling range. + // + // Unwrap such macro calls. If the target file has A(B(C)), the + // SourceLocation stack of a token inside C shows us the expansion of A first, + // then B, then any macros inside C's body, then C itself. + // (This is the reverse of the order the PP applies the expansions in). + while (First.isMacroID() && Last.isMacroID()) { + auto DecFirst = SM.getDecomposedLoc(First); + auto DecLast = SM.getDecomposedLoc(Last); + auto &ExpFirst = SM.getSLocEntry(DecFirst.first).getExpansion(); + auto &ExpLast = SM.getSLocEntry(DecLast.first).getExpansion(); + + if (!ExpFirst.isMacroArgExpansion() || !ExpLast.isMacroArgExpansion()) break; - // Do not continue into macro bodies. - if (!ExpInfoFirst.isMacroArgExpansion() || - !ExpInfoLast.isMacroArgExpansion()) + // Locations are in the same macro arg if they expand to the same place. + // (They may still have different FileIDs - an arg can have >1 chunks!) + if (ExpFirst.getExpansionLocStart() != ExpLast.getExpansionLocStart()) break; - FirstLoc = SM.getImmediateSpellingLoc(FirstLoc); - LastLoc = SM.getImmediateSpellingLoc(LastLoc); - // Update the result afterwards, as we want the tokens that triggered the - // expansion. - Res = {FirstLoc, LastLoc}; + // Careful, given: + // #define HIDE ID(ID(a)) + // ID(ID(HIDE)) + // The token `a` is wrapped in 4 arg-expansions, we only want to unwrap 2. + // We distinguish them by whether the macro expands into the target file. + // Fortunately, the target file ones will always appear first. + auto &ExpMacro = + SM.getSLocEntry(SM.getFileID(ExpFirst.getExpansionLocStart())) + .getExpansion(); + if (ExpMacro.getExpansionLocStart().isMacroID()) + break; + // Replace each endpoint with its spelling inside the macro arg. + // (This is getImmediateSpellingLoc without repeating lookups). + First = ExpFirst.getSpellingLoc().getLocWithOffset(DecFirst.second); + Last = ExpLast.getSpellingLoc().getLocWithOffset(DecLast.second); + + // Now: how do we adjust the previous/next bounds? Three cases: + // A) If they are also part of the same macro arg, we translate them too. + // This will ensure that we don't select any macros nested within the + // macro arg that cover extra tokens. Critical case: + // #define ID(X) X + // ID(prev target) // selecting 'target' succeeds + // #define LARGE ID(prev target) + // LARGE // selecting 'target' fails. + // B) They are not in the macro at all, then their expansion range is a + // sibling to it, and we can safely substitute that. + // #define PREV prev + // #define ID(X) X + // PREV ID(target) // selecting 'target' succeeds. + // #define LARGE PREV ID(target) + // LARGE // selecting 'target' fails. + // C) They are in a different arg of this macro, or the macro body. + // Now selecting the whole macro arg is fine, but the whole macro is not. + // Model this by setting using the edge of the macro call as the bound. + // #define ID2(X, Y) X Y + // ID2(prev, target) // selecting 'target' succeeds + // #define LARGE ID2(prev, target) + // LARGE // selecting 'target' fails + auto AdjustBound = [&](SourceLocation &Bound) { + if (Bound.isInvalid() || !Bound.isMacroID()) // Non-macro must be case B. + return; + auto DecBound = SM.getDecomposedLoc(Bound); + auto &ExpBound = SM.getSLocEntry(DecBound.first).getExpansion(); + if (ExpBound.isMacroArgExpansion() && + ExpBound.getExpansionLocStart() == ExpFirst.getExpansionLocStart()) { + // Case A: translate to (spelling) loc within the macro arg. + Bound = ExpBound.getSpellingLoc().getLocWithOffset(DecBound.second); + return; + } + while (Bound.isMacroID()) { + SourceRange Exp = SM.getImmediateExpansionRange(Bound).getAsRange(); + if (Exp.getBegin() == ExpMacro.getExpansionLocStart()) { + // Case B: bounds become the macro call itself. + Bound = (&Bound == &Prev) ? Exp.getBegin() : Exp.getEnd(); + return; + } + // Either case C, or expansion location will later find case B. + // We choose the upper bound for Prev and the lower one for Next: + // ID(prev) target ID(next) + // ^ ^ + // new-prev new-next + Bound = (&Bound == &Prev) ? Exp.getEnd() : Exp.getBegin(); + } + }; + AdjustBound(Prev); + AdjustBound(Next); } - // Normally mapping back to expansion location here only changes FileID, as - // we've already found some tokens expanded from the same macro argument, and - // they should map to a consecutive subset of spelled tokens. Unfortunately - // SourceManager::isBeforeInTranslationUnit discriminates sourcelocations - // based on their FileID in addition to offsets. So even though we are - // referring to same tokens, SourceManager might tell us that one is before - // the other if they've got different FileIDs. - return SM.getExpansionRange(CharSourceRange(Res, true)).getAsRange(); + + // In all remaining cases we need the full containing macros. + // If this overlaps Prev or Next, then no range is possible. + SourceRange Candidate = + SM.getExpansionRange(SourceRange(First, Last)).getAsRange(); + auto DecFirst = SM.getDecomposedExpansionLoc(Candidate.getBegin()); + auto DecLast = SM.getDecomposedLoc(Candidate.getEnd()); + // Can end up in the wrong file due to bad input or token-pasting shenanigans. + if (Candidate.isInvalid() || DecFirst.first != TargetFile || DecLast.first != TargetFile) + return SourceRange(); + // Check bounds, which may still be inside macros. + if (Prev.isValid()) { + auto Dec = SM.getDecomposedLoc(SM.getExpansionRange(Prev).getBegin()); + if (Dec.first != DecFirst.first || Dec.second >= DecFirst.second) + return SourceRange(); + } + if (Next.isValid()) { + auto Dec = SM.getDecomposedLoc(SM.getExpansionRange(Next).getEnd()); + if (Dec.first != DecLast.first || Dec.second <= DecLast.second) + return SourceRange(); + } + // Now we know that Candidate is a file range that covers [First, Last] + // without encroaching on {Prev, Next}. Ship it! + return Candidate; } } // namespace @@ -363,51 +458,50 @@ TokenBuffer::spelledForExpanded(llvm::ArrayRef Expanded) const { // of the range, bail out in that case. if (Expanded.empty()) return llvm::None; + const syntax::Token *First = &Expanded.front(); + const syntax::Token *Last = &Expanded.back(); + const syntax::Token *FirstSpelled, *LastSpelled; + const TokenBuffer::Mapping *FirstMapping, *LastMapping; + std::tie(FirstSpelled, FirstMapping) = spelledForExpandedToken(First); + std::tie(LastSpelled, LastMapping) = spelledForExpandedToken(Last); - const syntax::Token *BeginSpelled; - const Mapping *BeginMapping; - std::tie(BeginSpelled, BeginMapping) = - spelledForExpandedToken(&Expanded.front()); - - const syntax::Token *LastSpelled; - const Mapping *LastMapping; - std::tie(LastSpelled, LastMapping) = - spelledForExpandedToken(&Expanded.back()); - - FileID FID = SourceMgr->getFileID(BeginSpelled->location()); + FileID FID = SourceMgr->getFileID(FirstSpelled->location()); // FIXME: Handle multi-file changes by trying to map onto a common root. if (FID != SourceMgr->getFileID(LastSpelled->location())) return llvm::None; const MarkedFile &File = Files.find(FID)->second; - // If both tokens are coming from a macro argument expansion, try and map to - // smallest part of the macro argument. BeginMapping && LastMapping check is - // only for performance, they are a prerequisite for Expanded.front() and - // Expanded.back() being part of a macro arg expansion. - if (BeginMapping && LastMapping && - SourceMgr->isMacroArgExpansion(Expanded.front().location()) && - SourceMgr->isMacroArgExpansion(Expanded.back().location())) { - auto CommonRange = findCommonRangeForMacroArgs(Expanded.front(), - Expanded.back(), *SourceMgr); - // It might be the case that tokens are arguments of different macro calls, - // in that case we should continue with the logic below instead of returning - // an empty range. - if (CommonRange.isValid()) - return getTokensCovering(File.SpelledTokens, CommonRange, *SourceMgr); + // If the range is within one macro argument, the result may be only part of a + // Mapping. We must use the general (SourceManager-based) algorithm. + if (FirstMapping && FirstMapping == LastMapping && + SourceMgr->isMacroArgExpansion(First->location()) && + SourceMgr->isMacroArgExpansion(Last->location())) { + // We use excluded Prev/Next token for bounds checking. + SourceLocation Prev = (First == &ExpandedTokens.front()) + ? SourceLocation() + : (First - 1)->location(); + SourceLocation Next = (Last == &ExpandedTokens.back()) + ? SourceLocation() + : (Last + 1)->location(); + SourceRange Range = spelledForExpandedSlow( + First->location(), Last->location(), Prev, Next, FID, *SourceMgr); + if (Range.isInvalid()) + return llvm::None; + return getTokensCovering(File.SpelledTokens, Range, *SourceMgr); } + // Otherwise, use the fast version based on Mappings. // Do not allow changes that doesn't cover full expansion. - unsigned BeginExpanded = Expanded.begin() - ExpandedTokens.data(); - unsigned EndExpanded = Expanded.end() - ExpandedTokens.data(); - if (BeginMapping && BeginExpanded != BeginMapping->BeginExpanded) + unsigned FirstExpanded = Expanded.begin() - ExpandedTokens.data(); + unsigned LastExpanded = Expanded.end() - ExpandedTokens.data(); + if (FirstMapping && FirstExpanded != FirstMapping->BeginExpanded) return llvm::None; - if (LastMapping && LastMapping->EndExpanded != EndExpanded) + if (LastMapping && LastMapping->EndExpanded != LastExpanded) return llvm::None; - // All is good, return the result. return llvm::makeArrayRef( - BeginMapping ? File.SpelledTokens.data() + BeginMapping->BeginSpelled - : BeginSpelled, + FirstMapping ? File.SpelledTokens.data() + FirstMapping->BeginSpelled + : FirstSpelled, LastMapping ? File.SpelledTokens.data() + LastMapping->EndSpelled : LastSpelled + 1); } diff --git a/libcxx/include/__config b/libcxx/include/__config index 01377a9617ea..589b5c3b2241 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -36,7 +36,7 @@ #ifdef __cplusplus -# define _LIBCPP_VERSION 15002 +# define _LIBCPP_VERSION 15003 # define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y # define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y) diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 2958a5054afc..c784c27d36b4 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -5917,8 +5917,13 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) { if (const SCEV *S = createNodeFromSelectLikePHI(PN)) return S; + // If the PHI has a single incoming value, follow that value, unless the + // PHI's incoming blocks are in a different loop, in which case doing so + // risks breaking LCSSA form. Instcombine would normally zap these, but + // it doesn't have DominatorTree information, so it may miss cases. if (Value *V = simplifyInstruction(PN, {getDataLayout(), &TLI, &DT, &AC})) - return getSCEV(V); + if (LI.replacementPreservesLCSSAForm(PN, V)) + return getSCEV(V); // If it's not a loop phi, we can't handle it yet. return getUnknown(PN); diff --git a/llvm/lib/Support/X86TargetParser.cpp b/llvm/lib/Support/X86TargetParser.cpp index 2567f3ed8034..0daaa6d815bf 100644 --- a/llvm/lib/Support/X86TargetParser.cpp +++ b/llvm/lib/Support/X86TargetParser.cpp @@ -203,10 +203,10 @@ constexpr FeatureBitset FeaturesTigerlake = FeatureCLWB | FeatureMOVDIRI | FeatureSHSTK | FeatureKL | FeatureWIDEKL; constexpr FeatureBitset FeaturesSapphireRapids = FeaturesICLServer | FeatureAMX_BF16 | FeatureAMX_INT8 | FeatureAMX_TILE | - FeatureAVX512BF16 | FeatureAVX512FP16 | FeatureAVX512VP2INTERSECT | - FeatureAVXVNNI | FeatureCLDEMOTE | FeatureENQCMD | FeatureMOVDIR64B | - FeatureMOVDIRI | FeaturePTWRITE | FeatureSERIALIZE | FeatureSHSTK | - FeatureTSXLDTRK | FeatureUINTR | FeatureWAITPKG; + FeatureAVX512BF16 | FeatureAVX512FP16 | FeatureAVXVNNI | FeatureCLDEMOTE | + FeatureENQCMD | FeatureMOVDIR64B | FeatureMOVDIRI | FeaturePTWRITE | + FeatureSERIALIZE | FeatureSHSTK | FeatureTSXLDTRK | FeatureUINTR | + FeatureWAITPKG; // Intel Atom processors. // Bonnell has feature parity with Core2 and adds MOVBE. @@ -367,7 +367,7 @@ constexpr ProcInfo Processors[] = { // Tigerlake microarchitecture based processors. { {"tigerlake"}, CK_Tigerlake, FEATURE_AVX512VP2INTERSECT, FeaturesTigerlake }, // Sapphire Rapids microarchitecture based processors. - { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512VP2INTERSECT, FeaturesSapphireRapids }, + { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512BF16, FeaturesSapphireRapids }, // Alderlake microarchitecture based processors. { {"alderlake"}, CK_Alderlake, FEATURE_AVX2, FeaturesAlderlake }, // Knights Landing processor. diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index fa0a6bd415dc..f98916e81cee 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -909,7 +909,6 @@ def ProcessorFeatures { FeatureTSXLDTRK, FeatureENQCMD, FeatureSHSTK, - FeatureVP2INTERSECT, FeatureMOVDIRI, FeatureMOVDIR64B, FeatureUINTR]; diff --git a/llvm/lib/Transforms/Utils/LoopVersioning.cpp b/llvm/lib/Transforms/Utils/LoopVersioning.cpp index 97f29527bb95..6309eed7963d 100644 --- a/llvm/lib/Transforms/Utils/LoopVersioning.cpp +++ b/llvm/lib/Transforms/Utils/LoopVersioning.cpp @@ -137,8 +137,10 @@ void LoopVersioning::addPHINodes( // See if we have a single-operand PHI with the value defined by the // original loop. for (auto I = PHIBlock->begin(); (PN = dyn_cast(I)); ++I) { - if (PN->getIncomingValue(0) == Inst) + if (PN->getIncomingValue(0) == Inst) { + SE->forgetValue(PN); break; + } } // If not create it. if (!PN) {