[llvm-commits] [llvm] r113042 - in /llvm/trunk: lib/Transforms/Scalar/LICM.cpp test/Transforms/LICM/crash.ll

Chris Lattner sabre at nondot.org
Fri Sep 3 17:12:30 PDT 2010


Author: lattner
Date: Fri Sep  3 19:12:30 2010
New Revision: 113042

URL: http://llvm.org/viewvc/llvm-project?rev=113042&view=rev
Log:
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

Added:
    llvm/trunk/test/Transforms/LICM/crash.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/LICM.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=113042&r1=113041&r2=113042&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Fri Sep  3 19:12:30 2010
@@ -743,6 +743,7 @@
   // 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 @@
     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 @@
     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();
   }

Added: llvm/trunk/test/Transforms/LICM/crash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/crash.ll?rev=113042&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LICM/crash.ll (added)
+++ llvm/trunk/test/Transforms/LICM/crash.ll Fri Sep  3 19:12:30 2010
@@ -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
+ at 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
+}





More information about the llvm-commits mailing list