[llvm-commits] [llvm] r41010 - in /llvm/trunk: lib/Target/X86/README.txt lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2007-08-10-SignExtSubreg.ll test/CodeGen/X86/shl_elim.ll

Christopher Lamb christopher.lamb at gmail.com
Fri Aug 10 14:48:46 PDT 2007


Author: clamb
Date: Fri Aug 10 16:48:46 2007
New Revision: 41010

URL: http://llvm.org/viewvc/llvm-project?rev=41010&view=rev
Log:
Increase efficiency of sign_extend_inreg by using subregisters for truncation. As the README suggests sign_extend_subreg is selected to (sext(trunc)).

Added:
    llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll
Modified:
    llvm/trunk/lib/Target/X86/README.txt
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/test/CodeGen/X86/shl_elim.ll

Modified: llvm/trunk/lib/Target/X86/README.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=41010&r1=41009&r2=41010&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/README.txt (original)
+++ llvm/trunk/lib/Target/X86/README.txt Fri Aug 10 16:48:46 2007
@@ -473,21 +473,6 @@
 
 //===---------------------------------------------------------------------===//
 
-Bad codegen:
-
-char foo(int x) { return x; }
-
-_foo:
-	movl 4(%esp), %eax
-	shll $24, %eax
-	sarl $24, %eax
-	ret
-
-SIGN_EXTEND_INREG can be implemented as (sext (trunc)) to take advantage of 
-sub-registers.
-
-//===---------------------------------------------------------------------===//
-
 Consider this:
 
 typedef struct pair { float A, B; } pair;

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=41010&r1=41009&r2=41010&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Aug 10 16:48:46 2007
@@ -208,6 +208,10 @@
     /// base register.  Return the virtual register that holds this value.
     SDNode *getGlobalBaseReg();
 
+    /// getTruncate - return an SDNode that implements a subreg based truncate
+    /// of the specified operand to the the specified value type.
+    SDNode *getTruncate(SDOperand N0, MVT::ValueType VT);
+
 #ifndef NDEBUG
     unsigned Indent;
 #endif
@@ -979,6 +983,44 @@
   return FindCallStartFromCall(Node->getOperand(0).Val);
 }
 
+SDNode *X86DAGToDAGISel::getTruncate(SDOperand N0, MVT::ValueType VT) {
+    SDOperand SRIdx;
+    switch (VT) {
+    case MVT::i8:
+      SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+      // Ensure that the source register has an 8-bit subreg on 32-bit targets
+      if (!Subtarget->is64Bit()) { 
+        unsigned Opc;
+        MVT::ValueType VT;
+        switch (N0.getValueType()) {
+        default: assert(0 && "Unknown truncate!");
+        case MVT::i16:
+          Opc = X86::MOV16to16_;
+          VT = MVT::i16;
+          break;
+        case MVT::i32:
+          Opc = X86::MOV32to32_;
+          VT = MVT::i32;
+          break;
+        }
+        N0 = 
+          SDOperand(CurDAG->getTargetNode(Opc, VT, N0), 0);
+      }
+      break;
+    case MVT::i16:
+      SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
+      break;
+    case MVT::i32:
+      SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+      break;
+    default: assert(0 && "Unknown truncate!");
+    }
+    return CurDAG->getTargetNode(X86::EXTRACT_SUBREG, 
+                                 VT, 
+                                 N0, SRIdx);
+}
+
+
 SDNode *X86DAGToDAGISel::Select(SDOperand N) {
   SDNode *Node = N.Val;
   MVT::ValueType NVT = Node->getValueType(0);
@@ -1330,44 +1372,57 @@
 
       return NULL;
     }
