[llvm-commits] [llvm] r55078 - in /llvm/trunk/lib/Target/X86: X86ISelDAGToDAG.cpp X86Instr64bit.td X86InstrInfo.td

Dan Gohman gohman at apple.com
Wed Aug 20 14:27:32 PDT 2008


Author: djg
Date: Wed Aug 20 16:27:32 2008
New Revision: 55078

URL: http://llvm.org/viewvc/llvm-project?rev=55078&view=rev
Log:
Move the handling of ANY_EXTEND, SIGN_EXTEND_INREG, and TRUNCATE
out of X86ISelDAGToDAG.cpp C++ code and into tablegen code.
Among other things, using tablegen for these things makes them
friendlier to FastISel.

Tablegen can handle the case of i8 subregs on x86-32, but currently
the C++ code for that case uses MVT::Flag in a tricky way, and it
happens to schedule better in some cases. So for now, leave the
C++ code in place to handle the i8 case on x86-32.

Modified:
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
    llvm/trunk/lib/Target/X86/X86Instr64bit.td
    llvm/trunk/lib/Target/X86/X86InstrInfo.td

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

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Aug 20 16:27:32 2008
@@ -234,9 +234,11 @@
     /// 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(SDValue N0, MVT VT);
+    /// getTruncateTo8Bit - return an SDNode that implements a subreg based
+    /// truncate of the specified operand to i8. This can be done with tablegen,
+    /// except that this code uses MVT::Flag in a tricky way that happens to
+    /// improve scheduling in some cases.
+    SDNode *getTruncateTo8Bit(SDValue N0);
 
 #ifndef NDEBUG
     unsigned Indent;
@@ -1133,38 +1135,33 @@
   return FindCallStartFromCall(Node->getOperand(0).Val);
 }
 
-SDNode *X86DAGToDAGISel::getTruncate(SDValue N0, MVT VT) {
-    SDValue SRIdx;
-    switch (VT.getSimpleVT()) {
-    default: assert(0 && "Unknown truncate!");
-    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 N0VT = N0.getValueType();
-        switch (N0VT.getSimpleVT()) {
-        default: assert(0 && "Unknown truncate!");
-        case MVT::i16:
-          Opc = X86::MOV16to16_;
-          break;
-        case MVT::i32:
-          Opc = X86::MOV32to32_;
-          break;
-        }
-        N0 = SDValue(CurDAG->getTargetNode(Opc, N0VT, MVT::Flag, N0), 0);
-        return CurDAG->getTargetNode(X86::EXTRACT_SUBREG,
-                                     VT, N0, SRIdx, N0.getValue(1));
-      }
-      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;
-    }
-    return CurDAG->getTargetNode(X86::EXTRACT_SUBREG, VT, N0, SRIdx);
+/// getTruncateTo8Bit - return an SDNode that implements a subreg based
+/// truncate of the specified operand to i8. This can be done with tablegen,
+/// except that this code uses MVT::Flag in a tricky way that happens to
+/// improve scheduling in some cases.
+SDNode *X86DAGToDAGISel::getTruncateTo8Bit(SDValue N0) {
+  assert(!Subtarget->is64Bit() &&
+         "getTruncateTo8Bit is only needed on x86-32!");
+  SDValue SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+
+  // Ensure that the source register has an 8-bit subreg on 32-bit targets
+  unsigned Opc;
+  MVT N0VT = N0.getValueType();
+  switch (N0VT.getSimpleVT()) {
+  default: assert(0 && "Unknown truncate!");
+  case MVT::i16:
+    Opc = X86::MOV16to16_;
+    break;
+  case MVT::i32:
+    Opc = X86::MOV32to32_;
+    break;
+  }
+
+  // The use of MVT::Flag here is not strictly accurate, but it helps
+  // scheduling in some cases.
+  N0 = SDValue(CurDAG->getTargetNode(Opc, N0VT, MVT::Flag, N0), 0);
+  return CurDAG->getTargetNode(X86::EXTRACT_SUBREG,
+                               MVT::i8, N0, SRIdx, N0.getValue(1));
 }
 
 
@@ -1507,90 +1504,45 @@
       return NULL;
     }
 
