[llvm-commits] [llvm] r56118 - in /llvm/trunk: lib/CodeGen/SimpleRegisterCoalescing.cpp lib/CodeGen/SimpleRegisterCoalescing.h test/CodeGen/X86/2008-09-11-CoalescerBug2.ll

Evan Cheng evan.cheng at apple.com
Thu Sep 11 13:07:12 PDT 2008


Author: evancheng
Date: Thu Sep 11 15:07:10 2008
New Revision: 56118

URL: http://llvm.org/viewvc/llvm-project?rev=56118&view=rev
Log:
Fix PR2748. Avoid coalescing physical register with virtual register which would create illegal extract_subreg. e.g.
vr1024 = extract_subreg vr1025, 1
..
vr1024 = mov8rr AH
If vr1024 is coalesced with AH, the extract_subreg is now illegal since AH does not have a super-reg whose sub-register 1 is AH.

Added:
    llvm/trunk/test/CodeGen/X86/2008-09-11-CoalescerBug2.ll
Modified:
    llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
    llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h

Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=56118&r1=56117&r2=56118&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Thu Sep 11 15:07:10 2008
@@ -875,6 +875,8 @@
   }
 }
 
+/// getMatchingSuperReg - Return a super-register of the specified register
+/// Reg so its sub-register of index SubIdx is Reg.
 static unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, 
                                     const TargetRegisterClass *RC,
                                     const TargetRegisterInfo* TRI) {
@@ -919,6 +921,61 @@
   return (SrcSize + DstSize) <= Threshold;
 }
 
+/// HasIncompatibleSubRegDefUse - If we are trying to coalesce a virtual
+/// register with a physical register, check if any of the virtual register
+/// operand is a sub-register use or def. If so, make sure it won't result
+/// in an illegal extract_subreg or insert_subreg instruction. e.g.
+/// vr1024 = extract_subreg vr1025, 1
+/// ...
+/// vr1024 = mov8rr AH
+/// If vr1024 is coalesced with AH, the extract_subreg is now illegal since
+/// AH does not have a super-reg whose sub-register 1 is AH.
+bool
+SimpleRegisterCoalescing::HasIncompatibleSubRegDefUse(MachineInstr *CopyMI,
+                                                      unsigned VirtReg,
+                                                      unsigned PhysReg) {
+  for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(VirtReg),
+         E = mri_->reg_end(); I != E; ++I) {
+    MachineOperand &O = I.getOperand();
+    MachineInstr *MI = &*I;
+    if (MI == CopyMI || JoinedCopies.count(MI))
+      continue;
+    unsigned SubIdx = O.getSubReg();
+    if (SubIdx && !tri_->getSubReg(PhysReg, SubIdx))
+      return true;
+    if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+      SubIdx = MI->getOperand(2).getImm();
+      if (O.isUse() && !tri_->getSubReg(PhysReg, SubIdx))
+        return true;
+      if (O.isDef()) {
+        unsigned SrcReg = MI->getOperand(1).getReg();
+        const TargetRegisterClass *RC =
+          TargetRegisterInfo::isPhysicalRegister(SrcReg)
+          ? tri_->getPhysicalRegisterRegClass(SrcReg)
+          : mri_->getRegClass(SrcReg);
+        if (!getMatchingSuperReg(PhysReg, SubIdx, RC, tri_))
+          return true;
+      }
+    }
+    if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+      SubIdx = MI->getOperand(3).getImm();
+      if (VirtReg == MI->getOperand(0).getReg()) {
+        if (!tri_->getSubReg(PhysReg, SubIdx))
+          return true;
+      } else {
+        unsigned DstReg = MI->getOperand(0).getReg();
+        const TargetRegisterClass *RC =
+          TargetRegisterInfo::isPhysicalRegister(DstReg)
+          ? tri_->getPhysicalRegisterRegClass(DstReg)
+          : mri_->getRegClass(DstReg);
+        if (!getMatchingSuperReg(PhysReg, SubIdx, RC, tri_))
+          return true;
+      }
+    }
+  }
+  return false;
+}
+
 
 /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
 /// which are the src/dst of the copy instruction CopyMI.  This returns true
