summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/tls
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/gcc.dg/tls
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/gcc.dg/tls')
-rw-r--r--gcc/testsuite/gcc.dg/tls/alias-1.c24
-rw-r--r--gcc/testsuite/gcc.dg/tls/alpha-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/tls/asm-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/tls/debug-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/tls/diag-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/tls/diag-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/tls/diag-3.c11
-rw-r--r--gcc/testsuite/gcc.dg/tls/diag-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/tls/diag-5.c4
-rw-r--r--gcc/testsuite/gcc.dg/tls/diag-6.c8
-rw-r--r--gcc/testsuite/gcc.dg/tls/emutls-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/tls/emutls-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/tls/init-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/tls/nonpic-1.c72
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-1.c30
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-10.c18
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-11.c34
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-12.c51
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-13.c16
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-14.c28
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-15.c24
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-2.c55
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-3.c12
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-4.c54
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-5.c110
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-6.c71
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-7.c15
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-8.c14
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-9.c9
-rw-r--r--gcc/testsuite/gcc.dg/tls/pic-1.c73
-rw-r--r--gcc/testsuite/gcc.dg/tls/pie-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/tls/pr24428-2.c14
-rw-r--r--gcc/testsuite/gcc.dg/tls/pr24428.c13
-rw-r--r--gcc/testsuite/gcc.dg/tls/pr42894.c12
-rw-r--r--gcc/testsuite/gcc.dg/tls/pr45870.c21
-rw-r--r--gcc/testsuite/gcc.dg/tls/section-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/tls/section-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/tls/struct-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/tls/thr-cse-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tls/thr-init-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/tls/thr-init-2.c24
-rw-r--r--gcc/testsuite/gcc.dg/tls/tls.exp36
-rw-r--r--gcc/testsuite/gcc.dg/tls/trivial.c3
43 files changed, 1050 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/tls/alias-1.c b/gcc/testsuite/gcc.dg/tls/alias-1.c
new file mode 100644
index 000000000..722ad2154
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/alias-1.c
@@ -0,0 +1,24 @@
+/* { dg-do link } */
+/* { dg-require-alias "" } */
+/* { dg-require-visibility "" } */
+/* { dg-require-effective-target tls_runtime } */
+/* Test that encode_section_info handles the change from externally
+ defined to locally defined (via hidden). Extracted from glibc. */
+
+struct __res_state {
+ char x[123];
+};
+
+extern __thread struct __res_state bar
+ __attribute__ ((tls_model ("initial-exec")));
+
+int main()
+{
+ bar.x[0] = 0;
+ return 0;
+}
+
+__thread struct __res_state foo;
+extern __thread struct __res_state bar
+ __attribute__ ((alias ("foo")))
+ __attribute__ ((visibility ("hidden")));
diff --git a/gcc/testsuite/gcc.dg/tls/alpha-1.c b/gcc/testsuite/gcc.dg/tls/alpha-1.c
new file mode 100644
index 000000000..1f0d6eda1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/alpha-1.c
@@ -0,0 +1,10 @@
+/* Make sure that we honor initial-exec. */
+/* { dg-do compile { target alpha*-*-* } } */
+/* { dg-options "" } */
+/* { dg-require-effective-target tls_native } */
+
+static __thread int xyzzy __attribute__ ((tls_model ("initial-exec")));
+int foo(void) { return xyzzy; }
+
+/* { dg-final { scan-assembler "gottprel" } } */
+/* { dg-final { scan-assembler-not "tprel(lo|hi|16)" } } */
diff --git a/gcc/testsuite/gcc.dg/tls/asm-1.c b/gcc/testsuite/gcc.dg/tls/asm-1.c
new file mode 100644
index 000000000..b77e550d7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/asm-1.c
@@ -0,0 +1,8 @@
+/* { dg-options "-Werror" } */
+/* { dg-require-effective-target tls } */
+__thread int i;
+
+int foo ()
+{
+ asm volatile ("" :: "m" (&i)); /* { dg-error "directly addressable" } */
+}
diff --git a/gcc/testsuite/gcc.dg/tls/debug-1.c b/gcc/testsuite/gcc.dg/tls/debug-1.c
new file mode 100644
index 000000000..67d7be69c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/debug-1.c
@@ -0,0 +1,5 @@
+/* { dg-do assemble } */
+/* { dg-options "-g" } */
+/* { dg-require-effective-target tls } */
+
+__thread int i;
diff --git a/gcc/testsuite/gcc.dg/tls/diag-1.c b/gcc/testsuite/gcc.dg/tls/diag-1.c
new file mode 100644
index 000000000..56b570c94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/diag-1.c
@@ -0,0 +1,12 @@
+/* Valid __thread specifiers. */
+/* { dg-require-effective-target tls } */
+
+__thread int g1;
+extern __thread int g2;
+static __thread int g3;
+
+void foo()
+{
+ extern __thread int l1;
+ static __thread int l2;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/diag-2.c b/gcc/testsuite/gcc.dg/tls/diag-2.c
new file mode 100644
index 000000000..8276cb3be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/diag-2.c
@@ -0,0 +1,22 @@
+/* Invalid __thread specifiers. */
+/* { dg-require-effective-target tls } */
+
+__thread extern int g1; /* { dg-error "'__thread' before 'extern'" } */
+__thread static int g2; /* { dg-error "'__thread' before 'static'" } */
+__thread __thread int g3; /* { dg-error "duplicate '__thread'" } */
+typedef __thread int g4; /* { dg-error "'__thread' used with 'typedef'" } */
+
+void foo()
+{
+ __thread int l1; /* { dg-error "implicitly auto and declared '__thread'" } */
+ auto __thread int l2; /* { dg-error "'__thread' used with 'auto'" } */
+ __thread extern int l3; /* { dg-error "'__thread' before 'extern'" } */
+ register __thread int l4; /* { dg-error "'__thread' used with 'register'" } */
+}
+
+__thread void f1 (); /* { dg-error "invalid storage class for function" } */
+extern __thread void f2 (); /* { dg-error "invalid storage class for function" } */
+static __thread void f3 (); /* { dg-error "invalid storage class for function" } */
+__thread void f4 () { } /* { dg-error "function definition declared '__thread'" } */
+
+void bar(__thread int p1); /* { dg-error "storage class specified for parameter" } */
diff --git a/gcc/testsuite/gcc.dg/tls/diag-3.c b/gcc/testsuite/gcc.dg/tls/diag-3.c
new file mode 100644
index 000000000..1a7994c69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/diag-3.c
@@ -0,0 +1,11 @@
+/* Report invalid extern and __thread combinations. */
+/* { dg-require-effective-target tls } */
+
+extern int j; /* { dg-message "note: previous declaration" } */
+__thread int j; /* { dg-error "follows non-thread-local" } */
+
+extern __thread int i; /* { dg-message "note: previous declaration" } */
+int i; /* { dg-error "follows thread-local" } */
+
+extern __thread int k; /* This is fine. */
+__thread int k;
diff --git a/gcc/testsuite/gcc.dg/tls/diag-4.c b/gcc/testsuite/gcc.dg/tls/diag-4.c
new file mode 100644
index 000000000..fed2f3acc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/diag-4.c
@@ -0,0 +1,11 @@
+/* Invalid __thread specifiers. As diag-4.c but some cases in
+ different orders. */
+/* { dg-require-effective-target tls } */
+
+__thread typedef int g4; /* { dg-error "'__thread' used with 'typedef'" } */
+
+void foo()
+{
+ __thread auto int l2; /* { dg-error "'__thread' used with 'auto'" } */
+ __thread register int l4; /* { dg-error "'__thread' used with 'register'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/tls/diag-5.c b/gcc/testsuite/gcc.dg/tls/diag-5.c
new file mode 100644
index 000000000..ac78cb295
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/diag-5.c
@@ -0,0 +1,4 @@
+/* __thread specifiers on empty declarations. */
+/* { dg-require-effective-target tls } */
+
+__thread struct foo; /* { dg-warning "useless '__thread' in empty declaration" } */
diff --git a/gcc/testsuite/gcc.dg/tls/diag-6.c b/gcc/testsuite/gcc.dg/tls/diag-6.c
new file mode 100644
index 000000000..71b0b9524
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/diag-6.c
@@ -0,0 +1,8 @@
+/* Invalid tls_model attributes. PR 35435. */
+/* { dg-require-effective-target tls } */
+
+int v __attribute__((tls_model("initial-exec"))); /* { dg-warning "attribute ignored" } */
+typedef int X __attribute__((tls_model("initial-exec"))); /* { dg-warning "attribute ignored" } */
+void f(int x __attribute__((tls_model("initial-exec")))); /* { dg-warning "attribute ignored" } */
+__thread int a __attribute__((tls_model(1))); /* { dg-error "tls_model argument not a string" } */
+__thread int b __attribute__((tls_model("unknown"))); /* { dg-error "tls_model argument must be one of" } */
diff --git a/gcc/testsuite/gcc.dg/tls/emutls-1.c b/gcc/testsuite/gcc.dg/tls/emutls-1.c
new file mode 100644
index 000000000..3b3577c89
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/emutls-1.c
@@ -0,0 +1,22 @@
+/* { dg-do run { target *-wrs-vxworks } } */
+/* { dg-require-effective-target tls } */
+/* { dg-add-options tls } */
+
+/* vxworks' TLS model requires no extra padding on the tls proxy
+ objects. */
+
+__thread int i;
+__thread int j;
+
+extern int __tls__i;
+extern int __tls__j;
+
+int main ()
+{
+ int delta = ((char *)&__tls__j - (char *)&__tls__i);
+
+ if (delta < 0)
+ delta = -delta;
+
+ return delta != 12;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/emutls-2.c b/gcc/testsuite/gcc.dg/tls/emutls-2.c
new file mode 100644
index 000000000..1e26d5fe1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/emutls-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls } */
+/* { dg-options "-O2" } */
+
+/* With emulated TLS, the constructor generated during IPA
+ was not properly lowered to SSA form. */
+
+__thread int i __attribute__((common));
diff --git a/gcc/testsuite/gcc.dg/tls/init-1.c b/gcc/testsuite/gcc.dg/tls/init-1.c
new file mode 100644
index 000000000..fa4208dce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/init-1.c
@@ -0,0 +1,5 @@
+/* Invalid initializations. */
+/* { dg-require-effective-target tls } */
+
+extern __thread int i;
+int *p = &i; /* { dg-error "initializer element is not constant" } */
diff --git a/gcc/testsuite/gcc.dg/tls/nonpic-1.c b/gcc/testsuite/gcc.dg/tls/nonpic-1.c
new file mode 100644
index 000000000..9c592a985
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/nonpic-1.c
@@ -0,0 +1,72 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftls-model=initial-exec" } */
+/* { dg-require-effective-target tls } */
+
+extern __thread long e1;
+extern __thread int e2;
+static __thread long s1;
+static __thread int s2;
+
+long *ae1 (void)
+{
+ return &e1;
+}
+
+int *ae2 (void)
+{
+ return &e2;
+}
+
+long *as1 (void)
+{
+ return &s1;
+}
+
+int *as2 (void)
+{
+ return &s2;
+}
+
+long ge1 (void)
+{
+ return e1;
+}
+
+int ge2 (void)
+{
+ return e2;
+}
+
+long gs1 (void)
+{
+ return s1;
+}
+
+int gs2 (void)
+{
+ return s2;
+}
+
+long ge3 (void)
+{
+ return e1 + e2;
+}
+
+long gs3 (void)
+{
+ return s1 + s2;
+}
+
+long ge4 (void)
+{
+ if (0)
+ return e1;
+ return e2;
+}
+
+long gs4 (void)
+{
+ if (0)
+ return s1;
+ return s2;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-1.c b/gcc/testsuite/gcc.dg/tls/opt-1.c
new file mode 100644
index 000000000..f9399e04a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC" } */
+/* { dg-options "-O2 -fPIC -mtune=i686" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target tls } */
+/* { dg-require-effective-target fpic } */
+
+extern __thread int thr;
+
+static int x;
+
+static void
+bar (void)
+{
+ x = 1;
+}
+
+static void
+#ifdef __i386__
+__attribute__ ((regparm (3)))
+#endif
+foo (const char *x, void *y, int *z)
+{
+ bar ();
+}
+
+void
+test (const char *x, void *y)
+{
+ foo (x, y, &thr);
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-10.c b/gcc/testsuite/gcc.dg/tls/opt-10.c
new file mode 100644
index 000000000..15dc68610
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-10.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O3 -fpic" } */
+/* { dg-require-effective-target tls } */
+
+/* The web pass was creating unrecognisable pic_load_dot_plus_four insns
+ on ARM. */
+
+__thread int a_thread_local;
+void *
+spin (int n)
+{
+ int i;
+ for (i = 0; i <= n; i++)
+ {
+ a_thread_local += i;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-11.c b/gcc/testsuite/gcc.dg/tls/opt-11.c
new file mode 100644
index 000000000..0069c484a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-11.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-add-options tls } */
+
+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;
+}
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 000000000..7b9e498a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-12.c
@@ -0,0 +1,51 @@
+/* PR target/29198 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fpic" } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-add-options tls } */
+/* { 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;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-13.c b/gcc/testsuite/gcc.dg/tls/opt-13.c
new file mode 100644
index 000000000..8eea76b68
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-13.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target tls } */
+
+__thread struct
+{
+ int a;
+ char b[32];
+} thr;
+
+int
+main ()
+{
+ __builtin_strcpy (thr.b, "abcd");
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-14.c b/gcc/testsuite/gcc.dg/tls/opt-14.c
new file mode 100644
index 000000000..5abeacea7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-14.c
@@ -0,0 +1,28 @@
+/* This testcase generated invalid assembly on ARM Thumb-2. Two
+ PIC additions of pc were combined, but the deleted label was still
+ used. */
+/* { dg-do assemble } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target tls } */
+
+struct __res_state
+{
+ int options;
+};
+extern __thread struct __res_state *__resp
+ __attribute__ ((tls_model ("initial-exec")));
+
+void foo (void);
+
+int main(void)
+{
+ int count, total = 0;
+
+ for (count = 0; count < 10; count++)
+ {
+ if (((*__resp).options & 0x00000001) == 0)
+ foo ();
+ (*__resp).options &= ~((0x00000002 | 0x00000200 | 0x00000080));
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-15.c b/gcc/testsuite/gcc.dg/tls/opt-15.c
new file mode 100644
index 000000000..a6cc7214a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-15.c
@@ -0,0 +1,24 @@
+/* PR target/42564 */
+/* This used to ICE on the SPARC because of an unrecognized TLS pattern. */
+
+/* { dg-do compile } */
+/* { dg-options "-O -fPIC" } */
+/* { dg-require-effective-target tls } */
+/* { dg-require-effective-target fpic } */
+
+extern void *memset(void *s, int c, __SIZE_TYPE__ n);
+
+struct S1 { int i; };
+
+struct S2
+{
+ int ver;
+ struct S1 s;
+};
+
+static __thread struct S2 m;
+
+void init(void)
+{
+ memset(&m.s, 0, sizeof(m.s));
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-2.c b/gcc/testsuite/gcc.dg/tls/opt-2.c
new file mode 100644
index 000000000..3ede35290
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-2.c
@@ -0,0 +1,55 @@
+/* This testcase generated invalid assembly on IA-32,
+ since %gs:0 memory load was not exposed to the compiler
+ as memory load and mem to mem moves are not possible
+ on IA-32. */
+/* { dg-do link } */
+/* { dg-options "-O2 -ftls-model=initial-exec" } */
+/* { dg-options "-O2 -ftls-model=initial-exec -march=i686" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target tls } */
+/* { dg-require-effective-target tls_runtime } */
+
+__thread int thr;
+
+struct A
+{
+ unsigned int a, b, c, d, e;
+};
+
+int bar (int x, unsigned long y, void *z)
+{
+ return 0;
+}
+
+int
+foo (int x, int y, const struct A *z)
+{
+ struct A b;
+ int d;
+
+ b = *z;
+ d = bar (x, y, &b);
+ if (d == 0 && y == 0x5402)
+ {
+ int e = thr;
+ d = bar (x, 0x5401, &b);
+ if (d)
+ {
+ thr = e;
+ d = 0;
+ }
+ else if ((z->c & 0600) != (b.c & 0600)
+ || ((z->c & 060) && ((z->c & 060) != (b.c & 060))))
+ {
+ thr = 22;
+ d = -1;
+ }
+ }
+
+ return d;
+}
+
+int main (void)
+{
+ foo (1, 2, 0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-3.c b/gcc/testsuite/gcc.dg/tls/opt-3.c
new file mode 100644
index 000000000..dd37dbc82
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fpic" } */
+/* { dg-options "-O2 -fpic -mregparm=3" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target tls } */
+/* { dg-require-effective-target fpic } */
+
+extern __thread int i, j, k;
+extern void bar(int *, int *, int *);
+void foo(void)
+{
+ bar(&i, &j, &k);
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-4.c b/gcc/testsuite/gcc.dg/tls/opt-4.c
new file mode 100644
index 000000000..3d7953b47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-4.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target tls_native } */
+
+struct A
+{
+ int a1;
+ int a2;
+};
+
+extern __thread const unsigned char *tcc1, **tcc2;
+
+extern inline const unsigned char ** __attribute__ ((const))
+foo (void)
+{
+ const unsigned char **a = &tcc1;
+ if (*a == 0)
+ *a = *tcc2 + 128;
+ return a;
+}
+
+extern inline int
+bar (const struct A *x)
+{
+ int a;
+
+ if (x->a2 & 8)
+ return 0;
+ a = x->a1;
+ return a > 0 && ((*foo ())[a] & 64);
+}
+
+int
+baz (const struct A *x, char *y)
+{
+ const struct A *a;
+
+ for (a = x; !!a->a1; a++)
+ if (! (x->a2 & 8))
+ if (bar (a))
+ {
+ *y++ = a->a1;
+ if (x->a1)
+ *y++ = ':';
+ *y = '\0';
+ }
+ return 0;
+}
+
+/* Verify tcc1 and tcc2 variables show up only in the TLS access sequences. */
+/* { dg-final { scan-assembler "tcc1@" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-assembler "tcc2@" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-assembler-not "tcc1\[^@\]" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-assembler-not "tcc2\[^@\]" { target i?86-*-* x86_64-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tls/opt-5.c b/gcc/testsuite/gcc.dg/tls/opt-5.c
new file mode 100644
index 000000000..0ae9f075d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-5.c
@@ -0,0 +1,110 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target tls } */
+/* Sched1 moved {load_tp} pattern between strlen call and the copy
+ of the hard return value to its pseudo. This resulted in a
+ reload abort, since the hard register was not spillable. */
+
+extern __thread int __libc_errno __attribute__ ((tls_model ("initial-exec")));
+
+struct stat64
+ {
+ long dummy[4];
+ };
+typedef __SIZE_TYPE__ size_t;
+typedef unsigned long long uint64_t;
+typedef int __mode_t;
+
+extern size_t strlen (__const char *__s) __attribute__ ((__pure__));
+extern int strcmp (__const char *__s1, __const char *__s2)
+ __attribute__ ((__pure__));
+
+extern int __open64 (__const char *__file, int __oflag, ...);
+extern int __open (__const char *__file, int __oflag, ...);
+extern int __mkdir (__const char *__path, __mode_t __mode);
+extern int __lxstat64 (int __ver, __const char *__filename,
+ struct stat64 *__stat_buf) ;
+
+static const char letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+int
+__gen_tempname (char *tmpl, int kind)
+{
+ int len;
+ char *XXXXXX;
+ static uint64_t value;
+ uint64_t random_time_bits;
+ unsigned long count;
+ int fd = -1;
+ int save_errno = __libc_errno;
+ struct stat64 st;
+ unsigned long attempts_min = 62L * 62L * 62L;
+ unsigned long attempts = attempts_min < 238328 ? 238328 : attempts_min;
+
+ len = strlen (tmpl);
+ if (len < 6 || strcmp(&tmpl[len - 6], "XXXXXX"))
+ {
+ (__libc_errno = (22));
+ return -1;
+ }
+
+ XXXXXX = &tmpl[len - 6];
+
+ for (count = 0; count < attempts; value += 7777, ++count)
+ {
+ uint64_t v = value;
+
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ switch (kind)
+ {
+ case 0:
+ fd = __open (tmpl, 02 | 01000 | 04000, 0400 | 0200);
+ break;
+
+ case 1:
+ fd = __open64 (tmpl, 02 | 01000 | 04000, 0400 | 0200);
+ break;
+
+ case 2:
+ fd = __mkdir (tmpl, 0400 | 0200 | 0100);
+ break;
+
+ case 3:
+ if (__lxstat64 (2, tmpl, &st) < 0)
+ {
+ if (__libc_errno == 2)
+ {
+ (__libc_errno = (save_errno));
+ return 0;
+ }
+ else
+
+ return -1;
+ }
+ continue;
+ }
+
+ if (fd >= 0)
+ {
+ (__libc_errno = (save_errno));
+ return fd;
+ }
+ else if (__libc_errno != 17)
+ return -1;
+ }
+
+ (__libc_errno = (17));
+ return -1;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-6.c b/gcc/testsuite/gcc.dg/tls/opt-6.c
new file mode 100644
index 000000000..8a01c019c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-6.c
@@ -0,0 +1,71 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target tls } */
+
+extern void abort (void);
+extern void exit (int);
+
+struct A
+{
+ char a;
+ int b;
+ long long c;
+};
+extern __thread struct A a1, a2, a3, a4;
+extern struct A *f1a (void);
+extern struct A *f2a (void);
+extern struct A *f3a (void);
+extern struct A *f4a (void);
+extern struct A *f5a (void);
+extern struct A *f6a (void);
+extern struct A *f7a (void);
+extern struct A *f8a (void);
+extern struct A *f9a (void);
+extern struct A *f10a (void);
+extern int f1b (void);
+extern int f2b (void);
+extern int f3b (void);
+extern int f4b (void);
+extern int f5b (void);
+extern int f6b (void);
+extern int f7b (void);
+extern int f8b (void);
+extern int f9b (void);
+extern int f10b (void);
+extern void check1 (void);
+extern void check2 (void);
+__thread int dummy = 12;
+__thread struct A local = { 1, 2, 3 };
+
+int
+main (void)
+{
+ struct A *p;
+
+ if (local.a != 1 || local.b != 2 || local.c != 3)
+ abort ();
+ if (a1.a != 4 || a1.b != 5 || a1.c != 6)
+ abort ();
+ if (a2.a != 22 || a2.b != 23 || a2.c != 24)
+ abort ();
+ if (a3.a != 10 || a3.b != 11 || a3.c != 12)
+ abort ();
+ if (a4.a != 25 || a4.b != 26 || a4.c != 27)
+ abort ();
+ check1 ();
+ check2 ();
+ if (f1a () != &a1 || f2a () != &a2 || f3a () != &a3 || f4a () != &a4)
+ abort ();
+ p = f5a (); if (p->a != 16 || p->b != 16 + 1 || p->c != 16 + 2)
+ abort ();
+ p = f6a (); if (p->a != 19 || p->b != 19 + 1 || p->c != 19 + 2)
+ abort ();
+ if (f7a () != &a2 || f8a () != &a4)
+ abort ();
+ p = f9a (); if (p->a != 28 || p->b != 28 + 1 || p->c != 28 + 2)
+ abort ();
+ p = f10a (); if (p->a != 31 || p->b != 31 + 1 || p->c != 31 + 2)
+ abort ();
+
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/tls/opt-7.c b/gcc/testsuite/gcc.dg/tls/opt-7.c
new file mode 100644
index 000000000..44b900f54
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-7.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC" } */
+/* { dg-require-effective-target tls } */
+/* { dg-require-effective-target fpic } */
+
+static __thread void *baz [4] __attribute__((tls_model ("initial-exec")));
+void foo (void)
+{
+ void **u = (void **) baz;
+
+ u[0] = 0;
+ u[1] = 0;
+}
+
+/* { dg-final { scan-assembler-not "\[48\]\\+baz" { target i?86-*-* x86_64-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tls/opt-8.c b/gcc/testsuite/gcc.dg/tls/opt-8.c
new file mode 100644
index 000000000..a73311153
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-8.c
@@ -0,0 +1,14 @@
+/* PR 18910 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target tls } */
+
+static __thread void *foo [2];
+void
+test1 (void)
+{
+ unsigned int s;
+
+ for (s = 0; s < 2; ++s)
+ foo [s] = &foo[s];
+}
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 000000000..49aa9085f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-9.c
@@ -0,0 +1,9 @@
+/* PR 21412 */
+/* { dg-do compile */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -fPIC" } */
+/* { dg-require-effective-target tls } */
+
+struct S { int x[10]; };
+extern __thread struct S s;
+int *foo() { return &s.x[2]; }
diff --git a/gcc/testsuite/gcc.dg/tls/pic-1.c b/gcc/testsuite/gcc.dg/tls/pic-1.c
new file mode 100644
index 000000000..9108b58aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/pic-1.c
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -fpic -ftls-model=global-dynamic" } */
+/* { dg-require-effective-target tls } */
+
+extern __thread long e1;
+extern __thread int e2;
+static __thread long s1;
+static __thread int s2;
+
+long *ae1 (void)
+{
+ return &e1;
+}
+
+int *ae2 (void)
+{
+ return &e2;
+}
+
+long *as1 (void)
+{
+ return &s1;
+}
+
+int *as2 (void)
+{
+ return &s2;
+}
+
+long ge1 (void)
+{
+ return e1;
+}
+
+int ge2 (void)
+{
+ return e2;
+}
+
+long gs1 (void)
+{
+ return s1;
+}
+
+int gs2 (void)
+{
+ return s2;
+}
+
+long ge3 (void)
+{
+ return e1 + e2;
+}
+
+long gs3 (void)
+{
+ return s1 + s2;
+}
+
+long ge4 (void)
+{
+ if (0)
+ return e1;
+ return e2;
+}
+
+long gs4 (void)
+{
+ if (0)
+ return s1;
+ return s2;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/pie-1.c b/gcc/testsuite/gcc.dg/tls/pie-1.c
new file mode 100644
index 000000000..07eb5f1ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/pie-1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-fpie" } */
+/* { dg-require-effective-target tls } */
+
+__thread int a; int b; int main() { return a = b; }
diff --git a/gcc/testsuite/gcc.dg/tls/pr24428-2.c b/gcc/testsuite/gcc.dg/tls/pr24428-2.c
new file mode 100644
index 000000000..b147f60d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/pr24428-2.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-add-options tls } */
+
+__thread double thrtest[81];
+int main ()
+{
+ double *p, *e;
+ e = &thrtest[81];
+ for (p = &thrtest[0]; p < e; ++p)
+ *p = 1.0;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/pr24428.c b/gcc/testsuite/gcc.dg/tls/pr24428.c
new file mode 100644
index 000000000..643969877
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/pr24428.c
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-add-options tls } */
+
+__thread double thrtest[81];
+int main ()
+{
+ int i;
+ for (i = 0; i < 81; i++)
+ thrtest[i] = 1.0;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/pr42894.c b/gcc/testsuite/gcc.dg/tls/pr42894.c
new file mode 100644
index 000000000..c3bd76c91
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/pr42894.c
@@ -0,0 +1,12 @@
+/* PR target/42894 */
+/* { dg-do compile } */
+/* { dg-options "-march=armv5te -mthumb" { target arm*-*-* } } */
+/* { dg-require-effective-target tls } */
+
+extern __thread int t;
+
+void
+foo (int a)
+{
+ t = a;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/pr45870.c b/gcc/testsuite/gcc.dg/tls/pr45870.c
new file mode 100644
index 000000000..8a5d3c74a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/pr45870.c
@@ -0,0 +1,21 @@
+/* PR target/45870 */
+/* { dg-do compile } */
+/* { dg-options "-g -O" } */
+/* { dg-require-effective-target tls } */
+
+__thread int v[30];
+int bar (void);
+
+int
+foo (int x, int y, int z)
+{
+ int a, b = z, c;
+ while (b > 0)
+ {
+ c = (bar () % 3);
+ a = v[x];
+ if (x < y)
+ for (;;);
+ b += a;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tls/section-1.c b/gcc/testsuite/gcc.dg/tls/section-1.c
new file mode 100644
index 000000000..1ca2ffb90
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/section-1.c
@@ -0,0 +1,12 @@
+/* Verify that we get errors for trying to put TLS data in
+ sections which can't work. */
+/* { dg-require-effective-target tls_native } */
+
+#define A(X) __attribute__((section(X)))
+
+__thread int i A("foo"); /* Ok */
+
+__thread int j A(".data"); /* { dg-error "causes a section type conflict" "conflict with .data section" { xfail *-*-* } } */
+
+int k A("bar");
+__thread int l A("bar"); /* { dg-error "causes a section type conflict" "conflict with user-defined section" } */
diff --git a/gcc/testsuite/gcc.dg/tls/section-2.c b/gcc/testsuite/gcc.dg/tls/section-2.c
new file mode 100644
index 000000000..8f11def96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/section-2.c
@@ -0,0 +1,8 @@
+/* Verify that we get errors for trying to put TLS data in
+ sections which can't work. */
+/* { dg-require-effective-target tls } */
+/* { dg-do compile { target *-*-vxworks } } */
+
+#define A(X) __attribute__((section(X)))
+
+__thread int i A("foo"); /* { dg-error "cannot be overridden" } */
diff --git a/gcc/testsuite/gcc.dg/tls/struct-1.c b/gcc/testsuite/gcc.dg/tls/struct-1.c
new file mode 100644
index 000000000..fbe3e3c10
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/struct-1.c
@@ -0,0 +1,34 @@
+/* This testcase ICEd on IA-32 because the backend was inconsistent whether
+ to allow addends for @dtpoff relocs or not. */
+/* { dg-do compile } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -fpic" } */
+/* { dg-require-effective-target tls } */
+
+struct S {
+ int s0, s1, s2, s3;
+};
+static __thread struct S x;
+extern void abort (void);
+extern void exit (int);
+
+void
+foo (struct S *s)
+{
+ s->s2 = 231;
+}
+
+void
+bar (void)
+{
+ if (x.s0 == 231 || x.s2 != 231)
+ abort ();
+}
+
+int
+main ()
+{
+ foo (&x);
+ bar ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/tls/thr-cse-1.c b/gcc/testsuite/gcc.dg/tls/thr-cse-1.c
new file mode 100644
index 000000000..95d3b4580
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/thr-cse-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* { dg-require-effective-target tls_emulated } */
+
+/* Test that we only get one call to emutls_get_address when CSE is
+ active. Note that the var _must_ be initialized for the scan asm
+ to work, since otherwise there will be an initializer which will,
+ correctly, call emutls_get_address. */
+int foo (int b, int c, int d)
+{
+ static __thread int a=1;
+ a += b;
+ a -= c;
+ a += d;
+ return a;
+}
+
+/* { dg-final { scan-assembler-not "emutls_get_address.*emutls_get_address.*" { target { ! { "*-wrs-vxworks" "*-*-darwin8" "hppa*-*-hpux*" "spu-*-*" } } } } } */
+/* { dg-final { scan-assembler-not "call\tL___emutls_get_address.stub.*call\tL___emutls_get_address.stub.*" { target "*-*-darwin8" } } } */
+/* { dg-final { scan-assembler-not "(b,l|bl) __emutls_get_address.*(b,l|bl) __emutls_get_address.*" { target "hppa*-*-hpux*" } } } */
+/* { dg-final { scan-assembler-not "(brsl|brasl)\t__emutls_get_address.*(brsl|brasl)\t__emutls_get_address.*" { target spu-*-* } } } */
+/* { dg-final { scan-assembler-not "tls_lookup.*tls_lookup.*" { target *-wrs-vxworks } } } */
+
diff --git a/gcc/testsuite/gcc.dg/tls/thr-init-1.c b/gcc/testsuite/gcc.dg/tls/thr-init-1.c
new file mode 100644
index 000000000..eb2f84695
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/thr-init-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls } */
+
+static __thread int fstat ;
+static __thread int fstat = 1 ;
+static __thread int fstat ;
+static __thread int fstat = 2; /* { dg-error "redefinition of 'fstat'" } */
+ /* { dg-message "note: previous definition of 'fstat' was here" "" { target *-*-* } 5 } */
diff --git a/gcc/testsuite/gcc.dg/tls/thr-init-2.c b/gcc/testsuite/gcc.dg/tls/thr-init-2.c
new file mode 100644
index 000000000..22c96ea9f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/thr-init-2.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-add-options tls } */
+
+extern void abort() ;
+
+static __thread int fstat ;
+static __thread int fstat = 1;
+
+int test_code(int b)
+{
+ fstat += b ;
+ return fstat;
+}
+
+int main (int ac, char *av[])
+{
+ int a = test_code(1);
+
+ if ((a != 2) || (fstat != 2))
+ abort () ;
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tls/tls.exp b/gcc/testsuite/gcc.dg/tls/tls.exp
new file mode 100644
index 000000000..890e05e55
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/tls.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+ "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/tls/trivial.c b/gcc/testsuite/gcc.dg/tls/trivial.c
new file mode 100644
index 000000000..96b8e49a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/trivial.c
@@ -0,0 +1,3 @@
+/* { dg-require-effective-target tls } */
+
+__thread int i;