-    case ISD::ANY_EXTEND: {
-      // Check if the type  extended to supports subregs.
-      if (NVT == MVT::i8)
-        break;
-      
-      SDValue N0 = Node->getOperand(0);
-      // Get the subregsiter index for the type to extend.
-      MVT N0VT = N0.getValueType();
-      // FIXME: In x86-32, 8-bit value may be in AH, etc. which don't have
-      // super-registers.
-      unsigned Idx = (N0VT == MVT::i32) ? X86::SUBREG_32BIT :
-                      (N0VT == MVT::i16) ? X86::SUBREG_16BIT :
-                        (Subtarget->is64Bit()) ? X86::SUBREG_8BIT : 0;
-      
-      // If we don't have a subreg Idx, let generated ISel have a try.
-      if (Idx == 0)
-        break;
-        
-      // If we have an index, generate an insert_subreg into undef.
-      AddToISelQueue(N0);
-      SDValue Undef = 
-        SDValue(CurDAG->getTargetNode(X86::IMPLICIT_DEF, NVT), 0);
-      SDValue SRIdx = CurDAG->getTargetConstant(Idx, MVT::i32);
-      SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
-                                              NVT, Undef, N0, SRIdx);
-
-#ifndef NDEBUG
-      DOUT << std::string(Indent-2, ' ') << "=> ";
-      DEBUG(ResNode->dump(CurDAG));
-      DOUT << "\n";
-      Indent -= 2;
-#endif
-      return ResNode;
-    }
-    
     case ISD::SIGN_EXTEND_INREG: {
-      SDValue N0 = Node->getOperand(0);
-      AddToISelQueue(N0);
-      
       MVT SVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
-      SDValue TruncOp = SDValue(getTruncate(N0, SVT), 0);
-      unsigned Opc = 0;
-      switch (NVT.getSimpleVT()) {
-      default: assert(0 && "Unknown sign_extend_inreg!");
-      case MVT::i16:
-        if (SVT == MVT::i8) Opc = X86::MOVSX16rr8;
-        else assert(0 && "Unknown sign_extend_inreg!");
-        break;
-      case MVT::i32:
-        switch (SVT.getSimpleVT()) {
-        default: assert(0 && "Unknown sign_extend_inreg!");
-        case MVT::i8:  Opc = X86::MOVSX32rr8;  break;
-        case MVT::i16: Opc = X86::MOVSX32rr16; break;
-        }
-        break;
-      case MVT::i64:
-        switch (SVT.getSimpleVT()) {
+      if (SVT == MVT::i8 && !Subtarget->is64Bit()) {
+        SDValue N0 = Node->getOperand(0);
+        AddToISelQueue(N0);
+      
+        SDValue TruncOp = SDValue(getTruncateTo8Bit(N0), 0);
+        unsigned Opc = 0;
+        switch (NVT.getSimpleVT()) {
         default: assert(0 && "Unknown sign_extend_inreg!");
-        case MVT::i8:  Opc = X86::MOVSX64rr8;  break;
-        case MVT::i16: Opc = X86::MOVSX64rr16; break;
-        case MVT::i32: Opc = X86::MOVSX64rr32; break;
+        case MVT::i16:
+          Opc = X86::MOVSX16rr8;
+          break;
+        case MVT::i32:
+          Opc = X86::MOVSX32rr8; 
+          break;
         }
-        break;
-      }
       
-      SDNode *ResNode = CurDAG->getTargetNode(Opc, NVT, TruncOp);
+        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;
+        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;
+        return ResNode;
+      }
       break;
     }
     
     case ISD::TRUNCATE: {
-      SDValue Input = Node->getOperand(0);
-      AddToISelQueue(Node->getOperand(0));
-      SDNode *ResNode = getTruncate(Input, NVT);
+      if (NVT == MVT::i8 && !Subtarget->is64Bit()) {
+        SDValue Input = Node->getOperand(0);
+        AddToISelQueue(Node->getOperand(0));
+        SDNode *ResNode = getTruncateTo8Bit(Input);
       
 #ifndef NDEBUG
         DOUT << std::string(Indent-2, ' ') << "=> ";
@@ -1598,7 +1550,8 @@
         DOUT << "\n";
         Indent -= 2;
 #endif
-      return ResNode;
+        return ResNode;
+      }
       break;
     }
 

Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=55078&r1=55077&r2=55078&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original)
+++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Wed Aug 20 16:27:32 2008
@@ -1254,24 +1254,40 @@
 def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
 
 // extload
