diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-05-17 18:32:42 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-05-17 18:32:42 +0000 |
commit | c3553ffc70ac8196629bc1d19b3186399e883a03 (patch) | |
tree | 59fc1f50bc2f7f9e4c72d3ea4c4cf1995b84784a /llvm/lib | |
parent | 14a87459906408ef325940b07bcf5fea3183f5fe (diff) | |
download | bcm5719-llvm-c3553ffc70ac8196629bc1d19b3186399e883a03.tar.gz bcm5719-llvm-c3553ffc70ac8196629bc1d19b3186399e883a03.zip |
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
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/RegisterCoalescer.cpp | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index f8794894d99..8dfd1b3fc85 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -918,6 +918,8 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(SrcReg); MachineInstr *UseMI = I.skipInstruction();) { + bool AlreadyJoined = JoinedCopies.count(UseMI); + // A PhysReg copy that won't be coalesced can perhaps be rematerialized // instead. if (DstIsPhys) { @@ -925,7 +927,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, UseMI->getOperand(1).getReg() == SrcReg && UseMI->getOperand(0).getReg() != SrcReg && UseMI->getOperand(0).getReg() != DstReg && - !JoinedCopies.count(UseMI) && + !AlreadyJoined && reMaterializeTrivialDef(LIS->getInterval(SrcReg), false, UseMI->getOperand(0).getReg(), UseMI)) 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 // because SrcReg is a sub-register. - if (!Reads && SubIdx) + if (!Reads && SubIdx && !AlreadyJoined) Reads = DstInt.liveAt(LIS->getInstructionIndex(UseMI)); // 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 // turn a full def into a read-modify-write sub-register def and vice // versa. - if (SubIdx && MO.isDef()) + if (SubIdx && !AlreadyJoined && MO.isDef()) MO.setIsUndef(!Reads); if (DstIsPhys) @@ -957,7 +959,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, } // This instruction is a copy that will be removed. - if (JoinedCopies.count(UseMI)) + if (AlreadyJoined) continue; DEBUG({ |