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; unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (JoinedCopies.count(MI)) { if (JoinedCopies.count(MI)) {
// Delete all coalesced copies. // Delete all coalesced copies.
bool DoDelete = true;
if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) { if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
assert((MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG || assert((MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG || MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) && MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) &&
"Unrecognized copy instruction"); "Unrecognized copy instruction");
DstReg = MI->getOperand(0).getReg(); 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)) { if (MI->registerDefIsDead(DstReg)) {
LiveInterval &li = li_->getInterval(DstReg); LiveInterval &li = li_->getInterval(DstReg);
if (!ShortenDeadCopySrcLiveRange(li, MI)) if (!ShortenDeadCopySrcLiveRange(li, MI))
ShortenDeadCopyLiveRange(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; continue;
} }

View File

@ -0,0 +1,24 @@
; RUN: llc < %s -mtriple=armv7-eabi -mcpu=cortex-a8
; PR5055
module asm ".globl\09__aeabi_f2lz"
module asm ".set\09__aeabi_f2lz, __fixsfdi"
module asm ""
define arm_aapcs_vfpcc i64 @__fixsfdi(float %a) nounwind {
entry:
%0 = fcmp olt float %a, 0.000000e+00 ; <i1> [#uses=1]
br i1 %0, label %bb, label %bb1
bb: ; preds = %entry
%1 = fsub float -0.000000e+00, %a ; <float> [#uses=1]
%2 = tail call arm_aapcs_vfpcc i64 @__fixunssfdi(float %1) nounwind ; <i64> [#uses=1]
%3 = sub i64 0, %2 ; <i64> [#uses=1]
ret i64 %3
bb1: ; preds = %entry
%4 = tail call arm_aapcs_vfpcc i64 @__fixunssfdi(float %a) nounwind ; <i64> [#uses=1]
ret i64 %4
}
declare arm_aapcs_vfpcc i64 @__fixunssfdi(float)

View File

@ -1,5 +1,4 @@
; RUN: llc < %s -march=bfin -verify-machineinstrs ; RUN: llc < %s -march=bfin -verify-machineinstrs
; XFAIL: *
; When joining live intervals of sub-registers, an MBB live-in list is not ; When joining live intervals of sub-registers, an MBB live-in list is not
; updated properly. The register scavenger asserts on an undefined register. ; updated properly. The register scavenger asserts on an undefined register.

View File

@ -7,7 +7,7 @@
; CHECK: foo: ; CHECK: foo:
; CHECK-NEXT: divsd ; CHECK-NEXT: divsd
; CHECK-NEXT: testb $1, %dil ; CHECK: testb $1, %dil
; CHECK-NEXT: jne ; CHECK-NEXT: jne
define double @foo(double %x, double %y, i1 %c) nounwind { define double @foo(double %x, double %y, i1 %c) nounwind {