[llvmlinux] Wrong types in inline assembly?

Marcelo Sousa marceloabsousa at gmail.com
Fri Sep 27 09:31:21 UTC 2013


Thanks a lot Tim. Your explanation makes sense to me.

Yesterday I bumped into:
%tmp15 = tail call i64 asm "", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32* %tmp1)

This seems to me a mov with cast operation using inline assembly. Any
idea why this type of code is in Kernel? I don't think clang is
generating the asm block on its own.

Regards,
Marcelo

On Fri, Sep 27, 2013 at 7:46 AM, Tim Northover <t.p.northover at gmail.com> wrote:
> Hi Marcelo,
>
>> Can someone explain how cmpxchg can receive a struct type? That seems
>> a potential bug to me.
>
> In both cases it's a pointer-to-struct type being used for a
> constraint that's effectively "r" (i.e. the value) rather than "m"
> (i.e. a location to be loaded from/stored to).
>
> The key point is that the "value" is just a 64-bit pointer no matter
> how big struct.llist_node is.
>
> In pseudo C/Asm mixed, something like this is happening:
>
>     llist_node *rax = first;
>     llist_node *r8 = new_first;
>     if (head->first == rax) head->first = new_first;
>     else rax = head->first;
>
> where the last two lines might be captured by a "cmpxchg %r8, %headreg".
>
>> Moreover, shouldn't there be bitcasts from %struct.llist_node* to i64*?
>
> If anything, casting %tmp2 to "%struct.llist_node**" would be more
> semantically accurate, since what's actually being stored is actually
> a "%struct.llist_node*". But since all pointers are 64-bits wide it
> doesn't matter really.
>
> Cheers.
>
> Tim.
> _______________________________________________
> LLVMLinux mailing list
> LLVMLinux at lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/llvmlinux


More information about the LLVMLinux mailing list