@@ -1111,6 +1168,12 @@
       return false;
     }
   }
+
+  // Will it create illegal extract_subreg / insert_subreg?
+  if (SrcIsPhys && HasIncompatibleSubRegDefUse(CopyMI, DstReg, SrcReg))
+    return false;
+  if (DstIsPhys && HasIncompatibleSubRegDefUse(CopyMI, SrcReg, DstReg))
+    return false;
   
   LiveInterval &SrcInt = li_->getInterval(SrcReg);
   LiveInterval &DstInt = li_->getInterval(DstReg);

Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h?rev=56118&r1=56117&r2=56118&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h Thu Sep 11 15:07:10 2008
@@ -223,6 +223,13 @@
     bool isProfitableToCoalesceToSubRC(unsigned SrcReg, unsigned DstReg,
                                        MachineBasicBlock *MBB);
 
+    /// HasIncompatibleSubRegDefUse - If we are trying to coalesce a virtual
+    /// register with a physical register, check if any of the virtual register
+    /// operand is a sub-register use or def. If so, make sure it won't result
+    /// in an illegal extract_subreg or insert_subreg instruction.
+    bool HasIncompatibleSubRegDefUse(MachineInstr *CopyMI,
+                                     unsigned VirtReg, unsigned PhysReg);
+
     /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of
     /// the specified live interval is defined by a copy from the specified
     /// register.

Added: llvm/trunk/test/CodeGen/X86/2008-09-11-CoalescerBug2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-09-11-CoalescerBug2.ll?rev=56118&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/2008-09-11-CoalescerBug2.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2008-09-11-CoalescerBug2.ll Thu Sep 11 15:07:10 2008
@@ -0,0 +1,33 @@
+; RUN: llvm-as < %s | llc -march=x86
+; PR2748
+
+ at g_73 = external global i32		; <i32*> [#uses=1]
+ at g_5 = external global i32		; <i32*> [#uses=1]
+
+define i32 @func_44(i16 signext %p_46) nounwind {
+entry:
+	%0 = load i32* @g_5, align 4		; <i32> [#uses=1]
+	%1 = ashr i32 %0, 1		; <i32> [#uses=1]
+	%2 = icmp sgt i32 %1, 1		; <i1> [#uses=1]
+	%3 = zext i1 %2 to i32		; <i32> [#uses=1]
+	%4 = load i32* @g_73, align 4		; <i32> [#uses=1]
+	%5 = zext i16 %p_46 to i64		; <i64> [#uses=1]
+	%6 = sub i64 0, %5		; <i64> [#uses=1]
+	%7 = trunc i64 %6 to i8		; <i8> [#uses=2]
+	%8 = trunc i32 %4 to i8		; <i8> [#uses=2]
+	%9 = icmp eq i8 %8, 0		; <i1> [#uses=1]
+	br i1 %9, label %bb11, label %bb12
+
+bb11:		; preds = %entry
+	%10 = urem i8 %7, %8		; <i8> [#uses=1]
+	br label %bb12
+
+bb12:		; preds = %bb11, %entry
+	%.014.in = phi i8 [ %10, %bb11 ], [ %7, %entry ]		; <i8> [#uses=1]
+	%11 = icmp ne i8 %.014.in, 0		; <i1> [#uses=1]
+	%12 = zext i1 %11 to i32		; <i32> [#uses=1]
+	%13 = tail call i32 (...)* @func_48( i32 %12, i32 %3, i32 0 ) nounwind		; <i32> [#uses=0]
+	ret i32 undef
+}
+
+declare i32 @func_48(...)





More information about the llvm-commits mailing list