Index: include/llvm/Analysis/MemorySSAUpdater.h =================================================================== --- include/llvm/Analysis/MemorySSAUpdater.h +++ include/llvm/Analysis/MemorySSAUpdater.h @@ -129,10 +129,9 @@ /// If New is the only predecessor, move Old's Phi, if present, to New. /// Otherwise, add a new Phi in New with appropriate incoming values, and /// update the incoming values in Old's Phi node too, if present. - void - wireOldPredecessorsToNewImmediatePredecessor(BasicBlock *Old, BasicBlock *New, - ArrayRef Preds); - + void wireOldPredecessorsToNewImmediatePredecessor( + BasicBlock *Old, BasicBlock *New, ArrayRef Preds, + bool IdenticalEdgesWereMerged = true); // The below are utility functions. Other than creation of accesses to pass // to insertDef, and removeAccess to remove accesses, you should generally // not attempt to update memoryssa yourself. It is very non-trivial to get Index: lib/Analysis/MemorySSAUpdater.cpp =================================================================== --- lib/Analysis/MemorySSAUpdater.cpp +++ lib/Analysis/MemorySSAUpdater.cpp @@ -498,7 +498,8 @@ } void MemorySSAUpdater::wireOldPredecessorsToNewImmediatePredecessor( - BasicBlock *Old, BasicBlock *New, ArrayRef Preds) { + BasicBlock *Old, BasicBlock *New, ArrayRef Preds, + bool IdenticalEdgesWereMerged) { assert(!MSSA->getWritableBlockAccesses(New) && "Access list should be null for a new block."); MemoryPhi *Phi = MSSA->getMemoryAccess(Old); @@ -513,9 +514,17 @@ "new immediate predecessor."); MemoryPhi *NewPhi = MSSA->createMemoryPhi(New); SmallPtrSet PredsSet(Preds.begin(), Preds.end()); + // Currently only support the case of removing a single incoming edge when + // identical edges were not merged. + if (!IdenticalEdgesWereMerged) + assert(PredsSet.size() == Preds.size() && + "If identical edges were not merged, we cannot have duplicate " + "blocks in the predecessors"); Phi->unorderedDeleteIncomingIf([&](MemoryAccess *MA, BasicBlock *B) { if (PredsSet.count(B)) { NewPhi->addIncoming(MA, B); + if (!IdenticalEdgesWereMerged) + PredsSet.erase(B); return true; } return false; Index: lib/Transforms/Utils/BreakCriticalEdges.cpp =================================================================== --- lib/Transforms/Utils/BreakCriticalEdges.cpp +++ lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -200,8 +200,10 @@ auto *DT = Options.DT; auto *LI = Options.LI; auto *MSSAU = Options.MSSAU; - if (MSSAU) - MSSAU->wireOldPredecessorsToNewImmediatePredecessor(DestBB, NewBB, {TIBB}); + if (MSSAU) { + MSSAU->wireOldPredecessorsToNewImmediatePredecessor( + DestBB, NewBB, {TIBB}, Options.MergeIdenticalEdges); + } if (!DT && !LI) return NewBB;