[llvm-commits] [llvm] r62617 - in /llvm/trunk: include/llvm/CodeGen/LiveVariables.h lib/CodeGen/LiveVariables.cpp test/CodeGen/X86/pr3243.ll

Evan Cheng evan.cheng at apple.com
Tue Jan 20 13:25:12 PST 2009


Author: evancheng
Date: Tue Jan 20 15:25:12 2009
New Revision: 62617

URL: http://llvm.org/viewvc/llvm-project?rev=62617&view=rev
Log:
Fix PR3243: a LiveVariables bug. When HandlePhysRegKill is checking whether the last reference is also the last def (i.e. dead def), it should also check if last reference is the current machine instruction being processed. This can happen when it is processing a physical register use and setting the current machine instruction as sub-register's last ref.

Added:
    llvm/trunk/test/CodeGen/X86/pr3243.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/LiveVariables.h
    llvm/trunk/lib/CodeGen/LiveVariables.cpp

Modified: llvm/trunk/include/llvm/CodeGen/LiveVariables.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveVariables.h?rev=62617&r1=62616&r2=62617&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveVariables.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LiveVariables.h Tue Jan 20 15:25:12 2009
@@ -146,7 +146,7 @@
   /// 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);

Modified: llvm/trunk/lib/CodeGen/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveVariables.cpp?rev=62617&r1=62616&r2=62617&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/LiveVariables.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveVariables.cpp Tue Jan 20 15:25:12 2009
@@ -335,7 +335,7 @@
   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 @@
       }
     }
   }
-  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 @@
 
   // 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 @@
           }
         } 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 @@
       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.

Added: llvm/trunk/test/CodeGen/X86/pr3243.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr3243.ll?rev=62617&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/pr3243.ll (added)
+++ llvm/trunk/test/CodeGen/X86/pr3243.ll Tue Jan 20 15:25:12 2009
@@ -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
+}





More information about the llvm-commits mailing list