title: GCC/Clang x86_64 C++ ABI mismatch when returning a tuple?
body: <p>When trying <a href="https://stackoverflow.com/q/25381736/3919155">to optimize return values on x86_64</a>, I noticed a strange thing. Namely, given the code:</p>
  
  <pre><code>#include &lt;cstdint&gt;
  #include &lt;tuple&gt;
  #include &lt;utility&gt;
  
  using namespace std;
  
  constexpr uint64_t a = 1u;
  constexpr uint64_t b = 2u;
  
  pair&lt;uint64_t, uint64_t&gt; f() { return {a, b}; }
  tuple&lt;uint64_t, uint64_t&gt; g() { return tuple&lt;uint64_t, uint64_t&gt;{a, b}; }
  </code></pre>
  
  <p><a href="https://gcc.godbolt.org/#compilers:!((compiler:clang380,options:&#39;-std%3Dc%2B%2B11+-O2&#39;,sourcez:MQSwdgxgNgrgJgUwAQB4IGcAudyYHwBQoksiqmMADlAocdPMijJiFCJgJ6EEzrgBzJGACGAWwTpKIiMixwA3AQIQA9mCwIAHpQBOSGLgBsAFgD6mJCKQBeJAEYYStRsza9B4%2BcsAjW0gAmJ2VpEF1mLwsAGk8wTFMLPCQAMwAKAEokAG8kXQQKXTBskRifAF8FJDKCCmoECLiEzBjDRu8kgQzs3PyYQqRamgb47xbI/CySpHLK6oIsEVYIMxF0dARdTFT%2BAC8EVTTQ8NaR6NjT/HSCJBvbu7ubO139tJOmzIBqJGeD1LfvdIxABEQPSSgWSxWaw2Wx%2BaUG9X%2BZyRl2u93RN0e3xAe1%2BR2GTTGbUSgKQILBQAAA%3D%3D)),filterAsm:(commentOnly:!t,directives:!t,labels:!t),version:3" rel="nofollow noreferrer">Clang 3.8 outputs</a> this assembly code for <code>f</code>:</p>
  
  <pre><code>movl $1, %eax
  movl $2, %edx
  retq
  </code></pre>
  
  <p>and this for <code>g</code>:</p>
  
  <pre><code>movl $2, %eax
  movl $1, %edx
  retq
  </code></pre>
  
  <p>which look optimal. However, when <a href="https://gcc.godbolt.org/#compilers:!((compiler:g6,options:&#39;-std%3Dc%2B%2B11+-O2&#39;,sourcez:MQSwdgxgNgrgJgUwAQB4IGcAudyYHwBQoksiqmMADlAocdPMijJiFCJgJ6EEzrgBzJGACGAWwTpKIiMixwA3AQIQA9mCwIAHpQBOSGLgBsAFgD6mJCKQBeJAEYYStRsza9B4%2BcsAjW0gAmJ2VpEF1mLwsAGk8wTFMLPCQAMwAKAEokAG8kXQQKXTBskRifAF8FJDKCCmoECLiEzBjDRu8kgQzs3PyYQqRamgb47xbI/CySpHLK6oIsEVYIMxF0dARdTFT%2BAC8EVTTQ8NaR6NjT/HSCJBvbu7ubO139tJOmzIBqJGeD1LfvdIxABEQPSSgWSxWaw2Wx%2BaUG9X%2BZyRl2u93RN0e3xAe1%2BR2GTTGbUSgKQILBQAAA%3D%3D)),filterAsm:(commentOnly:!t,directives:!t,labels:!t),version:3" rel="nofollow noreferrer">compiled with GCC 6.1</a>, while the generated assembly for <code>f</code> is identical to what Clang output, the assembly generated for <code>g</code> is:</p>
  
  <pre><code>movq %rdi, %rax
  movq $2, (%rdi)
  movq $1, 8(%rdi)
  ret
  </code></pre>
  
  <p>It looks like the type of the return value is classified as MEMORY by GCC but as INTEGER by Clang. I can confirm that linking Clang code with GCC code such code can result in segmentation faults (Clang calling GCC-compiled <code>g()</code> which writes to wherever <code>%rdi</code> happens to point) and an invalid value being returned (GCC calling Clang-compiled <code>g()</code>). Which compiler is at fault?</p>
  
  <h2>Related:</h2>
  
  <ul>
  <li><a href="https://stackoverflow.com/q/35586332/3919155">G++ and clang++ incompatibility with standard library when building shared libraries?</a></li>
  <li><a href="http://sourcerytools.com/pipermail/cxx-abi-dev/2016-February/002884.html" rel="nofollow noreferrer">[cxx-abi-dev] Non-trivial move constructor</a></li>
  </ul>
  
  <h2>See also</h2>
  
  <ul>
  <li><a href="http://www.x86-64.org/documentation/abi.pdf" rel="nofollow noreferrer">System V Application Binary Interface. AMD64 Architecture Processor Supplement. Draft Version 0.99.5</a></li>
  </ul>