[llvm-dev] question about ARM 32 big endian

Strahinja Petrovic via llvm-dev llvm-dev at lists.llvm.org
Fri Jun 17 06:31:32 PDT 2016


Thanks for response, I expected something like that, just needed 
confirmation.
I will make a patch for this soon.

Strahinja

On 17.06.2016. 15:18, John Brawn wrote:
> Structs are passed as if loaded from memory by an LDM instruction, and
> main is doing that correctly. The problem is in how f is then extracting
> the elements from that value.
>
> It looks like this is specifically a bug in clang's handling of va_arg -
> if you change f to take a struct tiny instead of a variadic list then it
> behaves correctly.
>
> Looking at the -O0 emit-llvm output of clang the va_arg is generated as
>
>    %0 = bitcast %struct.__va_list* %ap to i8**
>    %argp.cur = load i8*, i8** %0, align 4
>    %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 4
>    store i8* %argp.next, i8** %0, align 4
>    %1 = getelementptr inbounds i8, i8* %argp.cur, i32 1
>    %2 = bitcast i8* %1 to %struct.tiny*
>    %3 = bitcast %struct.tiny* %x to i8*
>    %4 = bitcast %struct.tiny* %2 to i8*
>    call void @llvm.memcpy.p0i8.p0i8.i32(i8* %3, i8* %4, i32 3, i32 1, i1 false)
>
> It's that '%1 = getelementptr inbounds i8, i8* %argp.cur, i32 1' which is
> wrong: the offset should be 0 not 1.
>
> John
>
>> -----Original Message-----
>> From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of
>> Strahinja Petrovic via llvm-dev
>> Sent: 17 June 2016 11:22
>> To: llvm-dev at lists.llvm.org
>> Subject: [llvm-dev] question about ARM 32 big endian
>>
>> Hi everyone,
>>
>> I have a question about ARM 32 big endian calling convention. It's about
>> sending small structures as function argument.
>> For example if passing 3 chars in a structure should alignment in
>> register (argument register for passing those chars in function) be
>> right-adjusted ?
>> LLVM (trunk version) is passing those chars left-adjusted in register,
>> and trying to read them  like they are right-adjusted and there is a
>> problem.
>> GCC is passing chars in register left-adjusted and works properly.
>>
>> Here is the example:
>>
>> #include <stdarg.h>
>>
>> struct tiny
>> {
>>     char c;
>>     char d;
>>     char e;
>> };
>>
>> f (int n, ...)
>> {
>>     struct tiny x;
>>
>>     va_list ap;
>>     va_start (ap,n);
>>     x = va_arg (ap,struct tiny);
>>     if (x.c !=  10)
>>         abort();
>>     if (x.d !=  11)
>>         abort();
>>     if(x.e != 12)
>>       abort();
>>     va_end (ap);
>> }
>> main ()
>> {
>>     struct tiny x[3];
>>     x[0].c = 10;
>>     x[0].d = 11;
>>     x[0].e = 12;
>>     f (3, x[0]);
>>     exit(0);
>> }
>>
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list