in X86-64 CCC, i8/i16 arguments are already properly zext/sext'd on input.
authorChris Lattner <sabre@nondot.org>
Mon, 26 Feb 2007 03:18:56 +0000 (03:18 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 26 Feb 2007 03:18:56 +0000 (03:18 +0000)
Capture this so that downstream zext/sext's are optimized out.  This
compiles:
  int test(short X) { return (int)X; }

to:

_test:
        movl %edi, %eax
        ret

instead of:

_test:
        movswl %di, %eax
        ret

GCC produces this bizarre code:

_test:
        movw    %di, -12(%rsp)
        movswl  -12(%rsp),%eax
        ret

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34623 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp

index 416acf841c033be8309875318d1c41a7b3bb0958..564cb692d1466c54b39a64624a5fa938a429b73a 100644 (file)
@@ -1137,12 +1137,6 @@ X86TargetLowering::LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG) {
   unsigned NumIntRegs = 0;  // Int regs used for parameter passing.
   unsigned NumXMMRegs = 0;  // XMM regs used for parameter passing.
 
-  static const unsigned GPR8ArgRegs[] = {
-    X86::DIL, X86::SIL, X86::DL,  X86::CL,  X86::R8B, X86::R9B
-  };
-  static const unsigned GPR16ArgRegs[] = {
-    X86::DI,  X86::SI,  X86::DX,  X86::CX,  X86::R8W, X86::R9W
-  };
   static const unsigned GPR32ArgRegs[] = {
     X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
   };
@@ -1156,6 +1150,7 @@ X86TargetLowering::LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG) {
 
   for (unsigned i = 0; i < NumArgs; ++i) {
     MVT::ValueType ObjectVT = Op.getValue(i).getValueType();
+    unsigned ArgFlags = cast<ConstantSDNode>(Op.getOperand(3+i))->getValue();
     unsigned ArgIncrement = 8;
     unsigned ObjSize = 0;
     unsigned ObjIntRegs = 0;
@@ -1178,26 +1173,36 @@ X86TargetLowering::LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG) {
       case MVT::i64: {
         TargetRegisterClass *RC = NULL;
         switch (ObjectVT) {
-        default: break;
+        default: assert(0 && "Unknown integer VT!");
         case MVT::i8:
-          RC = X86::GR8RegisterClass;
-          Reg = GPR8ArgRegs[NumIntRegs];
-          break;
         case MVT::i16:
-          RC = X86::GR16RegisterClass;
-          Reg = GPR16ArgRegs[NumIntRegs];
-          break;
         case MVT::i32:
           RC = X86::GR32RegisterClass;
           Reg = GPR32ArgRegs[NumIntRegs];
+          ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i32);
           break;
         case MVT::i64:
           RC = X86::GR64RegisterClass;
           Reg = GPR64ArgRegs[NumIntRegs];
+          ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i64);
           break;
         }
         Reg = AddLiveIn(MF, Reg, RC);
-        ArgValue = DAG.getCopyFromReg(Root, Reg, ObjectVT);
+
+        // If this is an 8 or 16-bit value, it is really passed promoted to 32
+        // bits.  Insert an assert[sz]ext to capture this, then truncate to the
+        // right size.
+        if (ObjectVT == MVT::i8 || ObjectVT == MVT::i16) {
+          // FIXME: FORMAL_ARGUMENTS can't currently distinguish between an
+          // argument with undefined high bits, so we can't insert a assertzext
+          // yet.
+          if (ArgFlags & 1) {
+            unsigned ExtOpc = (ArgFlags & 1) ? ISD::AssertSext :ISD::AssertZext;
+            ArgValue = DAG.getNode(ExtOpc, MVT::i32, ArgValue,
+                                   DAG.getValueType(ObjectVT));
+            ArgValue = DAG.getNode(ISD::TRUNCATE, ObjectVT, ArgValue);
+          }
+        }
         break;
       }
       case MVT::f32: