Date: Sat, 11 Feb 2017 13:25:24 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r313633 - in vendor/llvm/dist: docs include/llvm/ADT include/llvm/CodeGen include/llvm/IR include/llvm/Target lib/Bitcode/Reader lib/CodeGen lib/MC lib/Target/AArch64 lib/Target/X86 tes... Message-ID: <201702111325.v1BDPOx4075273@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Sat Feb 11 13:25:24 2017 New Revision: 313633 URL: https://svnweb.freebsd.org/changeset/base/313633 Log: Vendor import of llvm release_40 branch r294803: https://llvm.org/svn/llvm-project/llvm/branches/release_40@294803 Added: vendor/llvm/dist/test/CodeGen/AArch64/ldst-zero.ll vendor/llvm/dist/test/CodeGen/AArch64/misched-stp.ll vendor/llvm/dist/test/CodeGen/ARM/machine-copyprop.mir Deleted: vendor/llvm/dist/test/CodeGen/X86/conditional-tailcall.ll vendor/llvm/dist/test/CodeGen/X86/tail-call-conditional.mir Modified: vendor/llvm/dist/docs/ReleaseNotes.rst vendor/llvm/dist/docs/conf.py vendor/llvm/dist/include/llvm/ADT/ilist_iterator.h vendor/llvm/dist/include/llvm/CodeGen/MachineInstrBundleIterator.h vendor/llvm/dist/include/llvm/IR/PassManager.h vendor/llvm/dist/include/llvm/Target/TargetInstrInfo.h vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp vendor/llvm/dist/lib/CodeGen/BranchFolding.cpp vendor/llvm/dist/lib/CodeGen/MachineCopyPropagation.cpp vendor/llvm/dist/lib/CodeGen/RegisterCoalescer.cpp vendor/llvm/dist/lib/MC/MCCodeView.cpp vendor/llvm/dist/lib/Target/AArch64/AArch64ISelLowering.cpp vendor/llvm/dist/lib/Target/X86/X86ExpandPseudo.cpp vendor/llvm/dist/lib/Target/X86/X86InstrControl.td vendor/llvm/dist/lib/Target/X86/X86InstrInfo.cpp vendor/llvm/dist/lib/Target/X86/X86InstrInfo.h vendor/llvm/dist/lib/Target/X86/X86MCInstLower.cpp vendor/llvm/dist/test/Bitcode/DIGlobalVariableExpression.ll vendor/llvm/dist/test/Bitcode/DIGlobalVariableExpression.ll.bc vendor/llvm/dist/test/Bitcode/dityperefs-3.8.ll vendor/llvm/dist/test/CodeGen/AArch64/regcoal-physreg.mir vendor/llvm/dist/test/CodeGen/X86/shrink-compare.ll vendor/llvm/dist/test/MC/COFF/cv-def-range-gap.s vendor/llvm/dist/unittests/ADT/IListIteratorTest.cpp vendor/llvm/dist/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp vendor/llvm/dist/utils/release/build_llvm_package.bat Modified: vendor/llvm/dist/docs/ReleaseNotes.rst ============================================================================== --- vendor/llvm/dist/docs/ReleaseNotes.rst Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/docs/ReleaseNotes.rst Sat Feb 11 13:25:24 2017 (r313633) @@ -55,6 +55,12 @@ Non-comprehensive list of changes in thi * LLVM now handles invariant.group across different basic blocks, which makes it possible to devirtualize virtual calls inside loops. +* The aggressive dead code elimination phase ("adce") now remove + branches which do not effect program behavior. Loops are retained by + default since they may be infinite but these can also be removed + with LLVM option -adce-remove-loops when the loop body otherwise has + no live operations. + * ... next change ... .. NOTE @@ -75,6 +81,95 @@ Non-comprehensive list of changes in thi * Significant build-time and binary-size improvements when compiling with debug info (-g). +Code Generation Testing +----------------------- + +Passes that work on the machine instruction representation can be tested with +the .mir serialization format. ``llc`` supports the ``-run-pass``, +``-stop-after``, ``-stop-before``, ``-start-after``, ``-start-before`` to to +run a single pass of the code generation pipeline, or to stop or start the code +generation pipeline at a given point. + +Additional information can be found in the :doc:`MIRLangRef`. The format is +used by the tests ending in ``.mir`` in the ``test/CodeGen`` directory. + +This feature is available since 2015. It is used more often lately and was not +mentioned in the release notes yet. + +Intrusive list API overhaul +--------------------------- + +The intrusive list infrastructure was substantially rewritten over the last +couple of releases, primarily to excise undefined behaviour. The biggest +changes landed in this release. + +* ``simple_ilist<T>`` is a lower-level intrusive list that never takes + ownership of its nodes. New intrusive-list clients should consider using it + instead of ``ilist<T>``. + + * ``ilist_tag<class>`` allows a single data type to be inserted into two + parallel intrusive lists. A type can inherit twice from ``ilist_node``, + first using ``ilist_node<T,ilist_tag<A>>`` (enabling insertion into + ``simple_ilist<T,ilist_tag<A>>``) and second using + ``ilist_node<T,ilist_tag<B>>`` (enabling insertion into + ``simple_ilist<T,ilist_tag<B>>``), where ``A`` and ``B`` are arbitrary + types. + + * ``ilist_sentinel_tracking<bool>`` controls whether an iterator knows + whether it's pointing at the sentinel (``end()``). By default, sentinel + tracking is on when ABI-breaking checks are enabled, and off otherwise; + this is used for an assertion when dereferencing ``end()`` (this assertion + triggered often in practice, and many backend bugs were fixed). Explicitly + turning on sentinel tracking also enables ``iterator::isEnd()``. This is + used by ``MachineInstrBundleIterator`` to iterate over bundles. + +* ``ilist<T>`` is built on top of ``simple_ilist<T>``, and supports the same + configuration options. As before (and unlike ``simple_ilist<T>``), + ``ilist<T>`` takes ownership of its nodes. However, it no longer supports + *allocating* nodes, and is now equivalent to ``iplist<T>``. ``iplist<T>`` + will likely be removed in the future. + + * ``ilist<T>`` now always uses ``ilist_traits<T>``. Instead of passing a + custom traits class in via a template parameter, clients that want to + customize the traits should specialize ``ilist_traits<T>``. Clients that + want to avoid ownership can specialize ``ilist_alloc_traits<T>`` to inherit + from ``ilist_noalloc_traits<T>`` (or to do something funky); clients that + need callbacks can specialize ``ilist_callback_traits<T>`` directly. + +* The underlying data structure is now a simple recursive linked list. The + sentinel node contains only a "next" (``begin()``) and "prev" (``rbegin()``) + pointer and is stored in the same allocation as ``simple_ilist<T>``. + Previously, it was malloc-allocated on-demand by default, although the + now-defunct ``ilist_sentinel_traits<T>`` was sometimes specialized to avoid + this. + +* The ``reverse_iterator`` class no longer uses ``std::reverse_iterator``. + Instead, it now has a handle to the same node that it dereferences to. + Reverse iterators now have the same iterator invalidation semantics as + forward iterators. + + * ``iterator`` and ``reverse_iterator`` have explicit conversion constructors + that match ``std::reverse_iterator``'s off-by-one semantics, so that + reversing the end points of an iterator range results in the same range + (albeit in reverse). I.e., ``reverse_iterator(begin())`` equals + ``rend()``. + + * ``iterator::getReverse()`` and ``reverse_iterator::getReverse()`` return an + iterator that dereferences to the *same* node. I.e., + ``begin().getReverse()`` equals ``--rend()``. + + * ``ilist_node<T>::getIterator()`` and + ``ilist_node<T>::getReverseIterator()`` return the forward and reverse + iterators that dereference to the current node. I.e., + ``begin()->getIterator()`` equals ``begin()`` and + ``rbegin()->getReverseIterator()`` equals ``rbegin()``. + +* ``iterator`` now stores an ``ilist_node_base*`` instead of a ``T*``. The + implicit conversions between ``ilist<T>::iterator`` and ``T*`` have been + removed. Clients may use ``N->getIterator()`` (if not ``nullptr``) or + ``&*I`` (if not ``end()``); alternatively, clients may refactor to use + references for known-good nodes. + Changes to the LLVM IR ---------------------- @@ -133,9 +228,23 @@ Changes to the AMDGPU Target Changes to the AVR Target ----------------------------- -* The entire backend has been merged in-tree with all tests passing. All of - the instruction selection code and the machine code backend has landed - recently and is fully usable. +This marks the first release where the AVR backend has been completely merged +from a fork into LLVM trunk. The backend is still marked experimental, but +is generally quite usable. All downstream development has halted on +`GitHub <https://github.com/avr-llvm/llvm>`_, and changes now go directly into +LLVM trunk. + +* Instruction selector and pseudo instruction expansion pass landed +* `read_register` and `write_register` intrinsics are now supported +* Support stack stores greater than 63-bytes from the bottom of the stack +* A number of assertion errors have been fixed +* Support stores to `undef` locations +* Very basic support for the target has been added to clang +* Small optimizations to some 16-bit boolean expressions + +Most of the work behind the scenes has been on correctness of generated +assembly, and also fixing some assertions we would hit on some well-formed +inputs. Changes to the OCaml bindings ----------------------------- Modified: vendor/llvm/dist/docs/conf.py ============================================================================== --- vendor/llvm/dist/docs/conf.py Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/docs/conf.py Sat Feb 11 13:25:24 2017 (r313633) @@ -48,9 +48,9 @@ copyright = u'2003-%d, LLVM Project' % d # built documents. # # The short X.Y version. -version = '4.0' +version = '4' # The full version, including alpha/beta/rc tags. -release = '4.0' +release = '4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. Modified: vendor/llvm/dist/include/llvm/ADT/ilist_iterator.h ============================================================================== --- vendor/llvm/dist/include/llvm/ADT/ilist_iterator.h Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/include/llvm/ADT/ilist_iterator.h Sat Feb 11 13:25:24 2017 (r313633) @@ -102,10 +102,23 @@ public: return *this; } - /// Convert from an iterator to its reverse. + /// Explicit conversion between forward/reverse iterators. /// - /// TODO: Roll this into the implicit constructor once we're sure that no one - /// is relying on the std::reverse_iterator off-by-one semantics. + /// Translate between forward and reverse iterators without changing range + /// boundaries. The resulting iterator will dereference (and have a handle) + /// to the previous node, which is somewhat unexpected; but converting the + /// two endpoints in a range will give the same range in reverse. + /// + /// This matches std::reverse_iterator conversions. + explicit ilist_iterator( + const ilist_iterator<OptionsT, !IsReverse, IsConst> &RHS) + : ilist_iterator(++RHS.getReverse()) {} + + /// Get a reverse iterator to the same node. + /// + /// Gives a reverse iterator that will dereference (and have a handle) to the + /// same node. Converting the endpoint iterators in a range will give a + /// different range; for range operations, use the explicit conversions. ilist_iterator<OptionsT, !IsReverse, IsConst> getReverse() const { if (NodePtr) return ilist_iterator<OptionsT, !IsReverse, IsConst>(*NodePtr); Modified: vendor/llvm/dist/include/llvm/CodeGen/MachineInstrBundleIterator.h ============================================================================== --- vendor/llvm/dist/include/llvm/CodeGen/MachineInstrBundleIterator.h Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/include/llvm/CodeGen/MachineInstrBundleIterator.h Sat Feb 11 13:25:24 2017 (r313633) @@ -153,6 +153,18 @@ public: : MII(I.getInstrIterator()) {} MachineInstrBundleIterator() : MII(nullptr) {} + /// Explicit conversion between forward/reverse iterators. + /// + /// Translate between forward and reverse iterators without changing range + /// boundaries. The resulting iterator will dereference (and have a handle) + /// to the previous node, which is somewhat unexpected; but converting the + /// two endpoints in a range will give the same range in reverse. + /// + /// This matches std::reverse_iterator conversions. + explicit MachineInstrBundleIterator( + const MachineInstrBundleIterator<Ty, !IsReverse> &I) + : MachineInstrBundleIterator(++I.getReverse()) {} + /// Get the bundle iterator for the given instruction's bundle. static MachineInstrBundleIterator getAtBundleBegin(instr_iterator MI) { return MachineInstrBundleIteratorHelper<IsReverse>::getBundleBegin(MI); @@ -258,6 +270,11 @@ public: nonconst_iterator getNonConstIterator() const { return MII.getNonConst(); } + /// Get a reverse iterator to the same node. + /// + /// Gives a reverse iterator that will dereference (and have a handle) to the + /// same node. Converting the endpoint iterators in a range will give a + /// different range; for range operations, use the explicit conversions. reverse_iterator getReverse() const { return MII.getReverse(); } }; Modified: vendor/llvm/dist/include/llvm/IR/PassManager.h ============================================================================== --- vendor/llvm/dist/include/llvm/IR/PassManager.h Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/include/llvm/IR/PassManager.h Sat Feb 11 13:25:24 2017 (r313633) @@ -311,6 +311,8 @@ template <typename IRUnitT, typename... template <typename DerivedT> struct PassInfoMixin { /// Gets the name of the pass we are mixed into. static StringRef name() { + static_assert(std::is_base_of<PassInfoMixin, DerivedT>::value, + "Must pass the derived type as the template argument!"); StringRef Name = getTypeName<DerivedT>(); if (Name.startswith("llvm::")) Name = Name.drop_front(strlen("llvm::")); @@ -339,7 +341,11 @@ struct AnalysisInfoMixin : PassInfoMixin /// known platform with this limitation is Windows DLL builds, specifically /// building each part of LLVM as a DLL. If we ever remove that build /// configuration, this mixin can provide the static key as well. - static AnalysisKey *ID() { return &DerivedT::Key; } + static AnalysisKey *ID() { + static_assert(std::is_base_of<AnalysisInfoMixin, DerivedT>::value, + "Must pass the derived type as the template argument!"); + return &DerivedT::Key; + } }; /// This templated class represents "all analyses that operate over \<a @@ -1010,7 +1016,7 @@ extern template class InnerAnalysisManag template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs> class OuterAnalysisManagerProxy : public AnalysisInfoMixin< - OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> { + OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>> { public: /// \brief Result proxy object for \c OuterAnalysisManagerProxy. class Result { @@ -1072,7 +1078,7 @@ public: private: friend AnalysisInfoMixin< - OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>; + OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>>; static AnalysisKey Key; const AnalysisManagerT *AM; Modified: vendor/llvm/dist/include/llvm/Target/TargetInstrInfo.h ============================================================================== --- vendor/llvm/dist/include/llvm/Target/TargetInstrInfo.h Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/include/llvm/Target/TargetInstrInfo.h Sat Feb 11 13:25:24 2017 (r313633) @@ -1108,25 +1108,6 @@ public: /// terminator instruction that has not been predicated. virtual bool isUnpredicatedTerminator(const MachineInstr &MI) const; - /// Returns true if MI is an unconditional tail call. - virtual bool isUnconditionalTailCall(const MachineInstr &MI) const { - return false; - } - - /// Returns true if the tail call can be made conditional on BranchCond. - virtual bool - canMakeTailCallConditional(SmallVectorImpl<MachineOperand> &Cond, - const MachineInstr &TailCall) const { - return false; - } - - /// Replace the conditional branch in MBB with a conditional tail call. - virtual void replaceBranchWithTailCall(MachineBasicBlock &MBB, - SmallVectorImpl<MachineOperand> &Cond, - const MachineInstr &TailCall) const { - llvm_unreachable("Target didn't implement replaceBranchWithTailCall!"); - } - /// Convert the instruction into a predicated instruction. /// It returns true if the operation was successful. virtual bool PredicateInstruction(MachineInstr &MI, Modified: vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp ============================================================================== --- vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp Sat Feb 11 13:25:24 2017 (r313633) @@ -448,6 +448,7 @@ class MetadataLoader::MetadataLoaderImpl bool StripTBAA = false; bool HasSeenOldLoopTags = false; + bool NeedUpgradeToDIGlobalVariableExpression = false; /// True if metadata is being parsed for a module being ThinLTO imported. bool IsImporting = false; @@ -473,6 +474,45 @@ class MetadataLoader::MetadataLoaderImpl CUSubprograms.clear(); } + /// Upgrade old-style bare DIGlobalVariables to DIGlobalVariableExpressions. + void upgradeCUVariables() { + if (!NeedUpgradeToDIGlobalVariableExpression) + return; + + // Upgrade list of variables attached to the CUs. + if (NamedMDNode *CUNodes = TheModule.getNamedMetadata("llvm.dbg.cu")) + for (unsigned I = 0, E = CUNodes->getNumOperands(); I != E; ++I) { + auto *CU = cast<DICompileUnit>(CUNodes->getOperand(I)); + if (auto *GVs = dyn_cast_or_null<MDTuple>(CU->getRawGlobalVariables())) + for (unsigned I = 0; I < GVs->getNumOperands(); I++) + if (auto *GV = + dyn_cast_or_null<DIGlobalVariable>(GVs->getOperand(I))) { + auto *DGVE = + DIGlobalVariableExpression::getDistinct(Context, GV, nullptr); + GVs->replaceOperandWith(I, DGVE); + } + } + + // Upgrade variables attached to globals. + for (auto &GV : TheModule.globals()) { + SmallVector<MDNode *, 1> MDs, NewMDs; + GV.getMetadata(LLVMContext::MD_dbg, MDs); + GV.eraseMetadata(LLVMContext::MD_dbg); + for (auto *MD : MDs) + if (auto *DGV = dyn_cast_or_null<DIGlobalVariable>(MD)) { + auto *DGVE = + DIGlobalVariableExpression::getDistinct(Context, DGV, nullptr); + GV.addMetadata(LLVMContext::MD_dbg, *DGVE); + } else + GV.addMetadata(LLVMContext::MD_dbg, *MD); + } + } + + void upgradeDebugInfo() { + upgradeCUSubprograms(); + upgradeCUVariables(); + } + public: MetadataLoaderImpl(BitstreamCursor &Stream, Module &TheModule, BitcodeReaderValueList &ValueList, @@ -726,7 +766,7 @@ Error MetadataLoader::MetadataLoaderImpl // Reading the named metadata created forward references and/or // placeholders, that we flush here. resolveForwardRefsAndPlaceholders(Placeholders); - upgradeCUSubprograms(); + upgradeDebugInfo(); // Return at the beginning of the block, since it is easy to skip it // entirely from there. Stream.ReadBlockEnd(); // Pop the abbrev block context. @@ -750,7 +790,7 @@ Error MetadataLoader::MetadataLoaderImpl return error("Malformed block"); case BitstreamEntry::EndBlock: resolveForwardRefsAndPlaceholders(Placeholders); - upgradeCUSubprograms(); + upgradeDebugInfo(); return Error::success(); case BitstreamEntry::Record: // The interesting case. @@ -1420,11 +1460,17 @@ Error MetadataLoader::MetadataLoaderImpl getDITypeRefOrNull(Record[6]), Record[7], Record[8], getMDOrNull(Record[10]), AlignInBits)); - auto *DGVE = DIGlobalVariableExpression::getDistinct(Context, DGV, Expr); - MetadataList.assignValue(DGVE, NextMetadataNo); - NextMetadataNo++; + DIGlobalVariableExpression *DGVE = nullptr; + if (Attach || Expr) + DGVE = DIGlobalVariableExpression::getDistinct(Context, DGV, Expr); + else + NeedUpgradeToDIGlobalVariableExpression = true; if (Attach) Attach->addDebugInfo(DGVE); + + auto *MDNode = Expr ? cast<Metadata>(DGVE) : cast<Metadata>(DGV); + MetadataList.assignValue(MDNode, NextMetadataNo); + NextMetadataNo++; } else return error("Invalid record"); Modified: vendor/llvm/dist/lib/CodeGen/BranchFolding.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/BranchFolding.cpp Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/CodeGen/BranchFolding.cpp Sat Feb 11 13:25:24 2017 (r313633) @@ -49,7 +49,6 @@ STATISTIC(NumDeadBlocks, "Number of dead STATISTIC(NumBranchOpts, "Number of branches optimized"); STATISTIC(NumTailMerge , "Number of block tails merged"); STATISTIC(NumHoist , "Number of times common instructions are hoisted"); -STATISTIC(NumTailCalls, "Number of tail calls optimized"); static cl::opt<cl::boolOrDefault> FlagEnableTailMerge("enable-tail-merge", cl::init(cl::BOU_UNSET), cl::Hidden); @@ -1387,42 +1386,6 @@ ReoptimizeBlock: } } - if (!IsEmptyBlock(MBB) && MBB->pred_size() == 1 && - MF.getFunction()->optForSize()) { - // Changing "Jcc foo; foo: jmp bar;" into "Jcc bar;" might change the branch - // direction, thereby defeating careful block placement and regressing - // performance. Therefore, only consider this for optsize functions. - MachineInstr &TailCall = *MBB->getFirstNonDebugInstr(); - if (TII->isUnconditionalTailCall(TailCall)) { - MachineBasicBlock *Pred = *MBB->pred_begin(); - MachineBasicBlock *PredTBB = nullptr, *PredFBB = nullptr; - SmallVector<MachineOperand, 4> PredCond; - bool PredAnalyzable = - !TII->analyzeBranch(*Pred, PredTBB, PredFBB, PredCond, true); - - if (PredAnalyzable && !PredCond.empty() && PredTBB == MBB) { - // The predecessor has a conditional branch to this block which consists - // of only a tail call. Try to fold the tail call into the conditional - // branch. - if (TII->canMakeTailCallConditional(PredCond, TailCall)) { - // TODO: It would be nice if analyzeBranch() could provide a pointer - // to the branch insturction so replaceBranchWithTailCall() doesn't - // have to search for it. - TII->replaceBranchWithTailCall(*Pred, PredCond, TailCall); - ++NumTailCalls; - Pred->removeSuccessor(MBB); - MadeChange = true; - return MadeChange; - } - } - // If the predecessor is falling through to this block, we could reverse - // the branch condition and fold the tail call into that. However, after - // that we might have to re-arrange the CFG to fall through to the other - // block and there is a high risk of regressing code size rather than - // improving it. - } - } - // Analyze the branch in the current block. MachineBasicBlock *CurTBB = nullptr, *CurFBB = nullptr; SmallVector<MachineOperand, 4> CurCond; Modified: vendor/llvm/dist/lib/CodeGen/MachineCopyPropagation.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/MachineCopyPropagation.cpp Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/CodeGen/MachineCopyPropagation.cpp Sat Feb 11 13:25:24 2017 (r313633) @@ -61,6 +61,7 @@ namespace { private: void ClobberRegister(unsigned Reg); + void ReadRegister(unsigned Reg); void CopyPropagateBlock(MachineBasicBlock &MBB); bool eraseIfRedundant(MachineInstr &Copy, unsigned Src, unsigned Def); @@ -120,6 +121,18 @@ void MachineCopyPropagation::ClobberRegi } } +void MachineCopyPropagation::ReadRegister(unsigned Reg) { + // If 'Reg' is defined by a copy, the copy is no longer a candidate + // for elimination. + for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { + Reg2MIMap::iterator CI = CopyMap.find(*AI); + if (CI != CopyMap.end()) { + DEBUG(dbgs() << "MCP: Copy is used - not dead: "; CI->second->dump()); + MaybeDeadCopies.remove(CI->second); + } + } +} + /// Return true if \p PreviousCopy did copy register \p Src to register \p Def. /// This fact may have been obscured by sub register usage or may not be true at /// all even though Src and Def are subregisters of the registers used in @@ -212,12 +225,14 @@ void MachineCopyPropagation::CopyPropaga // If Src is defined by a previous copy, the previous copy cannot be // eliminated. - for (MCRegAliasIterator AI(Src, TRI, true); AI.isValid(); ++AI) { - Reg2MIMap::iterator CI = CopyMap.find(*AI); - if (CI != CopyMap.end()) { - DEBUG(dbgs() << "MCP: Copy is no longer dead: "; CI->second->dump()); - MaybeDeadCopies.remove(CI->second); - } + ReadRegister(Src); + for (const MachineOperand &MO : MI->implicit_operands()) { + if (!MO.isReg() || !MO.readsReg()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + ReadRegister(Reg); } DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI->dump()); @@ -234,6 +249,14 @@ void MachineCopyPropagation::CopyPropaga // ... // %xmm2<def> = copy %xmm9 ClobberRegister(Def); + for (const MachineOperand &MO : MI->implicit_operands()) { + if (!MO.isReg() || !MO.isDef()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + ClobberRegister(Reg); + } // Remember Def is defined by the copy. for (MCSubRegIterator SR(Def, TRI, /*IncludeSelf=*/true); SR.isValid(); @@ -268,17 +291,8 @@ void MachineCopyPropagation::CopyPropaga if (MO.isDef()) { Defs.push_back(Reg); - continue; - } - - // If 'Reg' is defined by a copy, the copy is no longer a candidate - // for elimination. - for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { - Reg2MIMap::iterator CI = CopyMap.find(*AI); - if (CI != CopyMap.end()) { - DEBUG(dbgs() << "MCP: Copy is used - not dead: "; CI->second->dump()); - MaybeDeadCopies.remove(CI->second); - } + } else { + ReadRegister(Reg); } // Treat undef use like defs for copy propagation but not for // dead copy. We would need to do a liveness check to be sure the copy Modified: vendor/llvm/dist/lib/CodeGen/RegisterCoalescer.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/RegisterCoalescer.cpp Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/CodeGen/RegisterCoalescer.cpp Sat Feb 11 13:25:24 2017 (r313633) @@ -1556,9 +1556,10 @@ bool RegisterCoalescer::joinCopy(Machine bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) { unsigned DstReg = CP.getDstReg(); + unsigned SrcReg = CP.getSrcReg(); assert(CP.isPhys() && "Must be a physreg copy"); assert(MRI->isReserved(DstReg) && "Not a reserved register"); - LiveInterval &RHS = LIS->getInterval(CP.getSrcReg()); + LiveInterval &RHS = LIS->getInterval(SrcReg); DEBUG(dbgs() << "\t\tRHS = " << RHS << '\n'); assert(RHS.containsOneValue() && "Invalid join with reserved register"); @@ -1592,17 +1593,36 @@ bool RegisterCoalescer::joinReservedPhys // Delete the identity copy. MachineInstr *CopyMI; if (CP.isFlipped()) { - CopyMI = MRI->getVRegDef(RHS.reg); + // Physreg is copied into vreg + // %vregY = COPY %X + // ... //< no other def of %X here + // use %vregY + // => + // ... + // use %X + CopyMI = MRI->getVRegDef(SrcReg); } else { - if (!MRI->hasOneNonDBGUse(RHS.reg)) { + // VReg is copied into physreg: + // %vregX = def + // ... //< no other def or use of %Y here + // %Y = COPY %vregX + // => + // %Y = def + // ... + if (!MRI->hasOneNonDBGUse(SrcReg)) { DEBUG(dbgs() << "\t\tMultiple vreg uses!\n"); return false; } - MachineInstr *DestMI = MRI->getVRegDef(RHS.reg); - CopyMI = &*MRI->use_instr_nodbg_begin(RHS.reg); - const SlotIndex CopyRegIdx = LIS->getInstructionIndex(*CopyMI).getRegSlot(); - const SlotIndex DestRegIdx = LIS->getInstructionIndex(*DestMI).getRegSlot(); + if (!LIS->intervalIsInOneMBB(RHS)) { + DEBUG(dbgs() << "\t\tComplex control flow!\n"); + return false; + } + + MachineInstr &DestMI = *MRI->getVRegDef(SrcReg); + CopyMI = &*MRI->use_instr_nodbg_begin(SrcReg); + SlotIndex CopyRegIdx = LIS->getInstructionIndex(*CopyMI).getRegSlot(); + SlotIndex DestRegIdx = LIS->getInstructionIndex(DestMI).getRegSlot(); if (!MRI->isConstantPhysReg(DstReg)) { // We checked above that there are no interfering defs of the physical @@ -1629,8 +1649,8 @@ bool RegisterCoalescer::joinReservedPhys // We're going to remove the copy which defines a physical reserved // register, so remove its valno, etc. - DEBUG(dbgs() << "\t\tRemoving phys reg def of " << DstReg << " at " - << CopyRegIdx << "\n"); + DEBUG(dbgs() << "\t\tRemoving phys reg def of " << PrintReg(DstReg, TRI) + << " at " << CopyRegIdx << "\n"); LIS->removePhysRegDefAt(DstReg, CopyRegIdx); // Create a new dead def at the new def location. Modified: vendor/llvm/dist/lib/MC/MCCodeView.cpp ============================================================================== --- vendor/llvm/dist/lib/MC/MCCodeView.cpp Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/MC/MCCodeView.cpp Sat Feb 11 13:25:24 2017 (r313633) @@ -509,17 +509,17 @@ void CodeViewContext::encodeDefRange(MCA // are artificially constructing. size_t RecordSize = FixedSizePortion.size() + sizeof(LocalVariableAddrRange) + 4 * NumGaps; - // Write out the recrod size. - support::endian::Writer<support::little>(OS).write<uint16_t>(RecordSize); + // Write out the record size. + LEWriter.write<uint16_t>(RecordSize); // Write out the fixed size prefix. OS << FixedSizePortion; // Make space for a fixup that will eventually have a section relative // relocation pointing at the offset where the variable becomes live. Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_4)); - Contents.resize(Contents.size() + 4); // Fixup for code start. + LEWriter.write<uint32_t>(0); // Fixup for code start. // Make space for a fixup that will record the section index for the code. Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_2)); - Contents.resize(Contents.size() + 2); // Fixup for section index. + LEWriter.write<uint16_t>(0); // Fixup for section index. // Write down the range's extent. LEWriter.write<uint16_t>(Chunk); @@ -529,7 +529,7 @@ void CodeViewContext::encodeDefRange(MCA } while (RangeSize > 0); // Emit the gaps afterwards. - assert((NumGaps == 0 || Bias < MaxDefRange) && + assert((NumGaps == 0 || Bias <= MaxDefRange) && "large ranges should not have gaps"); unsigned GapStartOffset = GapAndRangeSizes[I].second; for (++I; I != J; ++I) { @@ -537,7 +537,7 @@ void CodeViewContext::encodeDefRange(MCA assert(I < GapAndRangeSizes.size()); std::tie(GapSize, RangeSize) = GapAndRangeSizes[I]; LEWriter.write<uint16_t>(GapStartOffset); - LEWriter.write<uint16_t>(RangeSize); + LEWriter.write<uint16_t>(GapSize); GapStartOffset += GapSize + RangeSize; } } Modified: vendor/llvm/dist/lib/Target/AArch64/AArch64ISelLowering.cpp ============================================================================== --- vendor/llvm/dist/lib/Target/AArch64/AArch64ISelLowering.cpp Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/Target/AArch64/AArch64ISelLowering.cpp Sat Feb 11 13:25:24 2017 (r313633) @@ -8934,8 +8934,9 @@ static SDValue splitStoreSplat(Selection // instructions (stp). SDLoc DL(&St); SDValue BasePtr = St.getBasePtr(); + const MachinePointerInfo &PtrInfo = St.getPointerInfo(); SDValue NewST1 = - DAG.getStore(St.getChain(), DL, SplatVal, BasePtr, St.getPointerInfo(), + DAG.getStore(St.getChain(), DL, SplatVal, BasePtr, PtrInfo, OrigAlignment, St.getMemOperand()->getFlags()); unsigned Offset = EltOffset; @@ -8944,7 +8945,7 @@ static SDValue splitStoreSplat(Selection SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i64, BasePtr, DAG.getConstant(Offset, DL, MVT::i64)); NewST1 = DAG.getStore(NewST1.getValue(0), DL, SplatVal, OffsetPtr, - St.getPointerInfo(), Alignment, + PtrInfo.getWithOffset(Offset), Alignment, St.getMemOperand()->getFlags()); Offset += EltOffset; } Modified: vendor/llvm/dist/lib/Target/X86/X86ExpandPseudo.cpp ============================================================================== --- vendor/llvm/dist/lib/Target/X86/X86ExpandPseudo.cpp Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/Target/X86/X86ExpandPseudo.cpp Sat Feb 11 13:25:24 2017 (r313633) @@ -77,11 +77,9 @@ bool X86ExpandPseudo::ExpandMI(MachineBa default: return false; case X86::TCRETURNdi: - case X86::TCRETURNdicc: case X86::TCRETURNri: case X86::TCRETURNmi: case X86::TCRETURNdi64: - case X86::TCRETURNdi64cc: case X86::TCRETURNri64: case X86::TCRETURNmi64: { bool isMem = Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64; @@ -99,10 +97,6 @@ bool X86ExpandPseudo::ExpandMI(MachineBa Offset = StackAdj - MaxTCDelta; assert(Offset >= 0 && "Offset should never be negative"); - if (Opcode == X86::TCRETURNdicc || Opcode == X86::TCRETURNdi64cc) { - assert(Offset == 0 && "Conditional tail call cannot adjust the stack."); - } - if (Offset) { // Check for possible merge with preceding ADD instruction. Offset += X86FL->mergeSPUpdates(MBB, MBBI, true); @@ -111,21 +105,12 @@ bool X86ExpandPseudo::ExpandMI(MachineBa // Jump to label or value in register. bool IsWin64 = STI->isTargetWin64(); - if (Opcode == X86::TCRETURNdi || Opcode == X86::TCRETURNdicc || - Opcode == X86::TCRETURNdi64 || Opcode == X86::TCRETURNdi64cc) { + if (Opcode == X86::TCRETURNdi || Opcode == X86::TCRETURNdi64) { unsigned Op; switch (Opcode) { case X86::TCRETURNdi: Op = X86::TAILJMPd; break; - case X86::TCRETURNdicc: - Op = X86::TAILJMPd_CC; - break; - case X86::TCRETURNdi64cc: - assert(!IsWin64 && "Conditional tail calls confuse the Win64 unwinder."); - // TODO: We could do it for Win64 "leaf" functions though; PR30337. - Op = X86::TAILJMPd64_CC; - break; default: // Note: Win64 uses REX prefixes indirect jumps out of functions, but // not direct ones. @@ -141,10 +126,6 @@ bool X86ExpandPseudo::ExpandMI(MachineBa MIB.addExternalSymbol(JumpTarget.getSymbolName(), JumpTarget.getTargetFlags()); } - if (Op == X86::TAILJMPd_CC || Op == X86::TAILJMPd64_CC) { - MIB.addImm(MBBI->getOperand(2).getImm()); - } - } else if (Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64) { unsigned Op = (Opcode == X86::TCRETURNmi) ? X86::TAILJMPm Modified: vendor/llvm/dist/lib/Target/X86/X86InstrControl.td ============================================================================== --- vendor/llvm/dist/lib/Target/X86/X86InstrControl.td Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/Target/X86/X86InstrControl.td Sat Feb 11 13:25:24 2017 (r313633) @@ -264,21 +264,6 @@ let isCall = 1, isTerminator = 1, isRetu "jmp{l}\t{*}$dst", [], IIC_JMP_MEM>; } -// Conditional tail calls are similar to the above, but they are branches -// rather than barriers, and they use EFLAGS. -let isCall = 1, isTerminator = 1, isReturn = 1, isBranch = 1, - isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in - let Uses = [ESP, EFLAGS] in { - def TCRETURNdicc : PseudoI<(outs), - (ins i32imm_pcrel:$dst, i32imm:$offset, i32imm:$cond), []>; - - // This gets substituted to a conditional jump instruction in MC lowering. - def TAILJMPd_CC : Ii32PCRel<0x80, RawFrm, (outs), - (ins i32imm_pcrel:$dst, i32imm:$cond), - "", - [], IIC_JMP_REL>; -} - //===----------------------------------------------------------------------===// // Call Instructions... @@ -340,19 +325,3 @@ let isCall = 1, isTerminator = 1, isRetu "rex64 jmp{q}\t{*}$dst", [], IIC_JMP_MEM>; } } - -// Conditional tail calls are similar to the above, but they are branches -// rather than barriers, and they use EFLAGS. -let isCall = 1, isTerminator = 1, isReturn = 1, isBranch = 1, - isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in - let Uses = [RSP, EFLAGS] in { - def TCRETURNdi64cc : PseudoI<(outs), - (ins i64i32imm_pcrel:$dst, i32imm:$offset, - i32imm:$cond), []>; - - // This gets substituted to a conditional jump instruction in MC lowering. - def TAILJMPd64_CC : Ii32PCRel<0x80, RawFrm, (outs), - (ins i64i32imm_pcrel:$dst, i32imm:$cond), - "", - [], IIC_JMP_REL>; -} Modified: vendor/llvm/dist/lib/Target/X86/X86InstrInfo.cpp ============================================================================== --- vendor/llvm/dist/lib/Target/X86/X86InstrInfo.cpp Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/Target/X86/X86InstrInfo.cpp Sat Feb 11 13:25:24 2017 (r313633) @@ -5108,85 +5108,6 @@ bool X86InstrInfo::isUnpredicatedTermina return !isPredicated(MI); } -bool X86InstrInfo::isUnconditionalTailCall(const MachineInstr &MI) const { - switch (MI.getOpcode()) { - case X86::TCRETURNdi: - case X86::TCRETURNri: - case X86::TCRETURNmi: - case X86::TCRETURNdi64: - case X86::TCRETURNri64: - case X86::TCRETURNmi64: - return true; - default: - return false; - } -} - -bool X86InstrInfo::canMakeTailCallConditional( - SmallVectorImpl<MachineOperand> &BranchCond, - const MachineInstr &TailCall) const { - if (TailCall.getOpcode() != X86::TCRETURNdi && - TailCall.getOpcode() != X86::TCRETURNdi64) { - // Only direct calls can be done with a conditional branch. - return false; - } - - if (Subtarget.isTargetWin64()) { - // Conditional tail calls confuse the Win64 unwinder. - // TODO: Allow them for "leaf" functions; PR30337. - return false; - } - - assert(BranchCond.size() == 1); - if (BranchCond[0].getImm() > X86::LAST_VALID_COND) { - // Can't make a conditional tail call with this condition. - return false; - } - - const X86MachineFunctionInfo *X86FI = - TailCall.getParent()->getParent()->getInfo<X86MachineFunctionInfo>(); - if (X86FI->getTCReturnAddrDelta() != 0 || - TailCall.getOperand(1).getImm() != 0) { - // A conditional tail call cannot do any stack adjustment. - return false; - } - - return true; -} - -void X86InstrInfo::replaceBranchWithTailCall( - MachineBasicBlock &MBB, SmallVectorImpl<MachineOperand> &BranchCond, - const MachineInstr &TailCall) const { - assert(canMakeTailCallConditional(BranchCond, TailCall)); - - MachineBasicBlock::iterator I = MBB.end(); - while (I != MBB.begin()) { - --I; - if (I->isDebugValue()) - continue; - if (!I->isBranch()) - assert(0 && "Can't find the branch to replace!"); - - X86::CondCode CC = getCondFromBranchOpc(I->getOpcode()); - assert(BranchCond.size() == 1); - if (CC != BranchCond[0].getImm()) - continue; - - break; - } - - unsigned Opc = TailCall.getOpcode() == X86::TCRETURNdi ? X86::TCRETURNdicc - : X86::TCRETURNdi64cc; - - auto MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opc)); - MIB->addOperand(TailCall.getOperand(0)); // Destination. - MIB.addImm(0); // Stack offset (not used). - MIB->addOperand(BranchCond[0]); // Condition. - MIB.copyImplicitOps(TailCall); // Regmask and (imp-used) parameters. - - I->eraseFromParent(); -} - // Given a MBB and its TBB, find the FBB which was a fallthrough MBB (it may // not be a fallthrough MBB now due to layout changes). Return nullptr if the // fallthrough MBB cannot be identified. Modified: vendor/llvm/dist/lib/Target/X86/X86InstrInfo.h ============================================================================== --- vendor/llvm/dist/lib/Target/X86/X86InstrInfo.h Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/Target/X86/X86InstrInfo.h Sat Feb 11 13:25:24 2017 (r313633) @@ -316,13 +316,6 @@ public: // Branch analysis. bool isUnpredicatedTerminator(const MachineInstr &MI) const override; - bool isUnconditionalTailCall(const MachineInstr &MI) const override; - bool canMakeTailCallConditional(SmallVectorImpl<MachineOperand> &Cond, - const MachineInstr &TailCall) const override; - void replaceBranchWithTailCall(MachineBasicBlock &MBB, - SmallVectorImpl<MachineOperand> &Cond, - const MachineInstr &TailCall) const override; - bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, Modified: vendor/llvm/dist/lib/Target/X86/X86MCInstLower.cpp ============================================================================== --- vendor/llvm/dist/lib/Target/X86/X86MCInstLower.cpp Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/lib/Target/X86/X86MCInstLower.cpp Sat Feb 11 13:25:24 2017 (r313633) @@ -498,16 +498,11 @@ ReSimplify: break; } - // TAILJMPd, TAILJMPd64, TailJMPd_cc - Lower to the correct jump instruction. + // TAILJMPd, TAILJMPd64 - Lower to the correct jump instruction. { unsigned Opcode; case X86::TAILJMPr: Opcode = X86::JMP32r; goto SetTailJmpOpcode; case X86::TAILJMPd: case X86::TAILJMPd64: Opcode = X86::JMP_1; goto SetTailJmpOpcode; - case X86::TAILJMPd_CC: - case X86::TAILJMPd64_CC: - Opcode = X86::GetCondBranchFromCond( - static_cast<X86::CondCode>(MI->getOperand(1).getImm())); - goto SetTailJmpOpcode; SetTailJmpOpcode: MCOperand Saved = OutMI.getOperand(0); @@ -1281,11 +1276,9 @@ void X86AsmPrinter::EmitInstruction(cons case X86::TAILJMPr: case X86::TAILJMPm: case X86::TAILJMPd: - case X86::TAILJMPd_CC: case X86::TAILJMPr64: case X86::TAILJMPm64: case X86::TAILJMPd64: - case X86::TAILJMPd64_CC: case X86::TAILJMPr64_REX: case X86::TAILJMPm64_REX: // Lower these as normal, but add some comments. Modified: vendor/llvm/dist/test/Bitcode/DIGlobalVariableExpression.ll ============================================================================== --- vendor/llvm/dist/test/Bitcode/DIGlobalVariableExpression.ll Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/test/Bitcode/DIGlobalVariableExpression.ll Sat Feb 11 13:25:24 2017 (r313633) @@ -7,12 +7,16 @@ ; CHECK: @h = common global i32 0, align 4, !dbg ![[H:[0-9]+]] ; CHECK: ![[G]] = {{.*}}!DIGlobalVariableExpression(var: ![[GVAR:[0-9]+]], expr: ![[GEXPR:[0-9]+]]) ; CHECK: ![[GVAR]] = distinct !DIGlobalVariable(name: "g", +; CHECK: DICompileUnit({{.*}}, imports: ![[IMPORTS:[0-9]+]] ; CHECK: !DIGlobalVariableExpression(var: ![[CVAR:[0-9]+]], expr: ![[CEXPR:[0-9]+]]) ; CHECK: ![[CVAR]] = distinct !DIGlobalVariable(name: "c", ; CHECK: ![[CEXPR]] = !DIExpression(DW_OP_constu, 23, DW_OP_stack_value) -; CHECK: ![[H]] = {{.*}}!DIGlobalVariableExpression(var: ![[HVAR:[0-9]+]]) -; CHECK: ![[HVAR]] = distinct !DIGlobalVariable(name: "h", +; CHECK: ![[HVAR:[0-9]+]] = distinct !DIGlobalVariable(name: "h", +; CHECK: ![[IMPORTS]] = !{![[CIMPORT:[0-9]+]]} +; CHECK: ![[CIMPORT]] = !DIImportedEntity({{.*}}entity: ![[HVAR]] ; CHECK: ![[GEXPR]] = !DIExpression(DW_OP_plus, 1) +; CHECK: ![[H]] = {{.*}}!DIGlobalVariableExpression(var: ![[HVAR]]) + @g = common global i32 0, align 4, !dbg !0 @h = common global i32 0, align 4, !dbg !11 @@ -21,9 +25,9 @@ !llvm.ident = !{!9} !0 = distinct !DIGlobalVariable(name: "g", scope: !1, file: !2, line: 1, type: !5, isLocal: false, isDefinition: true, expr: !DIExpression(DW_OP_plus, 1)) -!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang version 4.0.0 (trunk 286129) (llvm/trunk 286128)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4) +!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang version 4.0.0 (trunk 286129) (llvm/trunk 286128)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, imports: !3) !2 = !DIFile(filename: "a.c", directory: "/") -!3 = !{} +!3 = !{!12} !4 = !{!0, !10, !11} !5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) !6 = !{i32 2, !"Dwarf Version", i32 4} @@ -32,3 +36,4 @@ !9 = !{!"clang version 4.0.0 (trunk 286129) (llvm/trunk 286128)"} !10 = distinct !DIGlobalVariable(name: "c", scope: !1, file: !2, line: 1, type: !5, isLocal: false, isDefinition: true, expr: !DIExpression(DW_OP_constu, 23, DW_OP_stack_value)) !11 = distinct !DIGlobalVariable(name: "h", scope: !1, file: !2, line: 2, type: !5, isLocal: false, isDefinition: true) +!12 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 1, scope: !1, entity: !11) Modified: vendor/llvm/dist/test/Bitcode/DIGlobalVariableExpression.ll.bc ============================================================================== Binary file (source and/or target). No diff available. Modified: vendor/llvm/dist/test/Bitcode/dityperefs-3.8.ll ============================================================================== --- vendor/llvm/dist/test/Bitcode/dityperefs-3.8.ll Sat Feb 11 07:35:27 2017 (r313632) +++ vendor/llvm/dist/test/Bitcode/dityperefs-3.8.ll Sat Feb 11 13:25:24 2017 (r313633) @@ -18,14 +18,13 @@ ; CHECK-NEXT: !7 = !DILocalVariable(name: "V1", scope: !6, type: !2) ; CHECK-NEXT: !8 = !DIObjCProperty(name: "P1", type: !1) ; CHECK-NEXT: !9 = !DITemplateTypeParameter(type: !1) -; CHECK-NEXT: !10 = distinct !DIGlobalVariableExpression(var: !11) -; CHECK-NEXT: !11 = !DIGlobalVariable(name: "G",{{.*}} type: !1, -; CHECK-NEXT: !12 = !DITemplateValueParameter(type: !1, value: i32* @G1) -; CHECK-NEXT: !13 = !DIImportedEntity(tag: DW_TAG_imported_module, name: "T2", scope: !0, entity: !1) -; CHECK-NEXT: !14 = !DICompositeType(tag: DW_TAG_structure_type, name: "T3", file: !0, elements: !15, identifier: "T3") -; CHECK-NEXT: !15 = !{!16} -; CHECK-NEXT: !16 = !DISubprogram(scope: !14, -; CHECK-NEXT: !17 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type,{{.*}} extraData: !14) +; CHECK-NEXT: !10 = !DIGlobalVariable(name: "G",{{.*}} type: !1, +; CHECK-NEXT: !11 = !DITemplateValueParameter(type: !1, value: i32* @G1) +; CHECK-NEXT: !12 = !DIImportedEntity(tag: DW_TAG_imported_module, name: "T2", scope: !0, entity: !1) +; CHECK-NEXT: !13 = !DICompositeType(tag: DW_TAG_structure_type, name: "T3", file: !0, elements: !14, identifier: "T3") +; CHECK-NEXT: !14 = !{!15} +; CHECK-NEXT: !15 = !DISubprogram(scope: !13, +; CHECK-NEXT: !16 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type,{{.*}} extraData: !13) !0 = !DIFile(filename: "path/to/file", directory: "/path/to/dir") !1 = !DICompositeType(tag: DW_TAG_structure_type, name: "T1", file: !0, identifier: "T1") Added: vendor/llvm/dist/test/CodeGen/AArch64/ldst-zero.ll ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm/dist/test/CodeGen/AArch64/ldst-zero.ll Sat Feb 11 13:25:24 2017 (r313633) @@ -0,0 +1,74 @@ +; RUN: llc -mtriple=aarch64 -mcpu=cortex-a53 < %s | FileCheck %s + +; Tests to check that zero stores which are generated as STP xzr, xzr aren't +; scheduled incorrectly due to incorrect alias information + +declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) +%struct.tree_common = type { i8*, i8*, i32 } + +; Original test case which exhibited the bug +define void @test1(%struct.tree_common* %t, i32 %code, i8* %type) { +; CHECK-LABEL: test1: +; CHECK: stp xzr, xzr, [x0, #8] +; CHECK: stp xzr, x2, [x0] +; CHECK: str w1, [x0, #16] +entry: + %0 = bitcast %struct.tree_common* %t to i8* + tail call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 24, i32 8, i1 false) + %code1 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 2 + store i32 %code, i32* %code1, align 8 + %type2 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 1 + store i8* %type, i8** %type2, align 8 + ret void +} + +; Store to each struct element instead of using memset +define void @test2(%struct.tree_common* %t, i32 %code, i8* %type) { +; CHECK-LABEL: test2: +; CHECK: stp xzr, xzr, [x0] +; CHECK: str wzr, [x0, #16] +; CHECK: str w1, [x0, #16] +; CHECK: str x2, [x0, #8] +entry: + %0 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 0 + %1 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 1 + %2 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 2 + store i8* zeroinitializer, i8** %0, align 8 + store i8* zeroinitializer, i8** %1, align 8 + store i32 zeroinitializer, i32* %2, align 8 + store i32 %code, i32* %2, align 8 + store i8* %type, i8** %1, align 8 + ret void +} + +; Vector store instead of memset +define void @test3(%struct.tree_common* %t, i32 %code, i8* %type) { +; CHECK-LABEL: test3: +; CHECK: stp xzr, xzr, [x0, #8] *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201702111325.v1BDPOx4075273>