[LLVMdev] [cfe-dev] Bug in ARM Thumb inline asm?

Renato Golin renato.golin at linaro.org
Tue Feb 10 18:51:39 PST 2015


On 11 February 2015 at 06:39, James Molloy <james at jamesmolloy.co.uk> wrote:
> My belief is that we don't fully support this syntax. I believe, and I'm
> sure Renato on CC will tell me if I'm wrong as he implemented it, that we
> only support this for non-allocatable registers, such as SP or FP.

Hi James,

We do support that syntax, and that's the only syntax for local
allocatable registers we support. But I'm not sure if we guarantee
that the register won't be clobbered in between, especially if you're
using macros in inline functions.

The main issue here is that such a macro would be expanded inside a
function that is already using a lot of registers for whatever reasons
and even though the compiler can try to guarantee it will assign a
specific register inside the inline asm, it won't have much effect
outside of it, and this is what I think it's going on.


>>     6:   278c            movs    r7, #140        ; 0x8c
>>     8:   46ec            mov     ip, sp
>>     a:   4619            mov     r1, r3
>>     c:   68bc            ldr     r4, [r7, #8]    ; XXX r7 is clobbered
>>     e:   4663            mov     r3, ip
>>    10:   df00            svc     0
>>    12:   f7ff fffe       bl      0 <__syscall_ret>

That code seems very odd... It may be a result of the outside function
(lseek) intermixing code with the macro after some heavy optimisation.


>> register long r7 __asm__("r7") = n;
>> make any guarantee about the value of r7 in the asm block?

I believe the guarantee is IFF the inline asm immediately follows,
which is what you have, so I'm not sure why r7 is being clobbered in
this case. It may be a side effect of some other optimisation or just
that the guarantee is not being kept in that special case.


>> Adding the -fomit-frame-pointer flag fixes it,

That sounds like a coincidence... :)


>> but is the bug in the code or in the compiler?

Hard to say. Inline asm is a poorly documented GNU extension that was
not designed in any meaningful way but evolved from whatever was out
there pretty much like a genetic algorithm. Clang/LLVM tries to
rationalise the implementation and, for obvious reasons, will get
different behaviour, not necessarily wrong. Basically, YMMV.

The first thing is to duplicate the macro code inside the static
inline function and see if the problem disappears. Also, try with
lower optimisation levels and if that fixes it, run bugpoint on a
reduced case to spot what pass "breaks" it.

I think we have to approach the problem in a different way, though. Is
there a better way of doing this?

cheers,
--renato



More information about the llvm-dev mailing list