When computing live intervals for earlyclobber operands,
authorDale Johannesen <dalej@apple.com>
Sun, 20 Sep 2009 00:36:41 +0000 (00:36 +0000)
committerDale Johannesen <dalej@apple.com>
Sun, 20 Sep 2009 00:36:41 +0000 (00:36 +0000)
we pushed the beginning of the interval back 1, so the
interval would overlap with inputs that die.  We were
also pushing the end of the interval back 1, though,
which means the earlyclobber didn't overlap with other
output operands.  Don't do this.  PR 4964.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82342 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/LiveIntervalAnalysis.cpp
test/CodeGen/X86/2009-09-19-earlyclobber.ll [new file with mode: 0644]

index 6296e933818b4bc3fc8e1c194a175a9d8c858e72..c690ac32412cf492c8af2cff56d843928559d1f0 100644 (file)
@@ -665,7 +665,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
   if (interval.empty()) {
     // Get the Idx of the defining instructions.
     MachineInstrIndex defIndex = getDefIndex(MIIdx);
-    // Earlyclobbers move back one.
+    // Earlyclobbers move back one, so that they overlap the live range
+    // of inputs.
     if (MO.isEarlyClobber())
       defIndex = getUseIndex(MIIdx);
     VNInfo *ValNo;
@@ -690,6 +691,11 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       MachineInstrIndex killIdx;
       if (vi.Kills[0] != mi)
         killIdx = getNextSlot(getUseIndex(getInstructionIndex(vi.Kills[0])));
+      else if (MO.isEarlyClobber())
+        // Earlyclobbers that die in this instruction move up one extra, to
+        // compensate for having the starting point moved back one.  This
+        // gets them to overlap the live range of other outputs.
+        killIdx = getNextSlot(getNextSlot(defIndex));
       else
         killIdx = getNextSlot(defIndex);
 
@@ -791,7 +797,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
       // range covering the def slot.
       if (MO.isDead())
         interval.addRange(
-          LiveRange(RedefIndex, getNextSlot(RedefIndex), OldValNo));
+          LiveRange(RedefIndex, MO.isEarlyClobber() ?
+                                getNextSlot(getNextSlot(RedefIndex)) :
+                                getNextSlot(RedefIndex), OldValNo));
 
       DEBUG({
           errs() << " RESULT: ";
@@ -892,9 +900,14 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
   // If it is not used after definition, it is considered dead at
   // the instruction defining it. Hence its interval is:
   // [defSlot(def), defSlot(def)+1)
+  // For earlyclobbers, the defSlot was pushed back one; the extra
+  // advance below compensates.
   if (MO.isDead()) {
     DEBUG(errs() << " dead");
-    end = getNextSlot(start);
+    if (MO.isEarlyClobber())
+      end = getNextSlot(getNextSlot(start));
+    else
+      end = getNextSlot(start);
     goto exit;
   }
 
diff --git a/test/CodeGen/X86/2009-09-19-earlyclobber.ll b/test/CodeGen/X86/2009-09-19-earlyclobber.ll
new file mode 100644 (file)
index 0000000..4f44cae
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = '4964.c'
+; PR 4964
+; Registers other than RAX, RCX are OK, but they must be different.
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-apple-darwin10.0"
+       type { i64, i64 }               ; type %0
+
+define i64 @flsst(i64 %find) nounwind ssp {
+entry:
+; CHECK: FOO %rax %rcx
+       %asmtmp = tail call %0 asm sideeffect "FOO $0 $1 $2", "=r,=&r,rm,~{dirflag},~{fpsr},~{flags},~{cc}"(i64 %find) nounwind         ; <%0> [#uses=1]
+       %asmresult = extractvalue %0 %asmtmp, 0         ; <i64> [#uses=1]
+       ret i64 %asmresult
+}