On Thu, Jul 28, 2011 at 3:03 PM, Uros Bizjak <[email protected]> wrote:
> On Thu, Jul 28, 2011 at 10:15 PM, H.J. Lu <[email protected]> wrote:
>
>>>>>>>> TP is 32bit in x32 For load_tp_x32, we load SImode value and
>>>>>>>> zero-extend to DImode. For add_tp_x32, we are adding SImode
>>>>>>>> value. We can't pretend TP is 64bit. load_tp_x32 and add_tp_x32
>>>>>>>> must take SImode TP.
>
>> Here is the revised patch. The difference is I changed *add_tp_x32 to
>> SImode.
>> For
>>
>> ---
>> extern __thread int __libc_errno __attribute__ ((tls_model
>> ("initial-exec")));
>>
>> int *
>> __errno_location (void)
>> {
>> return &__libc_errno;
>> }
>> ---
>>
>> compiled with -mx32 -O2 -fPIC DImode *add_tp_x32 generates:
>>
>> movq __libc_errno@gottpoff(%rip), %rax
>> addl %fs:0, %eax
>> mov %eax, %eax
>> ret
>>
>> SImode *add_tp_x32 generates:
>>
>> movl %fs:0, %eax
>> addl __libc_errno@gottpoff(%rip), %eax
>> ret
>
> This happens because combine can't combine DImode load and SImode plus
> RTXes. These RTXes have to be in Pmode, see the intention in
> legitimize_tls_address, also for TARGET_GNU2_TLS.
>
> Can you please debug what goes wrong with tp_add_x32 in DImode?
>
We start with
insn 5 2 6 2 (set (reg:DI 63)
(unspec:DI [
(const_int 0 [0])
] UNSPEC_TP)) err.i:6 716 {*load_tp_x32}
(nil))
(insn 6 5 7 2 (set (reg:DI 64)
(mem/u/c:DI (const:DI (unspec:DI [
(symbol_ref:SI ("__libc_errno") [flags 0x60] <var_decl
0x7ffff085b140 __libc_errno>)
] UNSPEC_GOTNTPOFF)) [0 S8 A8])) err.i:6 62 {*movdi_internal
_rex64}
(nil))
(insn 7 6 8 2 (parallel [
(set (reg:DI 65)
(plus:DI (reg:DI 63)
(reg:DI 64)))
(clobber (reg:CC 17 flags))
]) err.i:6 251 {*adddi_1}
(expr_list:REG_DEAD (reg:DI 64)
(expr_list:REG_DEAD (reg:DI 63)
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil)))))
With DImode *add_tp_x32, combine matches
(parallel [
(set (reg:DI 65)
(plus:DI (unspec:DI [
(const_int 0 [0])
] UNSPEC_TP)
(reg:DI 64)))
(clobber (reg:CC 17 flags))
])
first. It turns out that it isn't a very good choice since
it prevents combine to try
(parallel [
(set (reg:DI 65)
(plus:DI (reg:DI 63)
(mem/u/c:DI (const:DI (unspec:DI [
(symbol_ref:SI ("__libc_errno") [flags
0x60] <var_decl 0x7
ffff085b140 __libc_errno>)
] UNSPEC_GOTNTPOFF)) [0 S8 A8])))
(clobber (reg:CC 17 flags))
])
I am not sure how useful *add_tp_XXX pattern is.
--
H.J.