This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: Properly generate X32 IE sequence
On Sun, Mar 11, 2012 at 11:21 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Sun, Mar 11, 2012 at 7:16 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>
>>>>>>> ? ? ? ?* config/i386/i386.c (ix86_decompose_address): Disallow fs:(reg)
>>>>>>> ? ? ? ?if Pmode != word_mode.
>>>>>>> ? ? ? ?(legitimize_tls_address): Call gen_tls_initial_exec_x32 if
>>>>>>> ? ? ? ?Pmode == SImode for x32.
>>>>>>>
>>>>>>> ? ? ? ?* config/i386/i386.md (UNSPEC_TLS_IE_X32): New.
>>>>>>> ? ? ? ?(tls_initial_exec_x32): Likewise.
>>>>>>
>>>>>> Nice solution!
>>>>>>
>>>>>> OK for mainline.
>>>>>
>>>>> Done.
>>>>>
>>>>>> BTW: Did you investigate the issue with memory aliasing?
>>>>>>
>>>>>
>>>>> It isn't a problem since it is wrapped in UNSPEC_TLS_IE_X32
>>>>> which loads address of the TLS symbol.
>>>>>
>>>>> Thanks.
>>>>>
>>>>
>>>> Since we must use reg64 in %fs:(%reg) memory operand like
>>>>
>>>> movq x@gottpoff(%rip),%reg64;
>>>> mov %fs:(%reg64),%reg
>>>>
>>>> this patch optimizes x32 TLS IE load and store by wrapping
>>>> %reg64 inside of UNSPEC when Pmode == SImode. ?OK for
>>>> trunk?
>>>
>>> I think we should just scrap all these complications and go with the
>>> idea of clearing MASK_TLS_DIRECT_SEG_REFS.
>>>
>>
>> I will give it a try.
>
> You can also revert:
>
>>>>>>> ? ? ? ?* config/i386/i386.c (ix86_decompose_address): Disallow fs:(reg)
>>>>>>> ? ? ? ?if Pmode != word_mode.
>
> then, since this part is handled later in the function.
>
Here is the patch which is equivalent to clearing MASK_TLS_DIRECT_SEG_REFS
when Pmode != word_mode. We need to keep
else if (Pmode == SImode)
{
/* Always generate
movl %fs:0, %reg32
addl xgottpoff(%rip), %reg32
to support linker IE->LE optimization and avoid
fs:(%reg32) as memory operand. */
dest = gen_reg_rtx (Pmode);
emit_insn (gen_tls_initial_exec_x32 (dest, x));
return dest;
}
to support linker IE->LE optimization. TARGET_TLS_DIRECT_SEG_REFS only affects
TLS LE access and fs:(%reg) is only generated by combine.
So the main impact of disabling TARGET_TLS_DIRECT_SEG_REFS is to disable
fs:immediate memory operand for TLS LE access, which doesn't have any problems
to begin with.
I would prefer to keep TARGET_TLS_DIRECT_SEG_REFS and disable only
fs:(%reg), which is generated by combine.
--
H.J.
--
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b101922..1ffcc85 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11478,6 +11478,7 @@ ix86_decompose_address (rtx addr, struct
ix86_address *out)
case UNSPEC:
if (XINT (op, 1) == UNSPEC_TP
+ && Pmode == word_mode
&& TARGET_TLS_DIRECT_SEG_REFS
&& seg == SEG_DEFAULT)
seg = TARGET_64BIT ? SEG_FS : SEG_GS;
@@ -11534,11 +11535,6 @@ ix86_decompose_address (rtx addr, struct
ix86_address *out)
else
disp = addr; /* displacement */
- /* Since address override works only on the (reg32) part in fs:(reg32),
- we can't use it as memory operand. */
- if (Pmode != word_mode && seg == SEG_FS && (base || index))
- return 0;
-
if (index)
{
if (REG_P (index))
@@ -12706,7 +12702,9 @@ legitimize_tls_address (rtx x, enum tls_model
model, bool for_mov)
if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
{
- base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
+ base = get_thread_pointer (for_mov
+ || Pmode != word_mode
+ || !TARGET_TLS_DIRECT_SEG_REFS);
return gen_rtx_PLUS (Pmode, base, off);
}
else
@@ -13239,7 +13237,7 @@ ix86_delegitimize_tls_address (rtx orig_x)
rtx x = orig_x, unspec;
struct ix86_address addr;
- if (!TARGET_TLS_DIRECT_SEG_REFS)
+ if (Pmode != word_mode || !TARGET_TLS_DIRECT_SEG_REFS)
return orig_x;
if (MEM_P (x))
x = XEXP (x, 0);