+    
+    case ISD::SIGN_EXTEND_INREG: {
+      SDOperand N0 = Node->getOperand(0);
+      AddToISelQueue(N0);
       
-    case ISD::TRUNCATE: {
-      SDOperand Tmp;
-      SDOperand Input = Node->getOperand(0);
-      AddToISelQueue(Node->getOperand(0));
+      MVT::ValueType SVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
+      SDOperand TruncOp = SDOperand(getTruncate(N0, SVT), 0);
+      unsigned Opc;
       switch (NVT) {
-      case MVT::i8:
-        Tmp = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
-        // Ensure that the source register has an 8-bit subreg on 32-bit targets
-        if (!Subtarget->is64Bit()) { 
-          unsigned Opc;
-          MVT::ValueType VT;
-          switch (Node->getOperand(0).getValueType()) {
-          default: assert(0 && "Unknown truncate!");
-          case MVT::i16:
-            Opc = X86::MOV16to16_;
-            VT = MVT::i16;
-            break;
-          case MVT::i32:
-            Opc = X86::MOV32to32_;
-            VT = MVT::i32;
-            break;
-          }
-          Input = 
-            SDOperand(CurDAG->getTargetNode(Opc, VT, Node->getOperand(0)), 0);
-        }
-        break;
       case MVT::i16:
-        Tmp = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
+        if (SVT == MVT::i8) Opc = X86::MOVSX16rr8;
+        else assert(0 && "Unknown sign_extend_inreg!");
         break;
       case MVT::i32:
-        Tmp = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+        switch (SVT) {
+        case MVT::i8:  Opc = X86::MOVSX32rr8;  break;
+        case MVT::i16: Opc = X86::MOVSX32rr16; break;
+        default: assert(0 && "Unknown sign_extend_inreg!");
+        }
+        break;
+      case MVT::i64:
+        switch (SVT) {
+        case MVT::i8:  Opc = X86::MOVSX64rr8;  break;
+        case MVT::i16: Opc = X86::MOVSX64rr16; break;
+        case MVT::i32: Opc = X86::MOVSX64rr32; break;
+        default: assert(0 && "Unknown sign_extend_inreg!");
+        }
         break;
-      default: assert(0 && "Unknown truncate!");
+      default: assert(0 && "Unknown sign_extend_inreg!");
       }
-      SDNode *ResNode = CurDAG->getTargetNode(X86::EXTRACT_SUBREG, 
-                                              NVT, 
-                                              Input, Tmp);
+      
+      SDNode *ResNode = CurDAG->getTargetNode(Opc, NVT, TruncOp);
+      
+#ifndef NDEBUG
+      DOUT << std::string(Indent-2, ' ') << "=> ";
+      DEBUG(TruncOp.Val->dump(CurDAG));
+      DOUT << "\n";
+      DOUT << std::string(Indent-2, ' ') << "=> ";
+      DEBUG(ResNode->dump(CurDAG));
+      DOUT << "\n";
+      Indent -= 2;
+#endif
+      return ResNode;
+      break;
+    }
+    
+    case ISD::TRUNCATE: {
+      SDOperand Input = Node->getOperand(0);
+      AddToISelQueue(Node->getOperand(0));
+      SDNode *ResNode = getTruncate(Input, NVT);
+      
 #ifndef NDEBUG
         DOUT << std::string(Indent-2, ' ') << "=> ";
         DEBUG(ResNode->dump(CurDAG));

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=41010&r1=41009&r2=41010&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Aug 10 16:48:46 2007
@@ -157,9 +157,9 @@
   setOperationAction(ISD::SELECT_CC        , MVT::Other, Expand);
   setOperationAction(ISD::MEMMOVE          , MVT::Other, Expand);
   if (Subtarget->is64Bit())
-    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Expand);
-  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Expand);
-  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8   , Expand);
+    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Legal);
+  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Legal);
+  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8   , Legal);
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
   setOperationAction(ISD::FP_ROUND_INREG   , MVT::f32  , Expand);
   setOperationAction(ISD::FREM             , MVT::f64  , Expand);

Added: llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll?rev=41010&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll Fri Aug 10 16:48:46 2007
@@ -0,0 +1,10 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep {movsbl  .al, .eax}
+
+ at X = global i32 0               ; <i32*> [#uses=1]
+
+define i8 @_Z3fooi(i32 %x) signext  {
+entry:
+        store i32 %x, i32* @X, align 4
+        %retval67 = trunc i32 %x to i8          ; <i8> [#uses=1]
+        ret i8 %retval67
+}
\ No newline at end of file

Modified: llvm/trunk/test/CodeGen/X86/shl_elim.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shl_elim.ll?rev=41010&r1=41009&r2=41010&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/X86/shl_elim.ll (original)
+++ llvm/trunk/test/CodeGen/X86/shl_elim.ll Fri Aug 10 16:48:46 2007
@@ -1,6 +1,6 @@
 ; RUN: llvm-as < %s | llc -march=x86 | grep {movl	8(.esp), %eax}
-; RUN: llvm-as < %s | llc -march=x86 | grep {shll	.15, .eax}
-; RUN: llvm-as < %s | llc -march=x86 | grep {sarl	.16, .eax}
+; RUN: llvm-as < %s | llc -march=x86 | grep {shrl	.eax}
+; RUN: llvm-as < %s | llc -march=x86 | grep {movswl	.ax, .eax}
 
 define i32 @test1(i64 %a) {
         %tmp29 = lshr i64 %a, 24                ; <i64> [#uses=1]





More information about the llvm-commits mailing list