Index: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp =================================================================== --- llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -478,7 +478,7 @@ Args.insert(Ptr); // Instruction to lift before P. - SmallVector ToLift; + SmallVector ToLift{SI}; // Memory locations of lifted instructions. SmallVector MemLocs{StoreLoc}; @@ -544,10 +544,20 @@ } } - // We made it, we need to lift + // We made it, we need to lift. + MemoryUseOrDef *MemInsertPoint = + MSSAU ? MSSAU->getMemorySSA()->getMemoryAccess(P) : nullptr; for (auto *I : llvm::reverse(ToLift)) { LLVM_DEBUG(dbgs() << "Lifting " << *I << " before " << *P << "\n"); I->moveBefore(P); + if (MSSAU) { + if (MemoryUseOrDef *MA = MSSAU->getMemorySSA()->getMemoryAccess(I)) { + if (MemInsertPoint) + MSSAU->moveBefore(MA, MemInsertPoint); + else + MemInsertPoint = MA; + } + } } return true; @@ -631,9 +641,8 @@ << *M << "\n"); if (MSSAU) { - assert(isa(MSSAU->getMemorySSA()->getMemoryAccess(P))); auto *LastDef = - cast(MSSAU->getMemorySSA()->getMemoryAccess(P)); + cast(MSSAU->getMemorySSA()->getMemoryAccess(SI)); auto *NewAccess = MSSAU->createMemoryAccessAfter(M, LastDef, LastDef); MSSAU->insertDef(cast(NewAccess), /*RenameUses=*/true); Index: llvm/test/Transforms/MemCpyOpt/preserve-memssa.ll =================================================================== --- llvm/test/Transforms/MemCpyOpt/preserve-memssa.ll +++ llvm/test/Transforms/MemCpyOpt/preserve-memssa.ll @@ -148,6 +148,21 @@ ret void } +define void @test8(%t* noalias %src, %t* %dst) { +; CHECK-LABEL: @test8( +; CHECK-NEXT: [[TMP1:%.*]] = bitcast %t* [[SRC:%.*]] to i8* +; CHECK-NEXT: [[TMP2:%.*]] = bitcast %t* [[DST:%.*]] to i8* +; CHECK-NEXT: [[TMP3:%.*]] = bitcast %t* [[SRC]] to i8* +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[TMP2]], i8* align 1 [[TMP3]], i64 8224, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 0, i64 8224, i1 false) +; CHECK-NEXT: ret void +; + %1 = load %t, %t* %src + store %t zeroinitializer, %t* %src + store %t %1, %t* %dst + ret void +} + declare void @clobber() ; Function Attrs: argmemonly nounwind willreturn