According to the TLS spec, linker can optimize the TLS access by
overriding the TLS access model.  Do the same in compiler by using
the default TLS mode if it is more optimized than the TLS model
attribute.

gcc/

        PR c/121318
        * doc/extend.texi: Update the tls_model attribute.

gcc/c-family/

        PR c/121318
        * c-attribs.cc (handle_tls_model_attribute): Use the default TLS
        mode if it is more optimized.

gcc/testsuite/

        PR c/121318
        * gcc.dg/tls/pr121318.c: New test.

Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
---
 gcc/c-family/c-attribs.cc           |  4 ++++
 gcc/doc/extend.texi                 |  8 +++++++-
 gcc/testsuite/gcc.dg/tls/pr121318.c | 16 ++++++++++++++++
 3 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tls/pr121318.c

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 1f4a0df1205..d49d00c7471 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -3664,6 +3664,10 @@ handle_tls_model_attribute (tree *node, tree name, tree 
args,
           name,
           "local-exec", "initial-exec", "local-dynamic", "global-dynamic");
 
+  /* Use the default TLS mode if it is more optimized.  */
+  tls_model default_kind = decl_default_tls_model (decl);
+  if (default_kind > kind)
+    kind = default_kind;
   set_decl_tls_model (decl, kind);
   return NULL_TREE;
 }
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 224d6197d63..b204d1ce02c 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7528,7 +7528,13 @@ The @code{tls_model} attribute sets thread-local storage 
model
 overriding @option{-ftls-model=} command-line switch on a per-variable
 basis.
 The @var{tls_model} argument should be one of @code{global-dynamic},
-@code{local-dynamic}, @code{initial-exec} or @code{local-exec}.
+@code{local-dynamic}, @code{initial-exec} or @code{local-exec}.  The
+@code{tls_model} attribute specifies the least optimized @acronym{TLS}
+access model.  GCC may choose a more optimized @acronym{TLS} access
+model, according to
+@uref{https://www.akkadia.org/drepper/tls.pdf,
+ELF Handling For Thread-Local Storage}, ignoring the @code{tls_model}
+attribute.
 
 Not all targets support this attribute.
 
diff --git a/gcc/testsuite/gcc.dg/tls/pr121318.c 
b/gcc/testsuite/gcc.dg/tls/pr121318.c
new file mode 100644
index 00000000000..68378635f1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/pr121318.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { tls && pie } } } */
+/* { dg-options "-O2 -fPIE" } */
+
+extern const int afoo[3];
+
+__thread const int *pfoo __attribute__ ((tls_model ("initial-exec"))) = afoo;
+
+const int **
+ppfoo (void)
+{
+  return &pfoo;
+}
+
+/* { dg-final { scan-assembler "addq\[ \t\]\\\$pfoo@tpoff, %rax" { target { { 
i?86-*-linux* x86_64-*-linux* } && { lp64 } } } } } */
+/* { dg-final { scan-assembler "leal\[ \t\]pfoo@tpoff(%rax), %eax" { target { 
{ i?86-*-linux* x86_64-*-linux* } && { x32 } } } } } */
+/* { dg-final { scan-assembler "leal\[ \t\]pfoo@ntpoff, %eax" { target { { 
i?86-*-linux* x86_64-*-linux* } && { ia32 } } } } } */
-- 
2.50.1

Reply via email to