diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-09-04 00:12:30 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-09-04 00:12:30 +0000 | 
| commit | 50506787d1d918b979f57c64ef4d64de76957eba (patch) | |
| tree | 296933f3e0219dd9224e53e7dea435b883e56ded | |
| parent | 3df9a8dfd7714dd6d03d5e1a93dbbfee736946bc (diff) | |
| download | bcm5719-llvm-50506787d1d918b979f57c64ef4d64de76957eba.tar.gz bcm5719-llvm-50506787d1d918b979f57c64ef4d64de76957eba.zip  | |
fix a bug in my licm rewrite when a load from the promoted memory
location is being re-stored to the memory location.  We would get
a dangling pointer from the SSAUpdate data structure and miss a 
use.  This fixes PR8068
llvm-svn: 113042
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 32 | ||||
| -rw-r--r-- | llvm/test/Transforms/LICM/crash.ll | 27 | 
2 files changed, 56 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index bf06fee6efb..0399329f0dd 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -743,6 +743,7 @@ void LICM::PromoteAliasSet(AliasSet &AS) {    // Okay, now we can iterate over all the blocks in the loop with uses,    // processing them.  Keep track of which loads are loading a live-in value.    SmallVector<LoadInst*, 32> LiveInLoads; +  DenseMap<Value*, Value*> ReplacedLoads;    for (unsigned LoopUse = 0, e = LoopUses.size(); LoopUse != e; ++LoopUse) {      Instruction *User = LoopUses[LoopUse]; @@ -792,15 +793,17 @@ void LICM::PromoteAliasSet(AliasSet &AS) {      Value *StoredValue = 0;      for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) {        if (LoadInst *L = dyn_cast<LoadInst>(II)) { -        // If this is a load to an unrelated pointer, ignore it. +        // If this is a load from an unrelated pointer, ignore it.          if (!PointerMustAliases.count(L->getOperand(0))) continue;          // If we haven't seen a store yet, this is a live in use, otherwise          // use the stored value. -        if (StoredValue) +        if (StoredValue) {            L->replaceAllUsesWith(StoredValue); -        else +          ReplacedLoads[L] = StoredValue; +        } else {            LiveInLoads.push_back(L); +        }          continue;        } @@ -846,12 +849,35 @@ void LICM::PromoteAliasSet(AliasSet &AS) {      Value *NewVal = SSA.GetValueInMiddleOfBlock(ALoad->getParent());      ALoad->replaceAllUsesWith(NewVal);      CurAST->copyValue(ALoad, NewVal); +    ReplacedLoads[ALoad] = NewVal;    }    // Now that everything is rewritten, delete the old instructions from the body    // of the loop.  They should all be dead now.    for (unsigned i = 0, e = LoopUses.size(); i != e; ++i) {      Instruction *User = LoopUses[i]; +     +    // If this is a load that still has uses, then the load must have been added +    // as a live value in the SSAUpdate data structure for a block (e.g. because +    // the loaded value was stored later).  In this case, we need to recursively +    // propagate the updates until we get to the real value. +    if (!User->use_empty()) { +      Value *NewVal = ReplacedLoads[User]; +      assert(NewVal && "not a replaced load?"); +       +      // Propagate down to the ultimate replacee.  The intermediately loads +      // could theoretically already have been deleted, so we don't want to +      // dereference the Value*'s. +      DenseMap<Value*, Value*>::iterator RLI = ReplacedLoads.find(NewVal); +      while (RLI != ReplacedLoads.end()) { +        NewVal = RLI->second; +        RLI = ReplacedLoads.find(NewVal); +      } +       +      User->replaceAllUsesWith(NewVal); +      CurAST->copyValue(User, NewVal); +    } +          CurAST->deleteValue(User);      User->eraseFromParent();    } diff --git a/llvm/test/Transforms/LICM/crash.ll b/llvm/test/Transforms/LICM/crash.ll new file mode 100644 index 00000000000..325f250bd58 --- /dev/null +++ b/llvm/test/Transforms/LICM/crash.ll @@ -0,0 +1,27 @@ +; RUN: opt -licm %s -disable-output + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin10.0.0" + + +; PR8068 +@g_12 = external global i8, align 1 +define void @test1() nounwind ssp { +entry: +  br label %for.body + +for.body:                                         ; preds = %for.cond, %bb.nph +  store i8 0, i8* @g_12, align 1 +  %tmp6 = load i8* @g_12, align 1 +  br label %for.cond + +for.cond:                                         ; preds = %for.body +  store i8 %tmp6, i8* @g_12, align 1 +  br i1 false, label %for.cond.for.end10_crit_edge, label %for.body + +for.cond.for.end10_crit_edge:                     ; preds = %for.cond +  br label %for.end10 + +for.end10:                                        ; preds = %for.cond.for.end10_crit_edge, %entry +  ret void +}  | 

