@@ -1427,6 +1427,13 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
1427
1427
eraseInstruction (M);
1428
1428
return true ;
1429
1429
}
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 ;
1430
1437
1431
1438
// If copying from a constant, try to turn the memcpy into a memset.
1432
1439
if (auto *GV = dyn_cast<GlobalVariable>(M->getSource ()))
@@ -1436,8 +1443,7 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
1436
1443
IRBuilder<> Builder (M);
1437
1444
Instruction *NewM = Builder.CreateMemSet (
1438
1445
M->getRawDest (), ByteVal, M->getLength (), M->getDestAlign (), false );
1439
- auto *LastDef =
1440
- cast<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (M));
1446
+ auto *LastDef = cast<MemoryDef>(MA);
1441
1447
auto *NewAccess =
1442
1448
MSSAU->createMemoryAccessAfter (NewM, LastDef, LastDef);
1443
1449
MSSAU->insertDef (cast<MemoryDef>(NewAccess), /* RenameUses=*/ true );
@@ -1448,7 +1454,6 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
1448
1454
}
1449
1455
1450
1456
BatchAAResults BAA (*AA);
1451
- MemoryUseOrDef *MA = MSSA->getMemoryAccess (M);
1452
1457
// FIXME: Not using getClobberingMemoryAccess() here due to PR54682.
1453
1458
MemoryAccess *AnyClobber = MA->getDefiningAccess ();
1454
1459
MemoryLocation DestLoc = MemoryLocation::getForDest (M);
0 commit comments