diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index bf1b689587c..3e634240901 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -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: diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index dd66416e7fe..d9f5bc51cbc 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -191,6 +191,7 @@ static bool isStoreAtLeastAsWideAs(Instruction *I1, Instruction *I2, I1Size >= I2Size; } + bool DSE::runOnBasicBlock(BasicBlock &BB) { MemoryDependenceAnalysis &MD = getAnalysis(); TD = getAnalysisIfAvailable(); @@ -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(Inst)) { - AliasAnalysis::Location Loc = - getAnalysis().getLocation(SI); - while (InstDep.isClobber() && isa(InstDep.getInst()) && - InstDep.getInst() != &BB.front()) - InstDep = MD.getPointerDependencyFrom(Loc, false, InstDep.getInst(), - &BB); + AliasAnalysis &AA = getAnalysis(); + 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); + } } } diff --git a/test/Transforms/DeadStoreElimination/simple.ll b/test/Transforms/DeadStoreElimination/simple.ll index 05e0d351dee..c426c0a08b6 100644 --- a/test/Transforms/DeadStoreElimination/simple.ll +++ b/test/Transforms/DeadStoreElimination/simple.ll @@ -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 +} +