[llvm-commits] [llvm] r69087 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp test/CodeGen/X86/h-registers-0.ll test/CodeGen/X86/h-registers-1.ll test/CodeGen/X86/h-registers.ll

Dan Gohman gohman at apple.com
Tue Apr 14 15:17:14 PDT 2009


Author: djg
Date: Tue Apr 14 17:17:14 2009
New Revision: 69087

URL: http://llvm.org/viewvc/llvm-project?rev=69087&view=rev
Log:
When the result of an EXTRACT_SUBREG, INSERT_SUBREG, or SUBREG_TO_REG
operator is used by a CopyToReg to export the value to a different
block, don't reuse the CopyToReg's register for the subreg operation
result if the register isn't precisely the right class for the
subreg operation.

Also, rename the h-registers.ll test, now that there are more
than one.

Added:
    llvm/trunk/test/CodeGen/X86/h-registers-0.ll
      - copied unchanged from r69083, llvm/trunk/test/CodeGen/X86/h-registers.ll
    llvm/trunk/test/CodeGen/X86/h-registers-1.ll
Removed:
    llvm/trunk/test/CodeGen/X86/h-registers.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?rev=69087&r1=69086&r2=69087&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Tue Apr 14 17:17:14 2009
@@ -402,19 +402,16 @@
     const TargetRegisterClass *TRC = MRI.getRegClass(VReg);
     const TargetRegisterClass *SRC = getSubRegisterRegClass(TRC, SubIdx);
 
-    if (VRBase) {
-      // Grab the destination register
-#ifndef NDEBUG
-      const TargetRegisterClass *DRC = MRI.getRegClass(VRBase);
-      assert(SRC && DRC && (SRC == DRC || DRC->hasSubClass(SRC)) &&
-             "Source subregister and destination must have the same class");
-#endif
-    } else {
+    // Figure out the register class to create for the destreg.
+    // Note that if we're going to directly use an existing register,
+    // it must be precisely the required class, and not a subclass
+    // thereof.
+    if (VRBase == 0 || SRC != MRI.getRegClass(VRBase)) {
       // Create the reg
       assert(SRC && "Couldn't find source register class");
       VRBase = MRI.createVirtualRegister(SRC);
     }
-    
+
     // Add def, source, and subreg index
     MI->addOperand(MachineOperand::CreateReg(VRBase, true));
     AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
@@ -427,19 +424,21 @@
     SDValue N2 = Node->getOperand(2);
     unsigned SubReg = getVR(N1, VRBaseMap);
     unsigned SubIdx = cast<ConstantSDNode>(N2)->getZExtValue();
-    
-      
+    const TargetRegisterClass *TRC = MRI.getRegClass(SubReg);
+    const TargetRegisterClass *SRC =
+      getSuperRegisterRegClass(TRC, SubIdx,
+                               Node->getValueType(0));
+
     // Figure out the register class to create for the destreg.
-    const TargetRegisterClass *TRC = 0;
-    if (VRBase) {
-      TRC = MRI.getRegClass(VRBase);
-    } else {
-      TRC = getSuperRegisterRegClass(MRI.getRegClass(SubReg), SubIdx,
-                                     Node->getValueType(0));
-      assert(TRC && "Couldn't determine register class for insert_subreg");
-      VRBase = MRI.createVirtualRegister(TRC); // Create the reg
+    // Note that if we're going to directly use an existing register,
+    // it must be precisely the required class, and not a subclass
+    // thereof.
+    if (VRBase == 0 || SRC != MRI.getRegClass(VRBase)) {
+      // Create the reg
+      assert(SRC && "Couldn't find source register class");
+      VRBase = MRI.createVirtualRegister(SRC);
     }
-    
+
     // Create the insert_subreg or subreg_to_reg machine instruction.
     MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), TII->get(Opc));
     MI->addOperand(MachineOperand::CreateReg(VRBase, true));

