https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59401
--- Comment #5 from Oleg Endo <olegendo at gcc dot gnu.org> ---
Ugh, there's actually another problem with this thing, I think:
void other (void);
int test0 (void)
{
int x = ((int*)__builtin_thread_pointer ())[2];
other ();
return ((int*)__builtin_thread_pointer ())[5] + x;
}
compiles to:
stc gbr,r8
mov.l .L3,r1
jsr @r1
mov.l @(8,r8),r9
mov.l @(20,r8),r0 << use GBR value before the call
add r9,r0
lds.l @r15+,pr
mov.l @r15+,r9
rts
mov.l @r15+,r8
By default, GBR is marked as call-clobbered. Currently, if the GBR mem
optimization thing sees any calls in a function it will not form the GBR
address. It's not optimal, but was supposed to produce at least correct code.
Obviously the code above is wrong. The __builtin_thread_pointer insn is
hoisted by something else before combine/split1. The patch from r216128 is
incomplete. I'm checking it out.