Be bug compatible with gcc by returning MMX values in RAX.
authorEvan Cheng <evan.cheng@apple.com>
Sun, 22 Feb 2009 08:05:12 +0000 (08:05 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Sun, 22 Feb 2009 08:05:12 +0000 (08:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65274 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86CallingConv.td
lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/ret-mmx.ll

index 6742a90058a26f6e43727131b5f65b0004fb0772..80bdbd0b1cfa6e0661f62a658e6c7e50ff90b9e4 100644 (file)
@@ -72,8 +72,9 @@ def RetCC_X86_64_C : CallingConv<[
   CCIfType<[f32], CCAssignToReg<[XMM0, XMM1]>>,
   CCIfType<[f64], CCAssignToReg<[XMM0, XMM1]>>,
 
-  // MMX vector types are always returned in XMM0.
-  CCIfType<[v8i8, v4i16, v2i32, v1i64, v2f32], CCAssignToReg<[XMM0, XMM1]>>,
+  // MMX vector types are always returned in RAX. This seems to disagree with
+  // ABI documentation but is bug compatible with gcc.
+  CCIfType<[v8i8, v4i16, v2i32, v1i64, v2f32], CCAssignToReg<[RAX]>>,
   CCDelegateTo<RetCC_X86Common>
 ]>;
 
index efcb3f47ff77290e9ffffee709aea19facb7c5b1..674a633244d56172e84c057594bb2e4d4644b316 100644 (file)
@@ -997,6 +997,14 @@ SDValue X86TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
       continue;
     }
 
+    // 64-bit vector (MMX) values are returned in RAX.
+    if (Subtarget->is64Bit()) {
+      MVT ValVT = ValToCopy.getValueType();
+      if (VA.getLocReg() == X86::RAX &&
+          ValVT.isVector() && ValVT.getSizeInBits() == 64)
+        ValToCopy = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i64, ValToCopy);
+    }
+
     Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), ValToCopy, Flag);
     Flag = Chain.getValue(1);
   }
@@ -1073,13 +1081,10 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall,
 
     SDValue Val;
     if (Is64Bit && CopyVT.isVector() && CopyVT.getSizeInBits() == 64) {
-      // For x86-64, MMX values are returned in XMM0 and XMM1. Issue an
-      // extract_vector_elt to i64 and then bit_convert it to the desired type.
+      // For x86-64, MMX values are returned in RAX.
       Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(),
-                                 MVT::v2i64, InFlag).getValue(1);
+                                 MVT::i64, InFlag).getValue(1);
       Val = Chain.getValue(0);
-      Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i64,
-                        Val, DAG.getConstant(0, MVT::i64));
       Val = DAG.getNode(ISD::BIT_CONVERT, dl, CopyVT, Val);
     } else {
       Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(),
index fe9380585de38bf1e113d3404dda4f9fa78a9842..6587eabb76650d9af765a45feb64865f5d4bb8bc 100644 (file)
@@ -3,11 +3,15 @@
 
 @g_v1di = external global <1 x i64>
 
-define void @test_v1di() nounwind {
+define void @t1() nounwind {
 entry:
        %call = call <1 x i64> @return_v1di()           ; <<1 x i64>> [#uses=0]
        store <1 x i64> %call, <1 x i64>* @g_v1di
         ret void
 }
 
+define <1 x i64> @t2() nounwind {
+       ret <1 x i64> <i64 1>
+}
+
 declare <1 x i64> @return_v1di()