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