[llvm-dev] BUG: complete misunterstanding of the MS-ABI
Craig Topper via llvm-dev
llvm-dev at lists.llvm.org
Tue Sep 8 12:27:23 PDT 2020
__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
// Mingw64 GCC returns i128 in XMM0. Coerce to v2i64 to handle that.
// Clang matches them for compatibility.
return ABIArgInfo::getDirect(llvm::FixedVectorType::get(
llvm::Type::getInt64Ty(getVMContext()), 2));
~Craig
On Tue, Sep 8, 2020 at 11:57 AM Reid Kleckner via llvm-dev <
llvm-dev at lists.llvm.org> wrote:
> The code that you have has a large `#ifndef __clang__` block in it, and
> IMO that explains the ABI difference.
>
> 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.
>
> 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.
>
> ---
>
> 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.
>
> On Thu, Sep 3, 2020 at 5:35 PM Stefan Kanthak via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>> Objects compiled for the MS-ABI don't conform to it!
>>
>> Data types beyond 64 bit MUST BE returned by the callee via the
>> hidden first argument allocated by the caller, NOT in XMM0!
>>
>> Demo/proof: from this source
>>
>> --- llvm-bug.c ---
>> #ifndef __clang__
>> typedef struct {
>> unsigned __int64 low;
>> unsigned __int64 high;
>> } __uint128_t;
>> #else
>> __attribute__((ms_abi))
>> #endif
>> __uint128_t __udivmodti4(__uint128_t dividend, __uint128_t divisor,
>> __uint128_t *remainder) {
>> if (remainder != 0)
>> *remainder = divisor;
>> return dividend;
>> }
>> --- EOF ---
>>
>> clang -c -O1 generates the following INCOMPATIBLE and WRONG code:
>>
>> __udivmodti4 proc public
>> movaps xmm0, xmmword ptr [rcx]
>> test r8, r8
>> jz 0f
>> movaps xmm1, xmmword ptr [rdx]
>> movaps xmmword ptr [r8], xmm1
>> 0: ret
>> __udivmodti4 endp
>>
>>
>> clang's misunderstanding of the MS-ABI can be clearly seen here:
>>
>> - RCX holds the address of the return value, NOT the address
>> of the dividend;
>>
>> - RDX holds the address of the dividend, NOT the address of
>> the divisor;
>>
>> - R8 holds the address of the divisor, NOT the address of the
>> remainder;
>>
>> - R9 holds the address of the remainder;
>>
>> - aggregate data types are NOT returned in XMM0, but via the
>> hidden first argument addressed by RCX;
>>
>> - the address of the hidden first argument is returned in RAX!
>>
>> JFTR: an 128-bit integer data type is not supported by MS.
>> clang is also rather confused here: why is the return
>> value mapped to an XMM register, but not the arguments?
>>
>>
>> Microsoft's CL.EXE -c -Ox generates the following (of course)
>> CONFORMANT code:
>>
>> __udivmodti4 proc public
>> ; Line 10
>> test r9, r9
>> je SHORT $LN1 at udivmodti4
>> ; Line 11
>> mov rax, QWORD PTR [r8]
>> mov QWORD PTR [r9], rax
>> mov rax, QWORD PTR [r8+8]
>> mov QWORD PTR [r9+8], rax
>> $LN1 at udivmodti4:
>> ; Line 12
>> mov rax, QWORD PTR [rdx]
>> mov QWORD PTR [rcx], rax
>> mov rax, QWORD PTR [rdx+8]
>> mov QWORD PTR [rcx+8], rax
>> mov rax, rcx
>> ; Line 13
>> ret 0
>> __udivmodti4 endp
>>
>>
>> NOT AMUSED
>> Stefan
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200908/d1bb1a5d/attachment.html>
More information about the llvm-dev
mailing list