[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp

Chris Lattner sabre at nondot.org
Sun Feb 25 19:19:13 PST 2007



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.337 -> 1.338
---
Log message:

in X86-64 CCC, i8/i16 arguments are already properly zext/sext'd on input.
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



---
Diffs of the changes:  (+19 -14)

 X86ISelLowering.cpp |   33 +++++++++++++++++++--------------
 1 files changed, 19 insertions(+), 14 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.337 llvm/lib/Target/X86/X86ISelLowering.cpp:1.338
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.337	Sun Feb 25 17:10:46 2007
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Sun Feb 25 21:18:56 2007
@@ -1137,12 +1137,6 @@
   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 @@
 
   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 @@
       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:






More information about the llvm-commits mailing list