aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-05-07 09:46:08 -0700
committerRichard Henderson <rth@gcc.gnu.org>2005-05-07 09:46:08 -0700
commit84f52ebdf1ec00e55337e5e6de1ae72b7bbace8b (patch)
treea13164878b7b9ea9eb296d63f68e8fb6a4fa4e9e
parentf2f84cbaeb8e41ca297bd0087affc3f2f6befc7d (diff)
downloadgcc-84f52ebdf1ec00e55337e5e6de1ae72b7bbace8b.zip
gcc-84f52ebdf1ec00e55337e5e6de1ae72b7bbace8b.tar.gz
gcc-84f52ebdf1ec00e55337e5e6de1ae72b7bbace8b.tar.bz2
re PR target/21412 (ICE loading TLS address)
PR target/21412 * config/rs6000/rs6000.c (rs6000_emit_move): Look for tls addresses with constant offsets. From-SVN: r99352
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/rs6000.c26
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-9.c7
3 files changed, 35 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cea5099..2062ee4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-05-07 Richard Henderson <rth@redhat.com>
+
+ PR target/21412
+ * config/rs6000/rs6000.c (rs6000_emit_move): Look for tls addresses
+ with constant offsets.
+
2005-05-07 Nathan Sidwell <nathan@codesourcery.com>
* config/v850/v850.c (print_operand): Use gcc_assert and
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 5ed32b7..7223ffa 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3575,11 +3575,29 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
/* Recognize the case where operand[1] is a reference to thread-local
data and load its address to a register. */
- if (GET_CODE (operands[1]) == SYMBOL_REF)
+ if (rs6000_tls_referenced_p (operands[1]))
{
- enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
- if (model != 0)
- operands[1] = rs6000_legitimize_tls_address (operands[1], model);
+ enum tls_model model;
+ rtx tmp = operands[1];
+ rtx addend = NULL;
+
+ if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
+ {
+ addend = XEXP (XEXP (tmp, 0), 1);
+ tmp = XEXP (XEXP (tmp, 0), 0);
+ }
+
+ gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
+ model = SYMBOL_REF_TLS_MODEL (tmp);
+ gcc_assert (model != 0);
+
+ tmp = rs6000_legitimize_tls_address (tmp, model);
+ if (addend)
+ {
+ tmp = gen_rtx_PLUS (mode, tmp, addend);
+ tmp = force_operand (tmp, operands[0]);
+ }
+ operands[1] = tmp;
}
/* Handle the case where reload calls us with an invalid address. */
diff --git a/gcc/testsuite/gcc.dg/tls/opt-9.c b/gcc/testsuite/gcc.dg/tls/opt-9.c
new file mode 100644
index 0000000..3829c66
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-9.c
@@ -0,0 +1,7 @@
+/* PR 21412 */
+/* { dg-do compile */
+/* { dg-options "-O2 -fPIC" } */
+
+struct S { int x[10]; };
+extern __thread struct S s;
+int *foo() { return &s.x[2]; }