diff options
| author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2009-08-04 20:01:11 +0000 | 
|---|---|---|
| committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2009-08-04 20:01:11 +0000 | 
| commit | 6304369c4ec0fb6bf1868ebfe62d1403c2af65ad (patch) | |
| tree | 7fc7ceb07e0c8c05edb3f5684482a6e9e4bca1c1 | |
| parent | b0dd95d6d359e6197126aa9561e135cb6eff6fdb (diff) | |
| download | bcm5719-llvm-6304369c4ec0fb6bf1868ebfe62d1403c2af65ad.tar.gz bcm5719-llvm-6304369c4ec0fb6bf1868ebfe62d1403c2af65ad.zip  | |
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
| -rw-r--r-- | llvm/lib/CodeGen/LowerSubregs.cpp | 25 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll | 15 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/stack-color-with-reg.ll | 2 | 
3 files changed, 27 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/LowerSubregs.cpp b/llvm/lib/CodeGen/LowerSubregs.cpp index dfd666f96db..9c23a5ac155 100644 --- a/llvm/lib/CodeGen/LowerSubregs.cpp +++ b/llvm/lib/CodeGen/LowerSubregs.cpp @@ -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); diff --git a/llvm/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll b/llvm/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll new file mode 100644 index 00000000000..58076f9c2d8 --- /dev/null +++ b/llvm/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll @@ -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 +} diff --git a/llvm/test/CodeGen/X86/stack-color-with-reg.ll b/llvm/test/CodeGen/X86/stack-color-with-reg.ll index 4e277c7eb03..832886be756 100644 --- a/llvm/test/CodeGen/X86/stack-color-with-reg.ll +++ b/llvm/test/CodeGen/X86/stack-color-with-reg.ll @@ -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  | 

