diff options
| author | Michael Kuperstein <mkuper@google.com> | 2016-07-12 23:11:34 +0000 | 
|---|---|---|
| committer | Michael Kuperstein <mkuper@google.com> | 2016-07-12 23:11:34 +0000 | 
| commit | 51078b81ca7a8ef8fd20ce79f1ff637ad7bd387b (patch) | |
| tree | 5f3068011f68ac2ff24f67fbf4ea56030990b1e4 /llvm/lib/Transforms | |
| parent | d28fae834af6a9c841194f99409bd2a7a15c64cc (diff) | |
| download | bcm5719-llvm-51078b81ca7a8ef8fd20ce79f1ff637ad7bd387b.tar.gz bcm5719-llvm-51078b81ca7a8ef8fd20ce79f1ff637ad7bd387b.zip | |
[LV] Do not invalidate use-lists we're iterating over.
Should make sanitizers happier.
llvm-svn: 275230
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 29 | 
1 files changed, 15 insertions, 14 deletions
| diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index a8937b09f90..4bc3678646b 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3114,6 +3114,8 @@ void InnerLoopVectorizer::fixupIVUsers(PHINode *OrigPhi,    assert(OrigLoop->getExitBlock() && "Expected a single exit block"); +  DenseMap<Value *, Value *> MissingVals; +    // An external user of the last iteration's value should see the value that    // the remainder loop uses to initialize its own IV.    Value *PostInc = OrigPhi->getIncomingValueForBlock(OrigLoop->getLoopLatch()); @@ -3121,14 +3123,7 @@ void InnerLoopVectorizer::fixupIVUsers(PHINode *OrigPhi,      Instruction *UI = cast<Instruction>(U);      if (!OrigLoop->contains(UI)) {        assert(isa<PHINode>(UI) && "Expected LCSSA form"); -      // One corner case we have to handle is two IVs "chasing" each-other, -      // that is %IV2 = phi [...], [ %IV1, %latch ] -      // In this case, if IV1 has an external use, we need to avoid adding both -      // "last value of IV1" and "penultimate value of IV2". Since we don't know -      // which IV will be handled first, check we haven't handled this user yet. -      auto *User = cast<PHINode>(UI); -      if (User->getBasicBlockIndex(MiddleBlock) == -1) -        User->addIncoming(EndValue, MiddleBlock); +      MissingVals[UI] = EndValue;      }    } @@ -3140,12 +3135,7 @@ void InnerLoopVectorizer::fixupIVUsers(PHINode *OrigPhi,      if (!OrigLoop->contains(UI)) {        const DataLayout &DL =            OrigLoop->getHeader()->getModule()->getDataLayout(); -        assert(isa<PHINode>(UI) && "Expected LCSSA form"); -      auto *User = cast<PHINode>(UI); -      // As above, check we haven't already handled this user. -      if (User->getBasicBlockIndex(MiddleBlock) != -1) -        break;        IRBuilder<> B(MiddleBlock->getTerminator());        Value *CountMinusOne = B.CreateSub( @@ -3154,9 +3144,20 @@ void InnerLoopVectorizer::fixupIVUsers(PHINode *OrigPhi,                                         "cast.cmo");        Value *Escape = II.transform(B, CMO, PSE.getSE(), DL);        Escape->setName("ind.escape"); -      User->addIncoming(Escape, MiddleBlock); +      MissingVals[UI] = Escape;      }    } + +  for (auto &I : MissingVals) { +    PHINode *PHI = cast<PHINode>(I.first); +    // One corner case we have to handle is two IVs "chasing" each-other, +    // that is %IV2 = phi [...], [ %IV1, %latch ] +    // In this case, if IV1 has an external use, we need to avoid adding both +    // "last value of IV1" and "penultimate value of IV2". So, verify that we +    // don't already have an incoming value for the middle block. +    if (PHI->getBasicBlockIndex(MiddleBlock) == -1) +      PHI->addIncoming(I.second, MiddleBlock); +  }  }  namespace { | 

