verifyMemoryCongruency() filters out trivially dead MemoryDef, as we find them immediately dead, before moving from TOP to a new congruence class.
If you consider the testcase attached, I think we may have the same problem for PHI, and I think we may want to skip MemoryPhis if all the operands are dead.
This is the MemorySSA dump
0 = MemoryDef(liveOnEntry) 1 = MemoryDef(liveOnEntry) 2 = MemoryDef(1) 3 = MemoryPhi({entry,1},{body,2})
Looking at the operands of 3, they're both uses of trivially dead defs.
Skipping trivially dead instruction call void @llvm.lifetime.start.p0i8(i64 4, i8* undef) Marking call void @llvm.lifetime.start.p0i8(i64 4, i8* undef) for deletion Skipping trivially dead instruction call void @llvm.lifetime.start.p0i8(i64 4, i8* undef) Marking call void @llvm.lifetime.start.p0i8(i64 4, i8* undef) for deletion
so we never move them out of TOP, and the phi is dead as well. Otherwise, we think this is reachable, and we hit an assertion.