<div dir="ltr">You can try running the script that the bot runs.<div><br></div>git clone <a href="http://llvm.org/git/zorg.git" target="_blank">http://llvm.org/git/zorg<wbr>.git</a><div>BUILDBOT_REVISION=319096 BUILDBOT_BUILDERNAME=sanitizer-x86_64-linux-bootstrap-ubsan BUILDBOT_CLOBBER="" zorg/zorg/buildbot/builders/sanitizers/buildbot_selector.py</div><div><br></div><div>That will run the UBSan bootstrap locally.</div><div>You could also try setting BUILDBOT_BUILDERNAME=sanitizer-x86_64-linux as that bot failed as well.<br></div><div><br></div><div>Can't say which one would be faster, since <a href="http://labs.llvm.org:8011">labs.llvm.org:8011</a> seems to be down.</div><div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 28, 2017 at 11:17 AM, Davide Italiano <span dir="ltr"><<a href="mailto:davide@freebsd.org" target="_blank">davide@freebsd.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I wasn't able to repro this locally, but maybe Matt has the conf of<br>
the bot where this failed available.<br>
<br>
Thanks!<br>
<br>
--<br>
Davide<br>
<div class="HOEnZb"><div class="h5"><br>
On Tue, Nov 28, 2017 at 3:33 AM, Ariel Ben-Yehuda <<a href="mailto:ariel.byd@gmail.com">ariel.byd@gmail.com</a>> wrote:<br>
> That's annoying. Any of you knows the best way to reproduce this locally?<br>
><br>
> On Tue, Nov 28, 2017 at 3:21 AM, Davide Italiano <<a href="mailto:davide@freebsd.org">davide@freebsd.org</a>> wrote:<br>
>><br>
>> Rafael is going to revert this soon as I don't have access to a machine<br>
>> now.<br>
>><br>
>> On Nov 27, 2017 5:13 PM, "Davide Italiano" <<a href="mailto:davide@freebsd.org">davide@freebsd.org</a>> wrote:<br>
>>><br>
>>> cc: ing ariel.<br>
>>> Matt, I can't repro this locally. Can you plwase revert while we<br>
>>> investigate?<br>
>>><br>
>>> On Nov 27, 2017 4:03 PM, "Matt Morehouse" <<a href="mailto:mascasa@google.com">mascasa@google.com</a>> wrote:<br>
>>><br>
>>> This patch seems to be breaking several bots with:<br>
>>><br>
>>> clang-6.0:<br>
>>> /var/lib/buildbot/sanitizer-<wbr>buildbot6/sanitizer-x86_64-<wbr>linux-android/build/llvm/lib/<wbr>Transforms/Utils/<wbr>PromoteMemoryToRegister.cpp:<wbr>254:<br>
>>> SmallVector<(anonymous namespace)::<wbr>GuaranteedExecutionRange, 4> (anonymous<br>
>>> namespace)::LargeBlockInfo::<wbr>computeGEI(const llvm::BasicBlock *): Assertion<br>
>>> `It != InstNumbers.end() && InstNo <= It->second && "missing number for<br>
>>> interesting instruction"' failed.<br>
>>><br>
>>> Please take a look.<br>
>>><br>
>>> On Mon, Nov 27, 2017 at 1:25 PM, Davide Italiano via llvm-commits<br>
>>> <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
>>>><br>
>>>> Author: davide<br>
>>>> Date: Mon Nov 27 13:25:13 2017<br>
>>>> New Revision: 319096<br>
>>>><br>
>>>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=319096&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=319096&view=rev</a><br>
>>>> Log:<br>
>>>> [SROA] Propagate !range metadata when moving loads.<br>
>>>><br>
>>>> This tries to propagate !range metadata to a pre-existing load<br>
>>>> when a load is optimized out. This is done instead of adding an<br>
>>>> assume because converting loads to and from assumes creates a<br>
>>>> lot of IR.<br>
>>>><br>
>>>> Patch by Ariel Ben-Yehuda.<br>
>>>><br>
>>>> Differential Revision:  <a href="https://reviews.llvm.org/D37216" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D37216</a><br>
>>>><br>
>>>> Modified:<br>
>>>>     llvm/trunk/lib/Transforms/<wbr>Scalar/SROA.cpp<br>
>>>>     llvm/trunk/lib/Transforms/<wbr>Utils/Local.cpp<br>
>>>>     llvm/trunk/lib/Transforms/<wbr>Utils/PromoteMemoryToRegister.<wbr>cpp<br>
>>>>     llvm/trunk/test/Transforms/<wbr>SROA/preserve-nonnull.ll<br>
>>>><br>
>>>> Modified: llvm/trunk/lib/Transforms/<wbr>Scalar/SROA.cpp<br>
>>>> URL:<br>
>>>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=319096&r1=319095&r2=319096&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>Transforms/Scalar/SROA.cpp?<wbr>rev=319096&r1=319095&r2=<wbr>319096&view=diff</a><br>
>>>><br>
>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>> --- llvm/trunk/lib/Transforms/<wbr>Scalar/SROA.cpp (original)<br>
>>>> +++ llvm/trunk/lib/Transforms/<wbr>Scalar/SROA.cpp Mon Nov 27 13:25:13 2017<br>
>>>> @@ -2455,15 +2455,10 @@ private:<br>
>>>>        // are different types, for example by mapping !nonnull metadata<br>
>>>> to<br>
>>>>        // !range metadata by modeling the null pointer constant<br>
>>>> converted to the<br>
>>>>        // integer type.<br>
>>>> -      // FIXME: Add support for range metadata here. Currently the<br>
>>>> utilities<br>
>>>> -      // for this don't propagate range metadata in trivial cases from<br>
>>>> one<br>
>>>> -      // integer load to another, don't handle non-addrspace-0 null<br>
>>>> pointers<br>
>>>> -      // correctly, and don't have any support for mapping ranges as<br>
>>>> the<br>
>>>> -      // integer type becomes winder or narrower.<br>
>>>>        if (MDNode *N = LI.getMetadata(LLVMContext::<wbr>MD_nonnull))<br>
>>>>          copyNonnullMetadata(LI, N, *NewLI);<br>
>>>> -<br>
>>>> -      // Try to preserve nonnull metadata<br>
>>>> +      if (MDNode *N = LI.getMetadata(LLVMContext::<wbr>MD_range))<br>
>>>> +        copyRangeMetadata(DL, LI, N, *NewLI);<br>
>>>>        V = NewLI;<br>
>>>><br>
>>>>        // If this is an integer load past the end of the slice (which<br>
>>>> means the<br>
>>>> @@ -3654,7 +3649,7 @@ bool SROA::presplitLoadsAndStores(<wbr>Alloca<br>
>>>>                           PartPtrTy, BasePtr->getName() + "."),<br>
>>>>            getAdjustedAlignment(LI, PartOffset, DL), /*IsVolatile*/<br>
>>>> false,<br>
>>>>            LI->getName());<br>
>>>> -      PLoad->copyMetadata(*LI,<br>
>>>> LLVMContext::MD_mem_parallel_<wbr>loop_access);<br>
>>>> +      PLoad->copyMetadata(*LI,<br>
>>>> LLVMContext::MD_mem_parallel_<wbr>loop_access);<br>
>>>><br>
>>>>        // Append this load onto the list of split loads so we can find<br>
>>>> it later<br>
>>>>        // to rewrite the stores.<br>
>>>><br>
>>>> Modified: llvm/trunk/lib/Transforms/<wbr>Utils/Local.cpp<br>
>>>> URL:<br>
>>>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=319096&r1=319095&r2=319096&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>Transforms/Utils/Local.cpp?<wbr>rev=319096&r1=319095&r2=<wbr>319096&view=diff</a><br>
>>>><br>
>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>> --- llvm/trunk/lib/Transforms/<wbr>Utils/Local.cpp (original)<br>
>>>> +++ llvm/trunk/lib/Transforms/<wbr>Utils/Local.cpp Mon Nov 27 13:25:13 2017<br>
>>>> @@ -1947,18 +1947,24 @@ void llvm::copyNonnullMetadata(<wbr>const Loa<br>
>>>>  void llvm::copyRangeMetadata(const DataLayout &DL, const LoadInst<br>
>>>> &OldLI,<br>
>>>>                               MDNode *N, LoadInst &NewLI) {<br>
>>>>    auto *NewTy = NewLI.getType();<br>
>>>> +  auto *OldTy = OldLI.getType();<br>
>>>><br>
>>>> -  // Give up unless it is converted to a pointer where there is a<br>
>>>> single very<br>
>>>> -  // valuable mapping we can do reliably.<br>
>>>> -  // FIXME: It would be nice to propagate this in more ways, but the<br>
>>>> type<br>
>>>> -  // conversions make it hard.<br>
>>>> -  if (!NewTy->isPointerTy())<br>
>>>> +  if (DL.getTypeStoreSizeInBits(<wbr>NewTy) == DL.getTypeSizeInBits(OldTy)<br>
>>>> &&<br>
>>>> +      NewTy->isIntegerTy()) {<br>
>>>> +    // An integer with the same number of bits - give it the range<br>
>>>> +    // metadata!.<br>
>>>> +    NewLI.setMetadata(LLVMContext:<wbr>:MD_range, N);<br>
>>>>      return;<br>
>>>> +  }<br>
>>>><br>
>>>> -  unsigned BitWidth = DL.getTypeSizeInBits(NewTy);<br>
>>>> -  if (!<wbr>getConstantRangeFromMetadata(*<wbr>N).contains(APInt(BitWidth, 0))) {<br>
>>>> -    MDNode *NN = MDNode::get(OldLI.getContext()<wbr>, None);<br>
>>>> -    NewLI.setMetadata(LLVMContext:<wbr>:MD_nonnull, NN);<br>
>>>> +  if (NewTy->isPointerTy()) {<br>
>>>> +    // Try to convert the !range metadata to !nonnull metadata on the<br>
>>>> +    // new pointer.<br>
>>>> +    unsigned BitWidth = DL.getTypeSizeInBits(NewTy);<br>
>>>> +    if (!<wbr>getConstantRangeFromMetadata(*<wbr>N).contains(APInt(BitWidth, 0)))<br>
>>>> {<br>
>>>> +      MDNode *NN = MDNode::get(OldLI.getContext()<wbr>, None);<br>
>>>> +      NewLI.setMetadata(LLVMContext:<wbr>:MD_nonnull, NN);<br>
>>>> +    }<br>
>>>>    }<br>
>>>>  }<br>
>>>><br>
>>>><br>
>>>> Modified: llvm/trunk/lib/Transforms/<wbr>Utils/PromoteMemoryToRegister.<wbr>cpp<br>
>>>> URL:<br>
>>>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=319096&r1=319095&r2=319096&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>Transforms/Utils/<wbr>PromoteMemoryToRegister.cpp?<wbr>rev=319096&r1=319095&r2=<wbr>319096&view=diff</a><br>
>>>><br>
>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>> --- llvm/trunk/lib/Transforms/<wbr>Utils/PromoteMemoryToRegister.<wbr>cpp<br>
>>>> (original)<br>
>>>> +++ llvm/trunk/lib/Transforms/<wbr>Utils/PromoteMemoryToRegister.<wbr>cpp Mon Nov<br>
>>>> 27 13:25:13 2017<br>
>>>> @@ -17,6 +17,7 @@<br>
>>>><br>
>>>>  #include "llvm/ADT/ArrayRef.h"<br>
>>>>  #include "llvm/ADT/DenseMap.h"<br>
>>>> +#include "llvm/ADT/Optional.h"<br>
>>>>  #include "llvm/ADT/STLExtras.h"<br>
>>>>  #include "llvm/ADT/SmallPtrSet.h"<br>
>>>>  #include "llvm/ADT/SmallVector.h"<br>
>>>> @@ -48,7 +49,7 @@<br>
>>>>  #include "llvm/Transforms/Utils/Local.<wbr>h"<br>
>>>>  #include "llvm/Transforms/Utils/<wbr>PromoteMemToReg.h"<br>
>>>>  #include <algorithm><br>
>>>> -#include <cassert><br>
>>>> +<br>
>>>>  #include <iterator><br>
>>>>  #include <utility><br>
>>>>  #include <vector><br>
>>>> @@ -177,6 +178,16 @@ public:<br>
>>>>    ValVector Values;<br>
>>>>  };<br>
>>>><br>
>>>> +/// \brief Semi-open interval of instructions that are guaranteed to<br>
>>>> +/// all execute if the first one does.<br>
>>>> +class GuaranteedExecutionRange {<br>
>>>> +public:<br>
>>>> +  unsigned Start;<br>
>>>> +  unsigned End;<br>
>>>> +<br>
>>>> +  GuaranteedExecutionRange(<wbr>unsigned S, unsigned E): Start(S), End(E) {}<br>
>>>> +};<br>
>>>> +<br>
>>>>  /// \brief This assigns and keeps a per-bb relative ordering of<br>
>>>> load/store<br>
>>>>  /// instructions in the block that directly load or store an alloca.<br>
>>>>  ///<br>
>>>> @@ -190,14 +201,109 @@ class LargeBlockInfo {<br>
>>>>    /// the block.<br>
>>>>    DenseMap<const Instruction *, unsigned> InstNumbers;<br>
>>>><br>
>>>> +  /// \brief For each basic block we track, keep track of the intervals<br>
>>>> +  /// of instruction numbers of instructions that transfer control<br>
>>>> +  /// to their successors, for propagating metadata.<br>
>>>> +  DenseMap<const BasicBlock *,<br>
>>>> Optional<SmallVector<<wbr>GuaranteedExecutionRange, 4>>><br>
>>>> +    GuaranteedExecutionIntervals;<br>
>>>> +<br>
>>>>  public:<br>
>>>><br>
>>>> -  /// This code only looks at accesses to allocas.<br>
>>>> +  /// This code looks for stores to allocas, and for loads both for<br>
>>>> +  /// allocas and for transferring metadata.<br>
>>>>    static bool isInterestingInstruction(const Instruction *I) {<br>
>>>> -    return (isa<LoadInst>(I) && isa<AllocaInst>(I->getOperand(<wbr>0))) ||<br>
>>>> +    return isa<LoadInst>(I) ||<br>
>>>>             (isa<StoreInst>(I) && isa<AllocaInst>(I->getOperand(<wbr>1)));<br>
>>>>    }<br>
>>>><br>
>>>> +  /// Compute the GuaranteedExecutionIntervals for a given BB.<br>
>>>> +  ///<br>
>>>> +  /// This is valid and remains valid as long as each interesting<br>
>>>> +  /// instruction (see isInterestingInstruction) that<br>
>>>> +  ///   A) existed when this LBI was cleared<br>
>>>> +  ///   B) has not been deleted (deleting interesting instructions is<br>
>>>> fine)<br>
>>>> +  /// are run in the same program executions and in the same order<br>
>>>> +  /// as when this LBI was cleared.<br>
>>>> +  ///<br>
>>>> +  /// Because `PromoteMemoryToRegister` does not move memory loads at<br>
>>>> +  /// all, this assumption is satisfied in this pass.<br>
>>>> +  SmallVector<<wbr>GuaranteedExecutionRange, 4> computeGEI(const BasicBlock<br>
>>>> *BB) {<br>
>>>> +    SmallVector<<wbr>GuaranteedExecutionRange, 4><br>
>>>> GuaranteedExecutionIntervals;<br>
>>>> +<br>
>>>> +    unsigned InstNo = 0;<br>
>>>> +    bool InRange = false;<br>
>>>> +    unsigned FirstInstInRange = 0;<br>
>>>> +    for (const Instruction &BBI : *BB) {<br>
>>>> +      if (<wbr>isGuaranteedToTransferExecutio<wbr>nToSuccessor(&BBI)) {<br>
>>>> +        if (!InRange && isInterestingInstruction(&BBI)<wbr>) {<br>
>>>> +          InRange = true;<br>
>>>> +          FirstInstInRange = InstNo;<br>
>>>> +        }<br>
>>>> +      } else {<br>
>>>> +        if (InRange) {<br>
>>>> +          assert(FirstInstInRange < InstNo && "Can't push an empty<br>
>>>> range here.");<br>
>>>> +          GuaranteedExecutionIntervals.<wbr>emplace_back(FirstInstInRange,<br>
>>>> InstNo);<br>
>>>> +        }<br>
>>>> +        InRange = false;<br>
>>>> +      }<br>
>>>> +<br>
>>>> +      if (isInterestingInstruction(&<wbr>BBI)) {<br>
>>>> +        auto It = InstNumbers.find(&BBI);<br>
>>>> +        assert(It != InstNumbers.end() &&<br>
>>>> +               InstNo <= It->second &&<br>
>>>> +               "missing number for interesting instruction");<br>
>>>> +        InstNo = It->second + 1;<br>
>>>> +      }<br>
>>>> +    }<br>
>>>> +<br>
>>>> +    if (InRange) {<br>
>>>> +      assert(FirstInstInRange < InstNo && "Can't push an empty range<br>
>>>> here.");<br>
>>>> +      GuaranteedExecutionIntervals.<wbr>emplace_back(FirstInstInRange,<br>
>>>> InstNo);<br>
>>>> +    }<br>
>>>> +<br>
>>>> +    return GuaranteedExecutionIntervals;<br>
>>>> +  }<br>
>>>> +<br>
>>>> +  /// Return true if, when CxtI executes, it is guaranteed that either<br>
>>>> +  /// I had executed already or that I is guaranteed to be later<br>
>>>> executed.<br>
>>>> +  ///<br>
>>>> +  /// The useful property this guarantees is that if I exhibits<br>
>>>> undefined<br>
>>>> +  /// behavior under some circumstances, then the whole program will<br>
>>>> exhibit<br>
>>>> +  /// undefined behavior at CxtI.<br>
>>>> +  bool isGuaranteedToBeExecuted(const Instruction *CxtI, const<br>
>>>> Instruction *I) {<br>
>>>> +    const BasicBlock *BB = CxtI->getParent();<br>
>>>> +<br>
>>>> +    if (BB != I->getParent()) {<br>
>>>> +      // Instructions in different basic blocks, so control flow<br>
>>>> +      // can diverge between them (we could track this with<br>
>>>> +      // postdoms, but we don't bother).<br>
>>>> +      return false;<br>
>>>> +    }<br>
>>>> +<br>
>>>> +    unsigned Index1 = getInstructionIndex(CxtI);<br>
>>>> +    unsigned Index2 = getInstructionIndex(I);<br>
>>>> +<br>
>>>> +    auto& BBGEI = GuaranteedExecutionIntervals[<wbr>BB];<br>
>>>> +    if (!BBGEI.hasValue()) {<br>
>>>> +      BBGEI.emplace(computeGEI(BB));<br>
>>>> +    }<br>
>>>> +<br>
>>>> +    // We want to check whether I and CxtI are in the same range. To do<br>
>>>> that,<br>
>>>> +    // we notice that CxtI can only be in the first range R where<br>
>>>> +    // CxtI.end < R.end. If we find that range using binary search,<br>
>>>> +    // we can check whether I and CxtI are both in it.<br>
>>>> +    GuaranteedExecutionRange Bound(Index1, Index1);<br>
>>>> +    auto R = std::upper_bound(<br>
>>>> +      BBGEI->begin(), BBGEI->end(), Bound,<br>
>>>> +      [](GuaranteedExecutionRange I_, GuaranteedExecutionRange R) {<br>
>>>> +        return I_.End < R.End;<br>
>>>> +      });<br>
>>>> +<br>
>>>> +    return R != BBGEI->end() &&<br>
>>>> +      R->Start <= Index1 && Index1 < R->End &&<br>
>>>> +      R->Start <= Index2 && Index2 < R->End;<br>
>>>> +  }<br>
>>>> +<br>
>>>>    /// Get or calculate the index of the specified instruction.<br>
>>>>    unsigned getInstructionIndex(const Instruction *I) {<br>
>>>>      assert(<wbr>isInterestingInstruction(I) &&<br>
>>>> @@ -213,9 +319,11 @@ public:<br>
>>>>      // avoid gratuitus rescans.<br>
>>>>      const BasicBlock *BB = I->getParent();<br>
>>>>      unsigned InstNo = 0;<br>
>>>> +    GuaranteedExecutionIntervals.<wbr>erase(BB);<br>
>>>>      for (const Instruction &BBI : *BB)<br>
>>>>        if (isInterestingInstruction(&<wbr>BBI))<br>
>>>>          InstNumbers[&BBI] = InstNo++;<br>
>>>> +<br>
>>>>      It = InstNumbers.find(I);<br>
>>>><br>
>>>>      assert(It != InstNumbers.end() && "Didn't insert instruction?");<br>
>>>> @@ -224,7 +332,10 @@ public:<br>
>>>><br>
>>>>    void deleteValue(const Instruction *I) { InstNumbers.erase(I); }<br>
>>>><br>
>>>> -  void clear() { InstNumbers.clear(); }<br>
>>>> +  void clear() {<br>
>>>> +    InstNumbers.clear();<br>
>>>> +    GuaranteedExecutionIntervals.<wbr>clear();<br>
>>>> +  }<br>
>>>>  };<br>
>>>><br>
>>>>  struct PromoteMem2Reg {<br>
>>>> @@ -303,6 +414,7 @@ private:<br>
>>>>                             SmallPtrSetImpl<BasicBlock *><br>
>>>> &LiveInBlocks);<br>
>>>>    void RenamePass(BasicBlock *BB, BasicBlock *Pred,<br>
>>>>                    RenamePassData::ValVector &IncVals,<br>
>>>> +                  LargeBlockInfo &LBI,<br>
>>>>                    std::vector<RenamePassData> &Worklist);<br>
>>>>    bool QueuePhiNode(BasicBlock *BB, unsigned AllocaIdx, unsigned<br>
>>>> &Version);<br>
>>>>  };<br>
>>>> @@ -321,6 +433,32 @@ static void addAssumeNonNull(AssumptionC<br>
>>>>    AC->registerAssumption(CI);<br>
>>>>  }<br>
>>>><br>
>>>> +static void addAssumptionsFromMetadata(<wbr>LoadInst *LI,<br>
>>>> +                                       Value *ReplVal,<br>
>>>> +                                       DominatorTree &DT,<br>
>>>> +                                       const DataLayout &DL,<br>
>>>> +              LargeBlockInfo &LBI,<br>
>>>> +                                       AssumptionCache *AC)<br>
>>>> +{<br>
>>>> +  if (LI->getMetadata(LLVMContext::<wbr>MD_nonnull) &&<br>
>>>> +      !isKnownNonZero(ReplVal, DL, 0, AC, LI, &DT)) {<br>
>>>> +    addAssumeNonNull(AC, LI);<br>
>>>> +  }<br>
>>>> +<br>
>>>> +  if (auto *N = LI->getMetadata(LLVMContext::<wbr>MD_range)) {<br>
>>>> +    // Range metadata is harder to use as an assumption,<br>
>>>> +    // so don't try to add one, but *do* try to copy<br>
>>>> +    // the metadata to a load in the same BB.<br>
>>>> +    if (LoadInst *NewLI = dyn_cast<LoadInst>(ReplVal)) {<br>
>>>> +      DEBUG(dbgs() << "trying to move !range metadata from" <<<br>
>>>> +        *LI << " to" << *NewLI << "\n");<br>
>>>> +      if (LBI.isGuaranteedToBeExecuted(<wbr>LI, NewLI)) {<br>
>>>> +        copyRangeMetadata(DL, *LI, N, *NewLI);<br>
>>>> +      }<br>
>>>> +    }<br>
>>>> +  }<br>
>>>> +}<br>
>>>> +<br>
>>>>  static void removeLifetimeIntrinsicUsers(<wbr>AllocaInst *AI) {<br>
>>>>    // Knowing that this alloca is promotable, we know that it's safe to<br>
>>>> kill all<br>
>>>>    // instructions except for load and store.<br>
>>>> @@ -409,9 +547,7 @@ static bool rewriteSingleStoreAlloca(All<br>
>>>>      // If the load was marked as nonnull we don't want to lose<br>
>>>>      // that information when we erase this Load. So we preserve<br>
>>>>      // it with an assume.<br>
>>>> -    if (AC && LI->getMetadata(LLVMContext::<wbr>MD_nonnull) &&<br>
>>>> -        !isKnownNonZero(ReplVal, DL, 0, AC, LI, &DT))<br>
>>>> -      addAssumeNonNull(AC, LI);<br>
>>>> +    addAssumptionsFromMetadata(LI, ReplVal, DT, DL, LBI, AC);<br>
>>>><br>
>>>>      LI->replaceAllUsesWith(<wbr>ReplVal);<br>
>>>>      LI->eraseFromParent();<br>
>>>> @@ -505,9 +641,7 @@ static bool promoteSingleBlockAlloca(All<br>
>>>>        // Note, if the load was marked as nonnull we don't want to lose<br>
>>>> that<br>
>>>>        // information when we erase it. So we preserve it with an<br>
>>>> assume.<br>
>>>>        Value *ReplVal = std::prev(I)->second-><wbr>getOperand(0);<br>
>>>> -      if (AC && LI->getMetadata(LLVMContext::<wbr>MD_nonnull) &&<br>
>>>> -          !isKnownNonZero(ReplVal, DL, 0, AC, LI, &DT))<br>
>>>> -        addAssumeNonNull(AC, LI);<br>
>>>> +      addAssumptionsFromMetadata(LI, ReplVal, DT, DL, LBI, AC);<br>
>>>><br>
>>>>        LI->replaceAllUsesWith(<wbr>ReplVal);<br>
>>>>      }<br>
>>>> @@ -643,7 +777,6 @@ void PromoteMem2Reg::run() {<br>
>>>><br>
>>>>    if (Allocas.empty())<br>
>>>>      return; // All of the allocas must have been trivial!<br>
>>>> -<br>
>>>>    LBI.clear();<br>
>>>><br>
>>>>    // Set the incoming values for the basic block to be null values for<br>
>>>> all of<br>
>>>> @@ -661,9 +794,10 @@ void PromoteMem2Reg::run() {<br>
>>>>      RenamePassData RPD = std::move(RenamePassWorkList.<wbr>back());<br>
>>>>      RenamePassWorkList.pop_back();<br>
>>>>      // RenamePass may add new worklist entries.<br>
>>>> -    RenamePass(<a href="http://RPD.BB" rel="noreferrer" target="_blank">RPD.BB</a>, RPD.Pred, RPD.Values, RenamePassWorkList);<br>
>>>> +    RenamePass(<a href="http://RPD.BB" rel="noreferrer" target="_blank">RPD.BB</a>, RPD.Pred, RPD.Values, LBI, RenamePassWorkList);<br>
>>>>    } while (!RenamePassWorkList.empty());<br>
>>>><br>
>>>> +  LBI.clear();<br>
>>>>    // The renamer uses the Visited set to avoid infinite loops.  Clear<br>
>>>> it now.<br>
>>>>    Visited.clear();<br>
>>>><br>
>>>> @@ -875,6 +1009,7 @@ bool PromoteMem2Reg::QueuePhiNode(<wbr>BasicB<br>
>>>>  /// predecessor block Pred.<br>
>>>>  void PromoteMem2Reg::RenamePass(<wbr>BasicBlock *BB, BasicBlock *Pred,<br>
>>>>                                  RenamePassData::ValVector<br>
>>>> &IncomingVals,<br>
>>>> +       LargeBlockInfo &LBI,<br>
>>>>                                  std::vector<RenamePassData> &Worklist)<br>
>>>> {<br>
>>>>  NextIteration:<br>
>>>>    // If we are inserting any phi nodes into this BB, they will already<br>
>>>> be in the<br>
>>>> @@ -941,13 +1076,12 @@ NextIteration:<br>
>>>>        // If the load was marked as nonnull we don't want to lose<br>
>>>>        // that information when we erase this Load. So we preserve<br>
>>>>        // it with an assume.<br>
>>>> -      if (AC && LI->getMetadata(LLVMContext::<wbr>MD_nonnull) &&<br>
>>>> -          !isKnownNonZero(V, SQ.DL, 0, AC, LI, &DT))<br>
>>>> -        addAssumeNonNull(AC, LI);<br>
>>>> +      addAssumptionsFromMetadata(LI, V, DT, SQ.DL, LBI, AC);<br>
>>>><br>
>>>>        // Anything using the load now uses the current value.<br>
>>>>        LI->replaceAllUsesWith(V);<br>
>>>>        BB->getInstList().erase(LI);<br>
>>>> +      LBI.deleteValue(LI);<br>
>>>>      } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {<br>
>>>>        // Delete this instruction and mark the name as the current<br>
>>>> holder of the<br>
>>>>        // value<br>
>>>> @@ -965,6 +1099,7 @@ NextIteration:<br>
>>>>        for (DbgInfoIntrinsic *DII : AllocaDbgDeclares[ai->second])<br>
>>>>          ConvertDebugDeclareToDebugValu<wbr>e(DII, SI, DIB);<br>
>>>>        BB->getInstList().erase(SI);<br>
>>>> +      LBI.deleteValue(SI);<br>
>>>>      }<br>
>>>>    }<br>
>>>><br>
>>>><br>
>>>> Modified: llvm/trunk/test/Transforms/<wbr>SROA/preserve-nonnull.ll<br>
>>>> URL:<br>
>>>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SROA/preserve-nonnull.ll?rev=319096&r1=319095&r2=319096&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>Transforms/SROA/preserve-<wbr>nonnull.ll?rev=319096&r1=<wbr>319095&r2=319096&view=diff</a><br>
>>>><br>
>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>> --- llvm/trunk/test/Transforms/<wbr>SROA/preserve-nonnull.ll (original)<br>
>>>> +++ llvm/trunk/test/Transforms/<wbr>SROA/preserve-nonnull.ll Mon Nov 27<br>
>>>> 13:25:13 2017<br>
>>>> @@ -3,6 +3,8 @@<br>
>>>>  ; Make sure that SROA doesn't lose nonnull metadata<br>
>>>>  ; on loads from allocas that get optimized out.<br>
>>>><br>
>>>> +%pair = type { i64, [0 x i64], [1 x i64] }<br>
>>>> +<br>
>>>>  declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8*<br>
>>>> nocapture readonly, i64, i32, i1)<br>
>>>><br>
>>>>  ; Check that we do basic propagation of nonnull when rewriting.<br>
>>>> @@ -42,6 +44,23 @@ entry:<br>
>>>>    ret float* %ret<br>
>>>>  }<br>
>>>><br>
>>>> +; Make sure we propagate the !range attribute when we expand loads.<br>
>>>> +define i64 @propagate_range(%pair* dereferenceable(16)) {<br>
>>>> +; CHECK-LABEL: define i64 @propagate_range(<br>
>>>> +; CHECK-NEXT:  start:<br>
>>>> +; CHECK-NEXT:      %[[SROA_IDX:.*]] = getelementptr inbounds %pair<br>
>>>> +; CHECK-NEXT:      %[[RESULT:.*]] = load i64, i64* %[[SROA_IDX]], align<br>
>>>> 8, !range !1<br>
>>>> +; CHECK:           ret i64 %[[RESULT]]<br>
>>>> +start:<br>
>>>> +  %a = alloca %pair<br>
>>>> +  %1 = bitcast %pair* %0 to i8*<br>
>>>> +  %2 = bitcast %pair* %a to i8*<br>
>>>> +  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %1, i64 16, i32 8,<br>
>>>> i1 false)<br>
>>>> +  %3 = getelementptr inbounds %pair, %pair* %a, i32 0, i32 0<br>
>>>> +  %4 = load i64, i64* %3, !range !1<br>
>>>> +  ret i64 %4<br>
>>>> +}<br>
>>>> +<br>
>>>>  ; Make sure we properly handle the !nonnull attribute when we convert<br>
>>>>  ; a pointer load to an integer load.<br>
>>>>  ; FIXME: While this doesn't do anythnig actively harmful today, it<br>
>>>> really<br>
>>>> @@ -90,3 +109,4 @@ entry:<br>
>>>>  }<br>
>>>><br>
>>>>  !0 = !{}<br>
>>>> +!1 = !{i64 0, i64 2}<br>
>>>><br>
>>>><br>
>>>> ______________________________<wbr>_________________<br>
>>>> llvm-commits mailing list<br>
>>>> <a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
>>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
>>><br>
>>><br>
>>><br>
><br>
<br>
<br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
Davide<br>
<br>
"There are no solved problems; there are only problems that are more<br>
or less solved" -- Henri Poincare<br>
</font></span></blockquote></div><br></div>