Teach basicaa that memset's modref set is at worst "mod" and never
authorChris Lattner <sabre@nondot.org>
Tue, 30 Nov 2010 00:28:45 +0000 (00:28 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 30 Nov 2010 00:28:45 +0000 (00:28 +0000)
contains "ref".

Enhance DSE to use a modref query instead of a store-specific hack
to generalize the "ignore may-alias stores" optimization to handle
memset and memcpy.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120368 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/BasicAliasAnalysis.cpp
lib/Transforms/Scalar/DeadStoreElimination.cpp
test/Transforms/DeadStoreElimination/simple.ll

index bf1b689587c9a61089ef654472d5306978d892a7..3e634240901f70b92bb586084e8c7d356863965b 100644 (file)
@@ -703,6 +703,8 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
         if (isNoAlias(Location(Dest, Len), Loc))
           return NoModRef;
       }
+      // We know that memset doesn't load anything.
+      Min = Mod;
       break;
     case Intrinsic::atomic_cmp_swap:
     case Intrinsic::atomic_swap:
index dd66416e7fe29cf7f87b84ae2f6e11d639da85d7..d9f5bc51cbc229a1517fc409fdb7d0e6d3005dcc 100644 (file)
@@ -191,6 +191,7 @@ static bool isStoreAtLeastAsWideAs(Instruction *I1, Instruction *I2,
          I1Size >= I2Size;
 }
 
+
 bool DSE::runOnBasicBlock(BasicBlock &BB) {
   MemoryDependenceAnalysis &MD = getAnalysis<MemoryDependenceAnalysis>();
   TD = getAnalysisIfAvailable<TargetData>();
@@ -239,7 +240,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
         }
       }
     }
-     
+
     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
@@ -250,12 +251,16 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
       // 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);
+        AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+        AliasAnalysis::Location Loc = AA.getLocation(SI);
+        while (InstDep.isClobber() && InstDep.getInst() != &BB.front()) {
+          // Can't look past this instruction if it might read 'Loc'.
+          if (AA.getModRefInfo(InstDep.getInst(), Loc) & AliasAnalysis::Ref)
+            break;
+          
+          InstDep = MD.getPointerDependencyFrom(Loc, false,
+                                                InstDep.getInst(), &BB);
+        }
       }
     }
     
index 05e0d351dee9188b94f22b0beacb2f22874ed183..c426c0a08b6e19449c3b3ab9d2779d83adf2e3b8 100644 (file)
@@ -54,3 +54,17 @@ define void @test5(i32* %Q) {
 ; CHECK-NEXT: volatile load
 ; CHECK-NEXT: ret void
 }
+
+declare void @llvm.memset.i32(i8*, i8, i32, i32)
+
+; Should delete store of 10 even though memset is a may-store to P (P and Q may
+; alias).
+define void @test6(i32 *%p, i8 *%q) {
+  store i32 10, i32* %p, align 4       ;; dead.
+  call void @llvm.memset.i32(i8* %q, i8 42, i32 900, i32 1)
+  store i32 30, i32* %p, align 4
+  ret void
+; CHECK: @test6
+; CHECK-NEXT: call void @llvm.memset
+}
+