Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp =================================================================== --- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -2367,6 +2367,46 @@ return false; } + bool eliminateDeadStoresOfExisitingValues() { + bool MadeChange = false; + LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs that write the " + "already exisiting value\n"); + for (int I = MemDefs.size() - 1; I >= 0; I--) { + MemoryDef *Def = MemDefs[I]; + SmallVector WorkList; + SmallPtrSet Visited; + auto PushMemUses = [&WorkList, &Visited](MemoryAccess *Acc) { + if (!Visited.insert(Acc).second) + return; + for (Use &U : Acc->uses()) + WorkList.push_back(cast(U.getUser())); + }; + PushMemUses(Def); + for (unsigned I = 0; I < WorkList.size(); I++) { + if (WorkList.size() >= MemorySSAScanLimit) { + LLVM_DEBUG(dbgs() << " ... hit exploration limit.\n"); + return false; + } + MemoryAccess *UseAccess = WorkList[I]; + if (isa(UseAccess)) + continue; + + Instruction *UseInst = cast(UseAccess)->getMemoryInst(); + if (MemoryDef *UseDef = dyn_cast(UseAccess)) { + MemoryAccess *tmp = UseDef->getDefiningAccess(); + Instruction *tmpi = cast(tmp)->getMemoryInst(); + if (tmpi->isIdenticalTo(UseInst)) { + deleteDeadInstruction(UseInst); + MadeChange = true; + } else { + PushMemUses(UseDef); + } + } + } + } + return MadeChange; + } + /// Eliminate writes to objects that are not visible in the caller and are not /// accessed before returning from the function. bool eliminateDeadWritesAtEndOfFunction() { @@ -2632,7 +2672,7 @@ } } } - + MadeChange |= State.eliminateDeadStoresOfExisitingValues(); if (EnablePartialOverwriteTracking) for (auto &KV : State.IOLs) MadeChange |= removePartiallyOverlappedStores(State.DL, KV.second, TLI); Index: llvm/test/Transforms/DeadStoreElimination/MSSA/pr16520.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/DeadStoreElimination/MSSA/pr16520.ll @@ -0,0 +1,25 @@ +; ModuleID = 'pr16520.cc' +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-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @_Z1fbRb(i1 zeroext %b, i8* nocapture %r) { +entry: + store i8 1, i8* %r, align 1 + br i1 %b, label %if.then, label %if.else + +if.then: ; preds = %entry + store i8 1, i8* %r, align 1 + tail call void @_Z1gv() + br label %if.end + +if.else: ; preds = %entry + tail call void @_Z1hv() + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +declare void @_Z1gv() + +declare void @_Z1hv()