Fix PR3243: a LiveVariables bug. When HandlePhysRegKill is checking whether the last...
authorEvan Cheng <evan.cheng@apple.com>
Tue, 20 Jan 2009 21:25:12 +0000 (21:25 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 20 Jan 2009 21:25:12 +0000 (21:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62617 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/LiveVariables.h
lib/CodeGen/LiveVariables.cpp
test/CodeGen/X86/pr3243.ll [new file with mode: 0644]

index 0d932cf19871667fccec9d83504b5a30c20a5071..bb050f260368dbf344ea7fbff4519c9b6214724e 100644 (file)
@@ -146,7 +146,7 @@ private:   // Intermediate data structures
   /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the
   /// uses. Pay special attention to the sub-register uses which may come below
   /// the last use of the whole register.
-  bool HandlePhysRegKill(unsigned Reg);
+  bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI);
 
   void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
   void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
index ecfebc55114e0e60c3da58e312a80d612e05ca7e..a7bdbd92ff2dd281b26008c61a1d387289075755 100644 (file)
@@ -335,7 +335,7 @@ bool LiveVariables::hasRegisterUseBelow(unsigned Reg,
   return true;
 }
 
-bool LiveVariables::HandlePhysRegKill(unsigned Reg) {
+bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
   if (!PhysRegUse[Reg] && !PhysRegDef[Reg])
     return false;
 
@@ -373,8 +373,10 @@ bool LiveVariables::HandlePhysRegKill(unsigned Reg) {
       }
     }
   }
-  if (LastRefOrPartRef == PhysRegDef[Reg])
-    // Not used at all.
+
+  if (LastRefOrPartRef == PhysRegDef[Reg] && LastRefOrPartRef != MI)
+    // If the last reference is the last def, then it's not used at all.
+    // That is, unless we are currently processing the last reference itself.
     LastRefOrPartRef->addRegisterDead(Reg, TRI, true);
 
   /* Partial uses. Mark register def dead and add implicit def of
@@ -427,14 +429,14 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) {
 
   // Start from the largest piece, find the last time any part of the register
   // is referenced.
-  if (!HandlePhysRegKill(Reg)) {
+  if (!HandlePhysRegKill(Reg, MI)) {
     // Only some of the sub-registers are used.
     for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
          unsigned SubReg = *SubRegs; ++SubRegs) {
       if (!Live.count(SubReg))
         // Skip if this sub-register isn't defined.
         continue;
-      if (HandlePhysRegKill(SubReg)) {
+      if (HandlePhysRegKill(SubReg, MI)) {
         Live.erase(SubReg);
         for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
           Live.erase(*SS);
@@ -475,7 +477,7 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) {
           }
         } else {
           // Otherwise, the super register is killed.
-          if (HandlePhysRegKill(SuperReg)) {
+          if (HandlePhysRegKill(SuperReg, MI)) {
             PhysRegDef[SuperReg]  = NULL;
             PhysRegUse[SuperReg]  = NULL;
             for (const unsigned *SS = TRI->getSubRegisters(SuperReg); *SS; ++SS) {
@@ -558,13 +560,13 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
       SmallVector<unsigned, 4> DefRegs;
       for (unsigned i = 0; i != NumOperandsToProcess; ++i) {
         const MachineOperand &MO = MI->getOperand(i);
-        if (MO.isReg() && MO.getReg()) {
-          unsigned MOReg = MO.getReg();
-          if (MO.isUse())
-            UseRegs.push_back(MOReg);
-          if (MO.isDef())
-            DefRegs.push_back(MOReg);
-        }
+        if (!MO.isReg() || MO.getReg() == 0)
+          continue;
+        unsigned MOReg = MO.getReg();
+        if (MO.isUse())
+          UseRegs.push_back(MOReg);
+        if (MO.isDef())
+          DefRegs.push_back(MOReg);
       }
 
       // Process all uses.
diff --git a/test/CodeGen/X86/pr3243.ll b/test/CodeGen/X86/pr3243.ll
new file mode 100644 (file)
index 0000000..7be887b
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | llc -march=x86
+; PR3243
+
+declare signext i16 @safe_mul_func_int16_t_s_s(i16 signext, i32) nounwind readnone optsize
+
+define i32 @func_120(i32 %p_121) nounwind optsize {
+entry:
+       %0 = trunc i32 %p_121 to i16            ; <i16> [#uses=1]
+       %1 = urem i16 %0, -15461                ; <i16> [#uses=1]
+       %phitmp1 = trunc i16 %1 to i8           ; <i8> [#uses=1]
+       %phitmp2 = urem i8 %phitmp1, -1         ; <i8> [#uses=1]
+       %phitmp3 = zext i8 %phitmp2 to i16              ; <i16> [#uses=1]
+       %2 = tail call signext i16 @safe_mul_func_int16_t_s_s(i16 signext %phitmp3, i32 1) nounwind             ; <i16> [#uses=0]
+       unreachable
+}