@@ -1427,6 +1427,13 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
14271427 eraseInstruction (M);
14281428 return true ;
14291429 }
1430+ // If the size is zero, remove the memcpy. This also prevents infinite loops
1431+ // in processMemSetMemCpyDependence, which is a no-op for zero-length memcpys.
1432+
1433+ MemoryUseOrDef *MA = MSSA->getMemoryAccess (M);
1434+ if (!MA)
1435+ // Degenerate case: memcpy marked as not accessing memory.
1436+ return false ;
14301437
14311438 // If copying from a constant, try to turn the memcpy into a memset.
14321439 if (auto *GV = dyn_cast<GlobalVariable>(M->getSource ()))
@@ -1436,8 +1443,7 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
14361443 IRBuilder<> Builder (M);
14371444 Instruction *NewM = Builder.CreateMemSet (
14381445 M->getRawDest (), ByteVal, M->getLength (), M->getDestAlign (), false );
1439- auto *LastDef =
1440- cast<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (M));
1446+ auto *LastDef = cast<MemoryDef>(MA);
14411447 auto *NewAccess =
14421448 MSSAU->createMemoryAccessAfter (NewM, LastDef, LastDef);
14431449 MSSAU->insertDef (cast<MemoryDef>(NewAccess), /* RenameUses=*/ true );
@@ -1448,7 +1454,6 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
14481454 }
14491455
14501456 BatchAAResults BAA (*AA);
1451- MemoryUseOrDef *MA = MSSA->getMemoryAccess (M);
14521457 // FIXME: Not using getClobberingMemoryAccess() here due to PR54682.
14531458 MemoryAccess *AnyClobber = MA->getDefiningAccess ();
14541459 MemoryLocation DestLoc = MemoryLocation::getForDest (M);
0 commit comments