https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94177
Bug ID: 94177
Summary: TLS global-dynamic model clobbers function parameter
on AIX
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: dje at gcc dot gnu.org
Target Milestone: ---
Target: powerpc-ibm-aix*
In global-dynamic model, if a TLS variable first is referenced in the argument
list to a function call, GCC can load the parameters to the call before
invoking the function to legitimize the TLS variable, and the legitimize
function clobbers some of the same function argument registers.
extern int foo (char *, int *, int);
int main()
{
static __thread int result;
foo ("%p %u\n", &result, 169);
return 0;
}
$ gcc -fPIC -S bug_tls.c
li 5,169
lwz 10,LCM..1(2)
lwz 9,LC..1(2)
mr 3,10
mr 4,9
bla __tls_get_addr <*** clobbers r4, r5 already loaded with arguments
to foo
mr 9,3
mr 4,9
lwz 3,LC..2(2)
bl .foo
The pattern that generates __tls_get_addr shows that it clobbers r4 and r5
(define_insn "tls_get_addr_internal<mode>"
[(set (reg:P 3)
(unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
(clobber (reg:P 0))
(clobber (reg:P 4))
(clobber (reg:P 5))
(clobber (reg:P 11))
(clobber (reg:CC CR0_REGNO))
(clobber (reg:P LR_REGNO))]
"TARGET_XCOFF && HAVE_AS_TLS"
"bla __tls_get_addr")
but GCC overwrites the parameters in calls.c during initial RTL generation.