diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1990,10 +1990,32 @@ UpperDef = dyn_cast(Def->getDefiningAccess()); if (!UpperDef || MSSA.isLiveOnEntryDef(UpperDef)) continue; - auto *DefInst = Def->getMemoryInst(); - auto *UpperInst = UpperDef->getMemoryInst(); + + Instruction *DefInst = Def->getMemoryInst(); + Instruction *UpperInst = UpperDef->getMemoryInst(); + auto IsRedundantStore = [this, DefInst, + UpperInst](MemoryLocation UpperLoc) { + if (DefInst->isIdenticalTo(UpperInst)) + return true; + if (auto *MemSetI = dyn_cast(UpperInst)) { + if (auto *SI = dyn_cast(DefInst)) { + auto MaybeDefLoc = getLocForWriteEx(DefInst); + if (!MaybeDefLoc) + return false; + int64_t InstWriteOffset = 0; + int64_t DepWriteOffset = 0; + auto OR = isOverwrite(UpperInst, DefInst, UpperLoc, *MaybeDefLoc, + InstWriteOffset, DepWriteOffset); + Value *StoredByte = isBytewiseValue(SI->getValueOperand(), DL); + return StoredByte && StoredByte == MemSetI->getOperand(1) && + OR == OW_Complete; + } + } + return false; + }; + auto MaybeUpperLoc = getLocForWriteEx(UpperInst); - if (!MaybeUpperLoc || !DefInst->isIdenticalTo(UpperInst) || + if (!MaybeUpperLoc || !IsRedundantStore(*MaybeUpperLoc) || isReadClobber(*MaybeUpperLoc, DefInst)) continue; deleteDeadInstruction(DefInst); @@ -2163,11 +2185,11 @@ } } - MadeChange |= State.eliminateRedundantStoresOfExistingValues(); if (EnablePartialOverwriteTracking) for (auto &KV : State.IOLs) MadeChange |= removePartiallyOverlappedStores(State.DL, KV.second, TLI); + MadeChange |= State.eliminateRedundantStoresOfExistingValues(); MadeChange |= State.eliminateDeadWritesAtEndOfFunction(); return MadeChange; } diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll --- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll +++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll @@ -402,8 +402,6 @@ define void @test12_memset_simple(i8* %ptr) { ; CHECK-LABEL: @test12_memset_simple( ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false) -; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 -; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1 ; CHECK-NEXT: ret void ; call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false) @@ -417,8 +415,6 @@ ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false) ; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 ; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1 -; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5 -; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1 ; CHECK-NEXT: ret void ; call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false)