implement PR8576, deleting dead stores with intervening may-alias stores.
authorChris Lattner <sabre@nondot.org>
Sun, 21 Nov 2010 07:34:32 +0000 (07:34 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 21 Nov 2010 07:34:32 +0000 (07:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119927 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/MemoryDependenceAnalysis.h
lib/Analysis/MemoryDependenceAnalysis.cpp
lib/Transforms/Scalar/DeadStoreElimination.cpp
test/Transforms/DeadStoreElimination/simple.ll

index cc34992b45699b648f4ef56bedcf29cf647f92b0..c9c8116dc516a0987d2ea84dd281dc0afae6858a 100644 (file)
@@ -335,11 +335,19 @@ namespace llvm {
     /// critical edges.
     void invalidateCachedPredecessors();
     
-  private:
+    /// getPointerDependencyFrom - Return the instruction on which a memory
+    /// location depends.  If isLoad is true, this routine ignores may-aliases
+    /// with read-only operations.  If isLoad is false, this routine ignores
+    /// may-aliases with reads from read-only locations.
+    ///
+    /// Note that this is an uncached query, and thus may be inefficient.
+    ///
     MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
                                           bool isLoad, 
                                           BasicBlock::iterator ScanIt,
                                           BasicBlock *BB);
+    
+  private:
     MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
                                            BasicBlock::iterator ScanIt,
                                            BasicBlock *BB);
index a16e334e020ef79380f3631d5557428bfcffcfc7..5fdf9a9c1a782d1171d59f7de7130d60bbaae438 100644 (file)
@@ -409,9 +409,9 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) {
     if (MemLoc.Ptr) {
       // If we can do a pointer scan, make it happen.
       bool isLoad = !(MR & AliasAnalysis::Mod);
-      if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst)) {
+      if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst))
         isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_end;
-      }
+
       LocalCache = getPointerDependencyFrom(MemLoc, isLoad, ScanPos,
                                             QueryParent);
     } else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
index 1ea0b15e4c9a7eecec1aecf00fbc957d9a4c2a50..02df1031e6046634b9156170898768c76ac3c9ca 100644 (file)
@@ -217,9 +217,28 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
       continue;
     }
     
-    // If not a definite must-alias dependency, ignore it.
-    if (!InstDep.isDef())
-      continue;
+    if (!InstDep.isDef()) {
+      // If this is a may-aliased store that is clobbering the store value, we
+      // can keep searching past it for another must-aliased pointer that stores
+      // to the same location.  For example, in:
+      //   store -> P
+      //   store -> Q
+      //   store -> P
+      // we can remove the first store to P even though we don't know if P and Q
+      // alias.
+      if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
+        AliasAnalysis::Location Loc =
+          getAnalysis<AliasAnalysis>().getLocation(SI);
+        while (InstDep.isClobber() && isa<StoreInst>(InstDep.getInst()) &&
+               InstDep.getInst() != &BB.front())
+          InstDep = MD.getPointerDependencyFrom(Loc, false, InstDep.getInst(),
+                                                &BB);
+      }
+        
+      // If not a definite must-alias dependency, ignore it.
+      if (!InstDep.isDef())
+        continue;
+    }
     
     // If this is a store-store dependence, then the previous store is dead so
     // long as this store is at least as big as it.
index f0c140d50a388afb8c1b6fa94e2a2677a8e801c1..0a16603f55d5503d88b2940b2c12cd765687117b 100644 (file)
@@ -11,3 +11,12 @@ define void @test1(i32* %Q, i32* %P) {
 ; CHECK-NEXT: ret void
 }
 
+; PR8576 - Should delete store of 10 even though p/q are may aliases.
+define void @test2(i32 *%p, i32 *%q) {
+  store i32 10, i32* %p, align 4
+  store i32 20, i32* %q, align 4
+  store i32 30, i32* %p, align 4
+  ret void
+; CHECK: @test2
+; CHECK-NEXT: store i32 20
+}