[llvm-commits] [llvm] r78093 - in /llvm/trunk: lib/CodeGen/LowerSubregs.cpp test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll test/CodeGen/X86/stack-color-with-reg.ll

Jakob Stoklund Olesen stoklund at 2pi.dk
Tue Aug 4 13:01:54 PDT 2009


Author: stoklund
Date: Tue Aug  4 15:01:11 2009
New Revision: 78093

URL: http://llvm.org/viewvc/llvm-project?rev=78093&view=rev
Log:
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.

Added:
    llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll
Modified:
    llvm/trunk/lib/CodeGen/LowerSubregs.cpp
    llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll

Modified: llvm/trunk/lib/CodeGen/LowerSubregs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LowerSubregs.cpp?rev=78093&r1=78092&r2=78093&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/LowerSubregs.cpp (original)
+++ llvm/trunk/lib/CodeGen/LowerSubregs.cpp Tue Aug  4 15:01:11 2009
@@ -103,7 +103,7 @@
   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 @@
          "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);

Added: llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll?rev=78093&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll (added)
+++ llvm/trunk/test/CodeGen/Blackfin/2009-08-04-LowerExtract-Live.ll Tue Aug  4 15:01:11 2009
@@ -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
+}

Modified: llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll?rev=78093&r1=78092&r2=78093&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll (original)
+++ llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll Tue Aug  4 15:01:11 2009
@@ -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





More information about the llvm-commits mailing list