Be bug compatible with gcc by returning MMX values in RAX.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65274 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td
index 6742a90..80bdbd0 100644
--- a/lib/Target/X86/X86CallingConv.td
+++ b/lib/Target/X86/X86CallingConv.td
@@ -72,8 +72,9 @@
   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>
 ]>;
 
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index efcb3f4..674a633 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -997,6 +997,14 @@
       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 @@
 
     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(),