OSDN Git Service

PR target/18910
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Jan 2005 20:29:06 +0000 (20:29 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Jan 2005 20:29:06 +0000 (20:29 +0000)
        * config/i386/i386.c (ix86_expand_move): Handle tls symbols
        with an offset.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@92968 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/gcc.dg/tls/opt-8.c [new file with mode: 0644]

index 08b41f5..7797ffc 100644 (file)
@@ -1,3 +1,10 @@
+2005-01-05  Jan Hubicka  <jh@suse.cz>
+           Richard Henderson  <rth@redhat.com>
+
+       PR target/18910
+       * config/i386/i386.c (ix86_expand_move): Handle tls symbols 
+       with an offset.
+
 2005-01-05  Richard Henderson  <rth@redhat.com>
 
        PR target/12902
index 51d36f1..ca1f1f7 100644 (file)
@@ -7472,13 +7472,32 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
   op0 = operands[0];
   op1 = operands[1];
 
-  model = GET_CODE (op1) == SYMBOL_REF ? SYMBOL_REF_TLS_MODEL (op1) : 0;
-  if (model)
+  if (GET_CODE (op1) == SYMBOL_REF)
     {
-      op1 = legitimize_tls_address (op1, model, true);
-      op1 = force_operand (op1, op0);
-      if (op1 == op0)
-       return;
+      model = SYMBOL_REF_TLS_MODEL (op1);
+      if (model)
+       {
+         op1 = legitimize_tls_address (op1, model, true);
+         op1 = force_operand (op1, op0);
+         if (op1 == op0)
+           return;
+       }
+    }
+  else if (GET_CODE (op1) == CONST
+          && GET_CODE (XEXP (op1, 0)) == PLUS
+          && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SYMBOL_REF)
+    {
+      model = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (op1, 0), 0));
+      if (model)
+       {
+         rtx addend = XEXP (XEXP (op1, 0), 1);
+         op1 = legitimize_tls_address (XEXP (XEXP (op1, 0), 0), model, true);
+         op1 = force_operand (op1, NULL);
+         op1 = expand_simple_binop (Pmode, PLUS, op1, addend,
+                                    op0, 1, OPTAB_DIRECT);
+         if (op1 == op0)
+           return;
+       }
     }
 
   if (flag_pic && mode == Pmode && symbolic_operand (op1, Pmode))
diff --git a/gcc/testsuite/gcc.dg/tls/opt-8.c b/gcc/testsuite/gcc.dg/tls/opt-8.c
new file mode 100644 (file)
index 0000000..dec0eab
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR 18910 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+static __thread void *foo [2];
+void
+test1 (void)
+{
+  unsigned int s;
+
+  for (s = 0; s < 2; ++s)
+    foo [s] = &foo[s];
+}