Added: llvm/trunk/test/CodeGen/X86/h-registers-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-registers-1.ll?rev=69087&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/h-registers-1.ll (added)
+++ llvm/trunk/test/CodeGen/X86/h-registers-1.ll Tue Apr 14 17:17:14 2009
@@ -0,0 +1,39 @@
+; RUN: llvm-as < %s | llc -march=x86-64 > %t
+; RUN: grep {movzbl	%\[abcd\]h,} %t | count 8
+; RUN: grep {%\[abcd\]h} %t | not grep {%r\[\[:digit:\]\]*d}
+
+; LLVM creates virtual registers for values live across blocks
+; based on the type of the value. Make sure that the extracts
+; here use the GR64_NOREX register class for their result,
+; instead of plain GR64.
+
+define i64 @foo(i64 %a, i64 %b, i64 %c, i64 %d,
+                i64 %e, i64 %f, i64 %g, i64 %h) {
+  %sa = lshr i64 %a, 8
+  %A = and i64 %sa, 255
+  %sb = lshr i64 %b, 8
+  %B = and i64 %sb, 255
+  %sc = lshr i64 %c, 8
+  %C = and i64 %sc, 255
+  %sd = lshr i64 %d, 8
+  %D = and i64 %sd, 255
+  %se = lshr i64 %e, 8
+  %E = and i64 %se, 255
+  %sf = lshr i64 %f, 8
+  %F = and i64 %sf, 255
+  %sg = lshr i64 %g, 8
+  %G = and i64 %sg, 255
+  %sh = lshr i64 %h, 8
+  %H = and i64 %sh, 255
+  br label %next
+
+next:
+  %u = add i64 %A, %B
+  %v = add i64 %C, %D
+  %w = add i64 %E, %F
+  %x = add i64 %G, %H
+  %y = add i64 %u, %v
+  %z = add i64 %w, %x
+  %t = add i64 %y, %z
+  ret i64 %t
+}

Removed: llvm/trunk/test/CodeGen/X86/h-registers.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-registers.ll?rev=69086&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/h-registers.ll (original)
+++ llvm/trunk/test/CodeGen/X86/h-registers.ll (removed)
@@ -1,48 +0,0 @@
-; RUN: llvm-as < %s | llc -march=x86-64 | grep {movzbl	%\[abcd\]h,} | count 4
-; RUN: llvm-as < %s | llc -march=x86    > %t
-; RUN: grep {incb	%ah} %t | count 3
-; RUN: grep {movzbl	%ah,} %t | count 3
-
-; Use h registers. On x86-64, codegen doesn't support general allocation
-; of h registers yet, due to x86 encoding complications.
-
-define void @bar64(i64 inreg %x, i8* inreg %p) nounwind {
-  %t0 = lshr i64 %x, 8
-  %t1 = trunc i64 %t0 to i8
-  %t2 = add i8 %t1, 1
-  store i8 %t2, i8* %p
-  ret void
-}
-
-define void @bar32(i32 inreg %x, i8* inreg %p) nounwind {
-  %t0 = lshr i32 %x, 8
-  %t1 = trunc i32 %t0 to i8
-  %t2 = add i8 %t1, 1
-  store i8 %t2, i8* %p
-  ret void
-}
-
-define void @bar16(i16 inreg %x, i8* inreg %p) nounwind {
-  %t0 = lshr i16 %x, 8
-  %t1 = trunc i16 %t0 to i8
-  %t2 = add i8 %t1, 1
-  store i8 %t2, i8* %p
-  ret void
-}
-
-define i64 @qux64(i64 inreg %x) nounwind {
-  %t0 = lshr i64 %x, 8
-  %t1 = and i64 %t0, 255
-  ret i64 %t1
-}
-
-define i32 @qux32(i32 inreg %x) nounwind {
-  %t0 = lshr i32 %x, 8
-  %t1 = and i32 %t0, 255
-  ret i32 %t1
-}
-
-define i16 @qux16(i16 inreg %x) nounwind {
-  %t0 = lshr i16 %x, 8
-  ret i16 %t0
-}





More information about the llvm-commits mailing list