Never clear <undef> flags on already joined copies.
RegisterCoalescer set <undef> flags on all operands of copy instructions that are scheduled to be removed. This is so they won't affect shrinkToUses() by introducing false register reads. Make sure those <undef> flags are never cleared, or shrinkToUses() could cause live intervals to end at instructions about to be deleted. This would be a lot simpler if RegisterCoalescer could just erase joined copies immediately instead of keeping all the to-be-deleted instructions around. This fixes PR12862. Unfortunately, bugpoint can't create a sane test case for this. Like many other coalescer problems, this failure depends of a very fragile series of events. <rdar://problem/11474428> llvm-svn: 157001
This commit is contained in:
parent
14a8745990
commit
c3553ffc70
|
@ -918,6 +918,8 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
|
||||||
|
|
||||||
for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(SrcReg);
|
for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(SrcReg);
|
||||||
MachineInstr *UseMI = I.skipInstruction();) {
|
MachineInstr *UseMI = I.skipInstruction();) {
|
||||||
|
bool AlreadyJoined = JoinedCopies.count(UseMI);
|
||||||
|
|
||||||
// A PhysReg copy that won't be coalesced can perhaps be rematerialized
|
// A PhysReg copy that won't be coalesced can perhaps be rematerialized
|
||||||
// instead.
|
// instead.
|
||||||
if (DstIsPhys) {
|
if (DstIsPhys) {
|
||||||
|
@ -925,7 +927,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
|
||||||
UseMI->getOperand(1).getReg() == SrcReg &&
|
UseMI->getOperand(1).getReg() == SrcReg &&
|
||||||
UseMI->getOperand(0).getReg() != SrcReg &&
|
UseMI->getOperand(0).getReg() != SrcReg &&
|
||||||
UseMI->getOperand(0).getReg() != DstReg &&
|
UseMI->getOperand(0).getReg() != DstReg &&
|
||||||
!JoinedCopies.count(UseMI) &&
|
!AlreadyJoined &&
|
||||||
reMaterializeTrivialDef(LIS->getInterval(SrcReg), false,
|
reMaterializeTrivialDef(LIS->getInterval(SrcReg), false,
|
||||||
UseMI->getOperand(0).getReg(), UseMI))
|
UseMI->getOperand(0).getReg(), UseMI))
|
||||||
continue;
|
continue;
|
||||||
|
@ -937,7 +939,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
|
||||||
|
|
||||||
// If SrcReg wasn't read, it may still be the case that DstReg is live-in
|
// If SrcReg wasn't read, it may still be the case that DstReg is live-in
|
||||||
// because SrcReg is a sub-register.
|
// because SrcReg is a sub-register.
|
||||||
if (!Reads && SubIdx)
|
if (!Reads && SubIdx && !AlreadyJoined)
|
||||||
Reads = DstInt.liveAt(LIS->getInstructionIndex(UseMI));
|
Reads = DstInt.liveAt(LIS->getInstructionIndex(UseMI));
|
||||||
|
|
||||||
// Replace SrcReg with DstReg in all UseMI operands.
|
// Replace SrcReg with DstReg in all UseMI operands.
|
||||||
|
@ -947,7 +949,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
|
||||||
// Adjust <undef> flags in case of sub-register joins. We don't want to
|
// Adjust <undef> flags in case of sub-register joins. We don't want to
|
||||||
// turn a full def into a read-modify-write sub-register def and vice
|
// turn a full def into a read-modify-write sub-register def and vice
|
||||||
// versa.
|
// versa.
|
||||||
if (SubIdx && MO.isDef())
|
if (SubIdx && !AlreadyJoined && MO.isDef())
|
||||||
MO.setIsUndef(!Reads);
|
MO.setIsUndef(!Reads);
|
||||||
|
|
||||||
if (DstIsPhys)
|
if (DstIsPhys)
|
||||||
|
@ -957,7 +959,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This instruction is a copy that will be removed.
|
// This instruction is a copy that will be removed.
|
||||||
if (JoinedCopies.count(UseMI))
|
if (AlreadyJoined)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DEBUG({
|
DEBUG({
|
||||||
|
|
Loading…
Reference in New Issue