Coalescer should not delete extract_subreg, insert_subreg, and subreg_to_reg of

physical registers. This is especially critical for the later two since they
start the live interval of a super-register. e.g.
%DO<def> = INSERT_SUBREG %D0<undef>, %S0<kill>, 1
If this instruction is eliminated, the register scavenger will not be happy as
D0 is not defined previously.
This fixes PR5055.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82968 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2009-09-28 05:28:43 +00:00
parent 17167be948
commit 0e6b590b91
4 changed files with 41 additions and 5 deletions

View File

@ -2692,21 +2692,34 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (JoinedCopies.count(MI)) {
// Delete all coalesced copies.
bool DoDelete = true;
if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
assert((MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) &&
"Unrecognized copy instruction");
DstReg = MI->getOperand(0).getReg();
if (TargetRegisterInfo::isPhysicalRegister(DstReg))
// Do not delete extract_subreg, insert_subreg of physical
// registers unless the definition is dead. e.g.
// %DO<def> = INSERT_SUBREG %D0<undef>, %S0<kill>, 1
// or else the scavenger may complain. LowerSubregs will
// change this to an IMPLICIT_DEF later.
DoDelete = false;
}
if (MI->registerDefIsDead(DstReg)) {
LiveInterval &li = li_->getInterval(DstReg);
if (!ShortenDeadCopySrcLiveRange(li, MI))
ShortenDeadCopyLiveRange(li, MI);
DoDelete = true;
}
if (!DoDelete)
mii = next(mii);
else {
li_->RemoveMachineInstrFromMaps(MI);
mii = mbbi->erase(mii);
++numPeep;
}
li_->RemoveMachineInstrFromMaps(MI);
mii = mbbi->erase(mii);
++numPeep;
continue;
}