This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix ia64 local-exec TLS with addends


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]