This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix ia64 local-exec TLS with addends
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 29 Nov 2005 13:08:07 -0500
- Subject: [PATCH] Fix ia64 local-exec TLS with addends
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
As shown on the attached testcase (or on
libgomp.fortran/threadprivate{2,3}.f90), IA-64 completely ignores the addend
passed to ia64_expand_tls_address in TLS_MODEL_LOCAL_EXEC model.
Fixed thusly; the addend_{hi,lo} setting movement is just an optimization,
the fix is just passing the original OP1 from ia64_expand_move as ORIG_OP1
to ia64_expand_tls_address (well, we could recreate it from OP1 and ADDEND
as well, but when the rtl is already created, I think it is better to add
an argument).
Ok to commit for trunk/4.1/4.0?
2005-11-29 Jakub Jelinek <jakub@redhat.com>
* config/ia64/ia64.c (ia64_expand_tls_address): Add ORIG_OP1 argument.
Move ADDEND_{HI,LO} computation into TLS_MODEL_INITIAL_EXEC case.
(ia64_expand_move): Adjust caller.
* gcc.dg/tls/opt-11.c: New test.
--- gcc/config/ia64/ia64.c.jj 2005-11-28 20:38:19.000000000 +0100
+++ gcc/config/ia64/ia64.c 2005-11-29 18:36:17.000000000 +0100
@@ -891,15 +891,12 @@ gen_thread_pointer (void)
static rtx
ia64_expand_tls_address (enum tls_model tls_kind, rtx op0, rtx op1,
- HOST_WIDE_INT addend)
+ rtx orig_op1, HOST_WIDE_INT addend)
{
rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp, insns;
- rtx orig_op0 = op0, orig_op1 = op1;
+ rtx orig_op0 = op0;
HOST_WIDE_INT addend_lo, addend_hi;
- addend_lo = ((addend & 0x3fff) ^ 0x2000) - 0x2000;
- addend_hi = addend - addend_lo;
-
switch (tls_kind)
{
case TLS_MODEL_GLOBAL_DYNAMIC:
@@ -959,6 +956,9 @@ ia64_expand_tls_address (enum tls_model
break;
case TLS_MODEL_INITIAL_EXEC:
+ addend_lo = ((addend & 0x3fff) ^ 0x2000) - 0x2000;
+ addend_hi = addend - addend_lo;
+
op1 = plus_constant (op1, addend_hi);
addend = addend_lo;
@@ -1023,7 +1023,7 @@ ia64_expand_move (rtx op0, rtx op1)
tls_kind = tls_symbolic_operand_type (sym);
if (tls_kind)
- return ia64_expand_tls_address (tls_kind, op0, sym, addend);
+ return ia64_expand_tls_address (tls_kind, op0, sym, op1, addend);
if (any_offset_symbol_operand (sym, mode))
addend = 0;
--- gcc/testsuite/gcc.dg/tls/opt-11.c.jj 2005-11-14 08:50:14.286436224 +0100
+++ gcc/testsuite/gcc.dg/tls/opt-11.c 2005-11-29 16:35:21.000000000 +0100
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+
+extern void abort (void);
+extern void *memset (void *, int, __SIZE_TYPE__);
+
+struct A
+{
+ char pad[48];
+ int i;
+ int pad2;
+ int j;
+};
+__thread struct A a;
+
+int *
+__attribute__((noinline))
+foo (void)
+{
+ return &a.i;
+}
+
+int
+main (void)
+{
+ int *p = foo ();
+ memset (&a, 0, sizeof (a));
+ a.i = 6;
+ a.j = 8;
+ if (p[0] != 6 || p[1] != 0 || p[2] != 8)
+ abort ();
+ return 0;
+}
Jakub