Index: lib/Transforms/Scalar/DeadStoreElimination.cpp =================================================================== --- lib/Transforms/Scalar/DeadStoreElimination.cpp +++ lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1172,7 +1172,8 @@ auto *Earlier = dyn_cast(DepWrite); auto *Later = dyn_cast(Inst); if (Earlier && isa(Earlier->getValueOperand()) && - Later && isa(Later->getValueOperand())) { + Later && isa(Later->getValueOperand()) && + memoryIsNotModifiedBetween(Earlier, Later, AA)) { // If the store we find is: // a) partially overwritten by the store to 'Loc' // b) the later store is fully contained in the earlier one and Index: test/Transforms/DeadStoreElimination/merge-stores.ll =================================================================== --- test/Transforms/DeadStoreElimination/merge-stores.ll +++ test/Transforms/DeadStoreElimination/merge-stores.ll @@ -186,12 +186,14 @@ ret void } -; FIXME: We can't eliminate the last store because P and Q may alias. +; We can't eliminate the last store because P and Q may alias. define void @PR36129(i32* %P, i32* %Q) { ; CHECK-LABEL: @PR36129( -; CHECK-NEXT: store i32 3, i32* [[P:%.*]] +; CHECK-NEXT: store i32 1, i32* [[P:%.*]] +; CHECK-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to i8* ; CHECK-NEXT: store i32 2, i32* [[Q:%.*]] +; CHECK-NEXT: store i8 3, i8* [[P2]] ; CHECK-NEXT: ret void ; store i32 1, i32* %P