-def : Pat<(extloadi64i1 addr:$src),  (MOVZX64rm8  addr:$src)>;
-def : Pat<(extloadi64i8 addr:$src),  (MOVZX64rm8  addr:$src)>;
-def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
-def : Pat<(extloadi64i32 addr:$src), 
-          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src), 
-                                                  x86_subreg_32bit)>;
-
-// anyext -> zext
-def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8  GR8 :$src)>;
-def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16:$src)>;
+def : Pat<(extloadi64i1 addr:$src),
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV8rm addr:$src),
+                         x86_subreg_8bit)>;
+def : Pat<(extloadi64i8 addr:$src),
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV8rm addr:$src),
+                         x86_subreg_8bit)>;
+def : Pat<(extloadi64i16 addr:$src),
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV16rm addr:$src),
+                         x86_subreg_16bit)>;
+def : Pat<(extloadi64i32 addr:$src),
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
+                         x86_subreg_32bit)>;
+def : Pat<(extloadi16i1 addr:$src), 
+          (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src), 
+                         x86_subreg_8bit)>,
+         Requires<[In64BitMode]>;
+def : Pat<(extloadi16i8 addr:$src), 
+          (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src), 
+                         x86_subreg_8bit)>,
+         Requires<[In64BitMode]>;
+
+// anyext
+def : Pat<(i64 (anyext GR8:$src)),
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>;
+def : Pat<(i64 (anyext GR16:$src)),
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR16:$src, x86_subreg_16bit)>;
 def : Pat<(i64 (anyext GR32:$src)), 
           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>;
