Before r265547, vreg defined by PHI VNI cannot be rematerialized because the def of PHI VNI has no instruction associated with it.
Now we use original def of vreg for rematerialization, so vreg defined by PHI VNI can be rematerialized. However, for rematerialization happen in splitting phase, live range update in splitting didn't update live range correctly if a PHI VNI becomes Dead after rematerialization. It will extend live range for Dead PHI, which may lead to some inconsistent state.
The fix is: move rewriteAssigned (which will extend live range according to real vreg uses) before extendPHIKillRanges. Then at the beginning of extendPHIKillRanges, if the segment associated with PHI->def is not extended, we know this is a Dead PHI. We will remove segment for Dead PHI, and skip live range extension for such PHI.
The bug could have been caught earlier if I run tests with -verify-regalloc, which I found quite powerful to catch inconsistent state in an early stage. After the fix, I run spec2006 and llvm testsuite with -verify-regalloc successfully, which provides me some confidence about correctness.
What about:
When enabling remat for vreg defined by PHIs, make sure the update of the live range removes dead phi. Otherwise, we may end up with PHIs with incorrect operands and that will trigger assertions or verifier failures in later passes.