<div dir="ltr">__uint128_t isn't getting the usual x86 handling. I think the usual handling for i128 return would be rdx:rax. Instead I believe it's being coerced to v2i64 by this code in clang/lib/CodeGen/TargetInfo.cpp<div><br></div><div>      // Mingw64 GCC returns i128 in XMM0. Coerce to v2i64 to handle that.<br>      // Clang matches them for compatibility.<br>      return ABIArgInfo::getDirect(llvm::FixedVectorType::get(<br>          llvm::Type::getInt64Ty(getVMContext()), 2));<br><div><br><div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">~Craig</div></div><br></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Sep 8, 2020 at 11:57 AM Reid Kleckner via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div>The code that you have has a large `#ifndef __clang__` block in it, and IMO that explains the ABI difference.</div><div><br></div><div>As you note, MSVC does not have native support for 128 bit integers, so there is no reason for Clang to attempt to be ABI compatible.</div><div><br></div><div>The __uint128_t arguments are passed indirectly because MSVC has a rule that requires arguments larger than 64 bits to be passed indirectly by address. I believe exceptions to that rule, such as vector arguments, are made on a case-by-case basis. No such rule exists for return values, so we get the usual i128 handling for x86 instead.</div><div><br></div><div>---</div><div><br></div><div>I see that you are interested in using compiler-rt, presumably on Windows, and maybe from MSVC compiled objects. I think the proper fix for your use case is to change compiler-rt to use a union when passing these types by value.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 3, 2020 at 5:35 PM Stefan Kanthak via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Objects compiled for the MS-ABI don't conform to it!<br>
<br>
Data types beyond 64 bit MUST BE returned by the callee via the<br>
hidden first argument allocated by the caller, NOT in XMM0!<br>
<br>
Demo/proof: from this source<br>
<br>
--- llvm-bug.c ---<br>
#ifndef __clang__<br>
typedef struct {<br>
    unsigned __int64 low;<br>
    unsigned __int64 high;<br>
} __uint128_t; <br>
#else<br>
__attribute__((ms_abi))<br>
#endif<br>
__uint128_t __udivmodti4(__uint128_t dividend, __uint128_t divisor, __uint128_t *remainder) {<br>
    if (remainder != 0)<br>
        *remainder = divisor;<br>
    return dividend;<br>
}<br>
--- EOF ---<br>
<br>
clang -c -O1 generates the following INCOMPATIBLE and WRONG code:<br>
<br>
__udivmodti4 proc public<br>
        movaps  xmm0, xmmword ptr [rcx]<br>
        test    r8, r8<br>
        jz      0f<br>
        movaps  xmm1, xmmword ptr [rdx]<br>
        movaps  xmmword ptr [r8], xmm1<br>
0:      ret<br>
__udivmodti4 endp<br>
<br>
<br>
clang's misunderstanding of the MS-ABI can be clearly seen here:<br>
<br>
- RCX holds the address of the return value, NOT the address<br>
  of the dividend;<br>
<br>
- RDX holds the address of the dividend, NOT the address of<br>
  the divisor;<br>
<br>
- R8 holds the address of the divisor, NOT the address of the<br>
  remainder;<br>
<br>
- R9 holds the address of the remainder;<br>
<br>
- aggregate data types are NOT returned in XMM0, but via the<br>
  hidden first argument addressed by RCX;<br>
<br>
- the address of the hidden first argument is returned in RAX!<br>
<br>
JFTR: an 128-bit integer data type is not supported by MS.<br>
      clang is also rather confused here: why is the return<br>
      value mapped to an XMM register, but not the arguments?<br>
<br>
<br>
Microsoft's CL.EXE -c -Ox generates the following (of course)<br>
CONFORMANT code:<br>
<br>
__udivmodti4 proc public<br>
; Line 10<br>
        test    r9, r9<br>
        je      SHORT $LN1@udivmodti4<br>
; Line 11<br>
        mov     rax, QWORD PTR [r8]<br>
        mov     QWORD PTR [r9], rax<br>
        mov     rax, QWORD PTR [r8+8]<br>
        mov     QWORD PTR [r9+8], rax<br>
$LN1@udivmodti4:<br>
; Line 12<br>
        mov     rax, QWORD PTR [rdx]<br>
        mov     QWORD PTR [rcx], rax<br>
        mov     rax, QWORD PTR [rdx+8]<br>
        mov     QWORD PTR [rcx+8], rax<br>
        mov     rax, rcx<br>
; Line 13<br>
        ret     0<br>
__udivmodti4 endp<br>
<br>
<br>
NOT AMUSED<br>
Stefan<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>