This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix IA-32 TLS IE and LE models (take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, roland at redhat dot com, drepper at redhat dot com, gcc-patches at gcc dot gnu dot org
- Date: Thu, 8 Aug 2002 17:44:29 -0400
- Subject: [PATCH] Fix IA-32 TLS IE and LE models (take 2)
- References: <20020808182655.B18963@sunsite.ms.mff.cuni.cz> <20020808170633.GE5121@redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Thu, Aug 08, 2002 at 10:06:33AM -0700, Richard Henderson wrote:
> On Thu, Aug 08, 2002 at 06:26:55PM +0200, Jakub Jelinek wrote:
> > - tp = gen_rtx_CONST (Pmode, tp);
> > + tp = gen_rtx_MEM (Pmode, tp);
> > + RTX_UNCHANGING_P (tp) = 1;
>
> Do
>
> set_mem_alias_set (new, ix86_GOT_alias_set ());
>
> as well.
>
> > +/* { dg-do link } */
> > +/* { dg-options "-O2 -ftls-model=initial-exec" } */
> > +/* { dg-options "-O2 -ftls-model=initial-exec -march=i686" { target i?86-*-* } } */
> > +
> > +extern __thread int thr;
>
> Link? Where does thr get defined?
Ok, here is the updated patch, bootstrapped/regression tested and
Roland tested glibc build with it.
Ok to commit?
2002-08-08 Jakub Jelinek <jakub@redhat.com>
* config/i386/i386.c (legitimate_constant_p): UNSPEC_TP is not
legitimate constant.
(legitimate_pic_operand_p): Neither pic operand.
(legitimate_address_p): But legitimate address.
(get_thread_pointer): Generate MEM/u instead of CONST around
UNSPEC_TP.
(print_operand): Remove printing of UNSPEC_TP.
(print_operand_address): And print it here.
* gcc.dg/tls/opt-2.c: New test.
--- gcc/config/i386/i386.c.jj 2002-08-07 22:18:39.000000000 +0200
+++ gcc/config/i386/i386.c 2002-08-08 18:18:18.000000000 +0200
@@ -4850,8 +4850,6 @@ legitimate_constant_p (x)
{
case UNSPEC_TPOFF:
return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
- case UNSPEC_TP:
- return true;
default:
return false;
}
@@ -4914,8 +4912,6 @@ legitimate_pic_operand_p (x)
{
case UNSPEC_TPOFF:
return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
- case UNSPEC_TP:
- return true;
default:
return false;
}
@@ -5054,6 +5050,13 @@ legitimate_address_p (mode, addr, strict
debug_rtx (addr);
}
+ if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_TP)
+ {
+ if (TARGET_DEBUG_ADDR)
+ fprintf (stderr, "Success.\n");
+ return TRUE;
+ }
+
if (ix86_decompose_address (addr, &parts) <= 0)
{
reason = "decomposition failed";
@@ -5521,7 +5524,9 @@ get_thread_pointer ()
rtx tp;
tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
- tp = gen_rtx_CONST (Pmode, tp);
+ tp = gen_rtx_MEM (Pmode, tp);
+ RTX_UNCHANGING_P (tp) = 1;
+ set_mem_alias_set (tp, ix86_GOT_alias_set ());
tp = force_reg (Pmode, tp);
return tp;
@@ -6611,17 +6615,6 @@ print_operand (file, x, code)
fprintf (file, "%s", dstr);
}
- else if (GET_CODE (x) == CONST
- && GET_CODE (XEXP (x, 0)) == UNSPEC
- && XINT (XEXP (x, 0), 1) == UNSPEC_TP)
- {
- if (ASSEMBLER_DIALECT == ASM_INTEL)
- fputs ("DWORD PTR ", file);
- if (ASSEMBLER_DIALECT == ASM_ATT || USER_LABEL_PREFIX[0] == 0)
- putc ('%', file);
- fputs ("gs:0", file);
- }
-
else
{
if (code != 'P')
@@ -6660,6 +6653,16 @@ print_operand_address (file, addr)
rtx base, index, disp;
int scale;
+ if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_TP)
+ {
+ if (ASSEMBLER_DIALECT == ASM_INTEL)
+ fputs ("DWORD PTR ", file);
+ if (ASSEMBLER_DIALECT == ASM_ATT || USER_LABEL_PREFIX[0] == 0)
+ putc ('%', file);
+ fputs ("gs:0", file);
+ return;
+ }
+
if (! ix86_decompose_address (addr, &parts))
abort ();
--- gcc/testsuite/gcc.dg/tls/opt-2.c.jj 2002-08-08 18:36:32.000000000 +0200
+++ gcc/testsuite/gcc.dg/tls/opt-2.c 2002-08-08 18:34:44.000000000 +0200
@@ -0,0 +1,53 @@
+/* This testcase generated invalid assembly on IA-32,
+ since %gs:0 memory load was not exposed to the compiler
+ as memory load and mem to mem moves are not possible
+ on IA-32. */
+/* { dg-do link } */
+/* { dg-options "-O2 -ftls-model=initial-exec" } */
+/* { dg-options "-O2 -ftls-model=initial-exec -march=i686" { target i?86-*-* } } */
+
+__thread int thr;
+
+struct A
+{
+ unsigned int a, b, c, d, e;
+};
+
+int bar (int x, unsigned long y, void *z)
+{
+ return 0;
+}
+
+int
+foo (int x, int y, const struct A *z)
+{
+ struct A b;
+ int d;
+
+ b = *z;
+ d = bar (x, y, &b);
+ if (d == 0 && y == 0x5402)
+ {
+ int e = thr;
+ d = bar (x, 0x5401, &b);
+ if (d)
+ {
+ thr = e;
+ d = 0;
+ }
+ else if ((z->c & 0600) != (b.c & 0600)
+ || ((z->c & 060) && ((z->c & 060) != (b.c & 060))))
+ {
+ thr = 22;
+ d = -1;
+ }
+ }
+
+ return d;
+}
+
+int main (void)
+{
+ foo (1, 2, 0);
+ return 0;
+}
Jakub