forked from OSchip/llvm-project
LowerSubregsInstructionPass::LowerExtract should not extend the live range of registers.
When LowerExtract eliminates an EXTRACT_SUBREG with a kill flag, it moves the kill flag to the place where the sub-register is killed. This can accidentally overlap with the use of a sibling sub-register, and we have trouble. In the test case we have this code: Live Ins: %R0 %R1 %R2 %R2L<def> = EXTRACT_SUBREG %R2<kill>, 1 %R2H<def> = LOAD16fi <fi#-1>, 0, Mem:LD(2,4) [FixedStack-1 + 0] %R1L<def> = EXTRACT_SUBREG %R1<kill>, 1 %R0L<def> = EXTRACT_SUBREG %R0<kill>, 1 %R0H<def> = ADD16 %R2H<kill>, %R2L<kill>, %AZ<imp-def>, %AN<imp-def>, %AC0<imp-def>, %V<imp-def>, %VS<imp-def> subreg: CONVERTING: %R2L<def> = EXTRACT_SUBREG %R2<kill>, 1 subreg: eliminated! subreg: killed here: %R0H<def> = ADD16 %R2H, %R2L, %R2<imp-use,kill>, %AZ<imp-def>, %AN<imp-def>, %AC0<imp-def>, %V<imp-def>, %VS<imp-def> The kill flag on %R2 is moved to the last instruction, and the live range overlaps with the definition of %R2H: *** Bad machine code: Redefining a live physical register *** - function: f - basic block: 0x18358c0 (#0) - instruction: %R2H<def> = LOAD16fi <fi#-1>, 0, Mem:LD(2,4) [FixedStack-1 + 0] Register R2H was defined but already live. The fix is to replace EXTRACT_SUBREG with IMPLICIT_DEF instead of eliminating it completely: subreg: CONVERTING: %R2L<def> = EXTRACT_SUBREG %R2<kill>, 1 subreg: replace by: %R2L<def> = IMPLICIT_DEF %R2<kill> Note that these IMPLICIT_DEF instructions survive to the asm output. It is necessary to fix the stack-color-with-reg test case because of that. llvm-svn: 78093
This commit is contained in:
parent
b0dd95d6d3
commit
6304369c4e
|
@ -103,7 +103,7 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) {
|
|||
MachineFunction &MF = *MBB->getParent();
|
||||
const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo();
|
||||
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
|
||||
|
||||
|
||||
assert(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
|
||||
MI->getOperand(1).isReg() && MI->getOperand(1).isUse() &&
|
||||
MI->getOperand(2).isImm() && "Malformed extract_subreg");
|
||||
|
@ -117,23 +117,20 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) {
|
|||
"Extract supperg source must be a physical register");
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(DstReg) &&
|
||||
"Extract destination must be in a physical register");
|
||||
|
||||
|
||||
DOUT << "subreg: CONVERTING: " << *MI;
|
||||
|
||||
if (SrcReg == DstReg) {
|
||||
// No need to insert an identify copy instruction.
|
||||
// No need to insert an identity copy instruction.
|
||||
if (MI->getOperand(1).isKill()) {
|
||||
// We must make sure the super-register gets killed.Replace the
|
||||
// instruction with IMPLICIT_DEF.
|
||||
MI->setDesc(TII.get(TargetInstrInfo::IMPLICIT_DEF));
|
||||
MI->RemoveOperand(2); // SubIdx
|
||||
DOUT << "subreg: replace by: " << *MI;
|
||||
return true;
|
||||
}
|
||||
DOUT << "subreg: eliminated!";
|
||||
// Find the kill of the destination register's live range, and insert
|
||||
// a kill of the source register at that point.
|
||||
if (MI->getOperand(1).isKill() && !MI->getOperand(0).isDead())
|
||||
for (MachineBasicBlock::iterator MII =
|
||||
next(MachineBasicBlock::iterator(MI));
|
||||
MII != MBB->end(); ++MII)
|
||||
if (MII->killsRegister(DstReg, &TRI)) {
|
||||
MII->addRegisterKilled(SuperReg, &TRI, /*AddIfNotFound=*/true);
|
||||
DOUT << "\nsubreg: killed here: " << *MII;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Insert copy
|
||||
const TargetRegisterClass *TRCS = TRI.getPhysicalRegisterRegClass(DstReg);
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
; RUN: llvm-as < %s | llc -march=bfin -join-liveintervals=0 -verify-machineinstrs
|
||||
|
||||
; Provoke an error in LowerSubregsPass::LowerExtract where the live range of a
|
||||
; super-register is illegally extended.
|
||||
|
||||
define i16 @f(i16 %x1, i16 %x2, i16 %x3, i16 %x4) {
|
||||
%y1 = add i16 %x1, 1
|
||||
%y2 = add i16 %x2, 2
|
||||
%y3 = add i16 %x3, 3
|
||||
%y4 = add i16 %x4, 4
|
||||
%z12 = add i16 %y1, %y2
|
||||
%z34 = add i16 %y3, %y4
|
||||
%p = add i16 %z12, %z34
|
||||
ret i16 %p
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin10 -relocation-model=pic -disable-fp-elim -color-ss-with-regs -stats -info-output-file - > %t
|
||||
; RUN: grep stackcoloring %t | grep "loads eliminated"
|
||||
; RUN: grep stackcoloring %t | grep "stack slot refs replaced with reg refs" | grep 5
|
||||
; RUN: grep asm-printer %t | grep 175
|
||||
; RUN: grep asm-printer %t | grep 180
|
||||
|
||||
type { [62 x %struct.Bitvec*] } ; type %0
|
||||
type { i8* } ; type %1
|
||||
|
|
Loading…
Reference in New Issue