https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66563

--- Comment #29 from Kazumoto Kojima <kkojima at gcc dot gnu.org> ---
I've reproduced one problem for mpfr-3.1.3 with the cross
compiler.  For some TLS variables, we need to set GOT address
to the PIC register R12 even in non-PIC objects.  Here is
a hypothetical example what is going on.  Assume that we
computed GOT address twice in a function:

        mova    1f,r0
        mov.l   1f,r12
        add     r0,r12
        ...
1:      .long   _GLOBAL_OFFSET_TABLE_   ! GOTPC relocation
        ...

        mova    2f,r0
        mov.l   2f,r12
        add     r0,r12
        ...
2:      .long   _GLOBAL_OFFSET_TABLE_   ! GOTPC relocation

GOTPC relocation means that the value should set to (GOT address - .)
by linker.
Unfortunately, 4.9 and later compilers 'optimize' the above code
to the code like

        mova    1f,r0
        mov.l   1f,r12
        mov     r12,r11
        add     r0,r12
        ...
1:      .long   _GLOBAL_OFFSET_TABLE_   ! GOTPC relocation
        ...

        mova    2f,r0
        mov.l   r11,r12
        add     r0,r12
        ...
2:      .long   _GLOBAL_OFFSET_TABLE_   ! GOTPC relocation

i.e. try to memoize the _GLOBAL_OFFSET_TABLE_ 'value'.  This doesn't
work because the 2nd computation gets (GOT address - 1f) + 2f
instead of the correct GOT address.  This issue will affect the non-PIC
objects which use TLS aggressively.

Reply via email to