-
-def : Pat<(i64 (anyext (loadi8  addr:$src))), (MOVZX64rm8  addr:$src)>;
-def : Pat<(i64 (anyext (loadi16 addr:$src))), (MOVZX64rm16 addr:$src)>;
-def : Pat<(i64 (anyext (loadi32 addr:$src))), 
-          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src), 
-                                                    x86_subreg_32bit)>;
+def : Pat<(i16 (anyext GR8:$src)),
+          (INSERT_SUBREG (i16 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
+         Requires<[In64BitMode]>;
+def : Pat<(i32 (anyext GR8:$src)),
+          (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
+         Requires<[In64BitMode]>;
 
 //===----------------------------------------------------------------------===//
 // Some peepholes
@@ -1295,6 +1311,34 @@
            (MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, x86_subreg_8bit)))>,
       Requires<[In64BitMode]>;
 
+// sext_inreg patterns
+def : Pat<(sext_inreg GR64:$src, i32),
+          (MOVSX64rr32 (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)))>;
+def : Pat<(sext_inreg GR64:$src, i16),
+          (MOVSX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>;
+def : Pat<(sext_inreg GR64:$src, i8),
+          (MOVSX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>;
+def : Pat<(sext_inreg GR32:$src, i8),
+          (MOVSX32rr8 (i8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)))>,
+      Requires<[In64BitMode]>;
+def : Pat<(sext_inreg GR16:$src, i8),
+          (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)))>,
+      Requires<[In64BitMode]>;
+
+// trunc patterns
+def : Pat<(i32 (trunc GR64:$src)),
+          (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
+def : Pat<(i16 (trunc GR64:$src)),
+          (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>;
+def : Pat<(i8 (trunc GR64:$src)),
+          (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>;
+def : Pat<(i8 (trunc GR32:$src)),
+          (i8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>,
+      Requires<[In64BitMode]>;
+def : Pat<(i8 (trunc GR16:$src)),
+          (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit))>,
+      Requires<[In64BitMode]>;
+
 // (shl x, 1) ==> (add x, x)
 def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
 

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=55078&r1=55077&r2=55078&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Aug 20 16:27:32 2008
@@ -2784,19 +2784,21 @@
 
 // extload bool -> extload byte
 def : Pat<(extloadi8i1 addr:$src),   (MOV8rm      addr:$src)>;
-def : Pat<(extloadi16i1 addr:$src),  (MOVZX16rm8  addr:$src)>;
+def : Pat<(extloadi16i1 addr:$src),  (MOVZX16rm8  addr:$src)>,
+         Requires<[In32BitMode]>;
 def : Pat<(extloadi32i1 addr:$src),  (MOVZX32rm8  addr:$src)>;
-def : Pat<(extloadi16i8 addr:$src),  (MOVZX16rm8  addr:$src)>;
+def : Pat<(extloadi16i8 addr:$src),  (MOVZX16rm8  addr:$src)>,
+         Requires<[In32BitMode]>;
 def : Pat<(extloadi32i8 addr:$src),  (MOVZX32rm8  addr:$src)>;
 def : Pat<(extloadi32i16 addr:$src), (MOVZX32rm16 addr:$src)>;
 
-// anyext -> zext
-def : Pat<(i16 (anyext GR8 :$src)), (MOVZX16rr8  GR8 :$src)>;
-def : Pat<(i32 (anyext GR8 :$src)), (MOVZX32rr8  GR8 :$src)>;
-def : Pat<(i32 (anyext GR16:$src)), (MOVZX32rr16 GR16:$src)>;
-def : Pat<(i16 (anyext (loadi8  addr:$src))), (MOVZX16rm8  addr:$src)>;
-def : Pat<(i32 (anyext (loadi8  addr:$src))), (MOVZX32rm8  addr:$src)>;
-def : Pat<(i32 (anyext (loadi16 addr:$src))), (MOVZX32rm16 addr:$src)>;
+// anyext
+def : Pat<(i16 (anyext GR8 :$src)), (MOVZX16rr8  GR8 :$src)>,
+         Requires<[In32BitMode]>;
+def : Pat<(i32 (anyext GR8 :$src)), (MOVZX32rr8  GR8 :$src)>,
+         Requires<[In32BitMode]>;
+def : Pat<(i32 (anyext GR16:$src)),
+          (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR16:$src, x86_subreg_16bit)>;
 
 // (and (i32 load), 255) -> (zextload i8)
 def : Pat<(i32 (and (loadi32 addr:$src), (i32 255))), (MOVZX32rm8 addr:$src)>;
@@ -2808,16 +2810,38 @@
 
 // r & (2^16-1) ==> movz
 def : Pat<(and GR32:$src1, 0xffff),
-           (MOVZX32rr16 (i16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit)))>;
+          (MOVZX32rr16 (i16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit)))>;
 // r & (2^8-1) ==> movz
 def : Pat<(and GR32:$src1, 0xff),
-           (MOVZX32rr8 (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src1),
-                                           x86_subreg_8bit)))>,
+          (MOVZX32rr8 (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src1),
+                                          x86_subreg_8bit)))>,
       Requires<[In32BitMode]>;
 // r & (2^8-1) ==> movz
 def : Pat<(and GR16:$src1, 0xff),
-           (MOVZX16rr8 (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src1),
-                                           x86_subreg_8bit)))>,
+          (MOVZX16rr8 (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src1),
+                                          x86_subreg_8bit)))>,
+      Requires<[In32BitMode]>;
+
+// sext_inreg patterns
+def : Pat<(sext_inreg GR32:$src, i16),
+          (MOVSX32rr16 (i16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit)))>;
+def : Pat<(sext_inreg GR32:$src, i8),
+          (MOVSX32rr8 (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src),
+                                          x86_subreg_8bit)))>,
+      Requires<[In32BitMode]>;
+def : Pat<(sext_inreg GR16:$src, i8),
+          (MOVSX16rr8 (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src),
+                                          x86_subreg_8bit)))>,
+      Requires<[In32BitMode]>;
+
+// trunc patterns
+def : Pat<(i16 (trunc GR32:$src)),
+          (i16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit))>;
+def : Pat<(i8 (trunc GR32:$src)),
+          (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src), x86_subreg_8bit))>,
+      Requires<[In32BitMode]>;
+def : Pat<(i8 (trunc GR16:$src)),
+          (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src), x86_subreg_8bit))>,
       Requires<[In32BitMode]>;
 
 // (shl x, 1) ==> (add x, x)





More information about the llvm-commits mailing list