diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3eaecfedff3..59bafdec7ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2006-10-06 Jakub Jelinek + PR target/29198 + * config/i386/i386.c (legitimize_pic_address): Reject TLS symbols. + * config/i386/predicates.md (local_symbolic_operand): Likewise. + PR c/29091 * varasm.c (output_constant): If TREE_VECTOR_CST_ELTS chain is shorter than the number of vector elements fill the rest with zeros. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cdbd0c658c5..287163e8e0e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -6623,7 +6623,7 @@ legitimize_pic_address (rtx orig, rtx reg) new = reg; } } - else if (GET_CODE (addr) == SYMBOL_REF) + else if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0) { if (TARGET_64BIT) { diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 457f5563a7b..52011918100 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -447,6 +447,9 @@ if (GET_CODE (op) != SYMBOL_REF) return 0; + if (SYMBOL_REF_TLS_MODEL (op) != 0) + return 0; + if (SYMBOL_REF_LOCAL_P (op)) return 1; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ce15a0f56e5..5027cb4f571 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2006-10-06 Jakub Jelinek + PR target/29198 + * gcc.dg/tls/opt-12.c: New test. + PR fortran/28415 * gfortran.dg/save_2.f90: New test. diff --git a/gcc/testsuite/gcc.dg/tls/opt-12.c b/gcc/testsuite/gcc.dg/tls/opt-12.c new file mode 100644 index 00000000000..7c6e73430a1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/opt-12.c @@ -0,0 +1,50 @@ +/* PR target/29198 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fpic" } */ +/* { dg-require-effective-target tls_runtime } */ +/* { dg-require-effective-target fpic } */ + +extern void abort (void); + +int f2 (int, int, int, int); +struct s { char b[4]; }; +__thread struct s thra[2]; + +void +__attribute__((noinline)) +f1 (int a1, int a2) +{ + int i, j; + for (i = 0; i < 4; i++) + { + int tot = 0; + for (j = 0; j < 4; j++) + tot += f2 (a1, a2, i, j); + *(&thra[0].b[0] + i) = tot; + } +} + +int +__attribute__((noinline)) +f2 (int a, int b, int c, int d) +{ + return a + b + c + d; +} + +int +main (void) +{ + f1 (0, 0); + if (thra[0].b[0] != 6 + || thra[0].b[1] != 10 + || thra[0].b[2] != 14 + || thra[0].b[3] != 18) + abort (); + f1 (2, 3); + if (thra[0].b[0] != 26 + || thra[0].b[1] != 30 + || thra[0].b[2] != 34 + || thra[0].b[3] != 38) + abort (); + return 0; +}