On Wed, Oct 22, 2025 at 3:53 PM H.J. Lu <[email protected]> wrote: > > On Thu, Sep 18, 2025 at 8:40 PM H.J. Lu <[email protected]> wrote: > > > > On Wed, Sep 10, 2025 at 11:11 AM H.J. Lu <[email protected]> wrote: > > > > > > Since C, C++, and Fortran front-ends now set the TLS access model after > > > a variable has been fully processed, not in the middle of processing it, > > > add an option, -fipa-tls-access, for TLS access optimization as the part > > > of IPA whole-program visibility optimization. Enabled by default, it > > > doesn't check tls_model attribute when optimizing TLS access since > > > > > > 1. -ftls-model=initial-exec can specify the weakest TLS access model > > > without tls_model attribute. > > > 2. Linker can optimize TLS access at link-time. > > > 3. LTO should perform the similar optimization. > > > > > > The recomputed model of an undefined TLS variable with LOCAL_EXEC > > > attribute is INITIAL_EXEC. Linker will issue an error if the TLS > > > model isn't supported in shared library. But compiler doesn't know > > > where the TLS variable is defined nor if the generated code will be > > > linked into executable or shared library. > > > > > > gcc/ > > > > > > PR middle-end/121352 > > > * common.opt: Add -fipa-tls-access. > > > * common.opt.urls: Regenerated. > > > * ipa-visibility.cc (function_and_variable_visibility): Don't > > > check tls_model attribute. Update TLS access comments. > > > * doc/extend.texi: Update the tls_model attribute. > > > * doc/invoke.texi: Document -fipa-tls-access. > > > > > > gcc/testsuite/ > > > > > > PR middle-end/121352 > > > * c-c++-common/tls-attr-hidden-gd.c: New test. > > > * c-c++-common/tls-attr-le-undef.c: Likewise. > > > * c-c++-common/tls-flag-hidden-gd.c: Likewise. > > > * c-c++-common/tls-pragma-hidden-gd.c: Likewise. > > > * gcc.dg/tls/vis-attr-hidden-gd.c: Pass -fno-ipa-tls-access. > > > * gcc.dg/tls/vis-flag-hidden-gd.c: Likewise. > > > * gcc.dg/tls/vis-pragma-hidden-gd.c: Likewise. > > > > > > Signed-off-by: H.J. Lu <[email protected]> > > > --- > > > gcc/common.opt | 4 ++++ > > > gcc/common.opt.urls | 3 +++ > > > gcc/doc/extend.texi | 14 +++++++++----- > > > gcc/doc/invoke.texi | 6 ++++++ > > > gcc/ipa-visibility.cc | 14 ++++++++++---- > > > gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c | 13 +++++++++++++ > > > gcc/testsuite/c-c++-common/tls-attr-le-undef.c | 15 +++++++++++++++ > > > gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c | 13 +++++++++++++ > > > .../c-c++-common/tls-pragma-hidden-gd.c | 17 +++++++++++++++++ > > > gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c | 2 +- > > > gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c | 2 +- > > > gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c | 2 +- > > > 12 files changed, 93 insertions(+), 12 deletions(-) > > > create mode 100644 gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c > > > create mode 100644 gcc/testsuite/c-c++-common/tls-attr-le-undef.c > > > create mode 100644 gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c > > > create mode 100644 gcc/testsuite/c-c++-common/tls-pragma-hidden-gd.c > > > > > > diff --git a/gcc/common.opt b/gcc/common.opt > > > index f6d93dc05fb..42c424b45d0 100644 > > > --- a/gcc/common.opt > > > +++ b/gcc/common.opt > > > @@ -2190,6 +2190,10 @@ fipa-icf-variables > > > Common Var(flag_ipa_icf_variables) Optimization > > > Perform Identical Code Folding for variables. > > > > > > +fipa-tls-access > > > +Common Var(flag_ipa_tls_access) Init(1) Optimization > > > +Perform TLS access optimization. > > > + > > > fipa-reference > > > Common Var(flag_ipa_reference) Init(0) Optimization > > > Discover read-only and non addressable static variables. > > > diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls > > > index ddc5eaf9c6b..b1af1b500f5 100644 > > > --- a/gcc/common.opt.urls > > > +++ b/gcc/common.opt.urls > > > @@ -917,6 +917,9 @@ > > > UrlSuffix(gcc/Optimize-Options.html#index-fipa-pure-const) > > > fipa-icf > > > UrlSuffix(gcc/Optimize-Options.html#index-fipa-icf) > > > > > > +fipa-tls-access > > > +UrlSuffix(gcc/Optimize-Options.html#index-fipa-tls-access) > > > + > > > fipa-reference > > > UrlSuffix(gcc/Optimize-Options.html#index-fipa-reference) > > > > > > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > > > index 2922d9e9839..9d55fbb61af 100644 > > > --- a/gcc/doc/extend.texi > > > +++ b/gcc/doc/extend.texi > > > @@ -7559,11 +7559,15 @@ information. > > > @cindex @code{tls_model} variable attribute > > > @item tls_model ("@var{tls_model}") > > > The @code{tls_model} attribute sets thread-local storage model > > > -(@pxref{Thread-Local}) of a particular @code{__thread} variable, > > > -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}. > > > +(@pxref{Thread-Local}) of a particular @code{__thread} variable 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}. The @code{tls_model} attribute specifies the > > > +weakest @acronym{TLS} model. It overrides @option{-ftls-model=} > > > +command-line switch if it is stronger than the @acronym{TLS} model > > > +specified by the command-line switch. GCC may optimize @acronym{TLS} > > > +access to a stronger @acronym{TLS} model by C/C++ front end as well > > > +as IPA optimization (see @option{-fno-ipa-tls-access}). > > > > > > Not all targets support this attribute. > > > > > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > > > index d0c13d4a24e..b6019cf2746 100644 > > > --- a/gcc/doc/invoke.texi > > > +++ b/gcc/doc/invoke.texi > > > @@ -14216,6 +14216,12 @@ option is not enabled by default otherwise. > > > Reduce stack alignment on call sites if possible. > > > Enabled by default. > > > > > > +@opindex fno-ipa-tls-access > > > +@opindex fipa-tls-access > > > +@item -fno-ipa-tls-access > > > +Don't upgrade TLS model as the part of IPA whole-program visibility > > > +optimization. > > > + > > > @opindex fipa-pta > > > @item -fipa-pta > > > Perform interprocedural pointer analysis and interprocedural modification > > > diff --git a/gcc/ipa-visibility.cc b/gcc/ipa-visibility.cc > > > index 8097a03e240..56bc39816bf 100644 > > > --- a/gcc/ipa-visibility.cc > > > +++ b/gcc/ipa-visibility.cc > > > @@ -883,18 +883,24 @@ function_and_variable_visibility (bool > > > whole_program) > > > tree decl = vnode->decl; > > > > > > /* Upgrade TLS access model based on optimized visibility > > > status, > > > - unless it was specified explicitly or no references remain. > > > */ > > > + unless TLS access optimization is disabled or no references > > > + remain. */ > > > if (DECL_THREAD_LOCAL_P (decl) > > > - && !lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl)) > > > + && flag_ipa_tls_access > > > && vnode->ref_list.referring.length ()) > > > { > > > enum tls_model new_model = decl_default_tls_model (decl); > > > STATIC_ASSERT (TLS_MODEL_GLOBAL_DYNAMIC < > > > TLS_MODEL_LOCAL_DYNAMIC); > > > STATIC_ASSERT (TLS_MODEL_INITIAL_EXEC < > > > TLS_MODEL_LOCAL_EXEC); > > > - /* We'd prefer to assert that recomputed model is not > > > weaker than > > > - what the front-end assigned, but cannot: see PR 107353. > > > */ > > > + /* decl_default_tls_model does not scan the attribute list > > > + and may return a weaker model than the attribute. If > > > + there was no attribute, we can expect that recomputed > > > + model is never weaker. */ > > > if (new_model >= decl_tls_model (decl)) > > > set_decl_tls_model (decl, new_model); > > > + else > > > + gcc_checking_assert (lookup_attribute ("tls_model", > > > + DECL_ATTRIBUTES > > > (decl))); > > > } > > > } > > > } > > > diff --git a/gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c > > > b/gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c > > > new file mode 100644 > > > index 00000000000..4512bff04ad > > > --- /dev/null > > > +++ b/gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c > > > @@ -0,0 +1,13 @@ > > > +/* { dg-do compile } */ > > > +/* { dg-require-effective-target fpic } */ > > > +/* { dg-require-effective-target tls } */ > > > +/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program" } */ > > > + > > > +__attribute__((visibility("hidden"))) > > > +__attribute__((tls_model("global-dynamic"))) > > > +__thread int x; > > > + > > > +void reference() { x++; } > > > + > > > +// tls_model should be local-dynamic due to hidden visibility. > > > +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-dynamic" > > > "whole-program" } } */ > > > diff --git a/gcc/testsuite/c-c++-common/tls-attr-le-undef.c > > > b/gcc/testsuite/c-c++-common/tls-attr-le-undef.c > > > new file mode 100644 > > > index 00000000000..b11c5c9dabc > > > --- /dev/null > > > +++ b/gcc/testsuite/c-c++-common/tls-attr-le-undef.c > > > @@ -0,0 +1,15 @@ > > > +/* { dg-do compile } */ > > > +/* { dg-require-effective-target tls } */ > > > +/* { dg-options "-O2 -fdump-ipa-whole-program" } */ > > > + > > > +__attribute__ ((tls_model ("local-exec"))) > > > +extern __thread int i; > > > + > > > +int * > > > +foo (void) > > > +{ > > > + return &i; > > > +} > > > + > > > +/* tls_model should be local-exec due to tls_model attribute. */ > > > +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-exec" > > > "whole-program" } } */ > > > diff --git a/gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c > > > b/gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c > > > new file mode 100644 > > > index 00000000000..fba79cfd75a > > > --- /dev/null > > > +++ b/gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c > > > @@ -0,0 +1,13 @@ > > > +/* { dg-do compile } */ > > > +/* { dg-require-effective-target fpic } */ > > > +/* { dg-require-effective-target tls } */ > > > +/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program -fvisibility=hidden" > > > } */ > > > + > > > + > > > +__attribute__((tls_model("global-dynamic"))) > > > +__thread int x; > > > + > > > +void reference() { x++; } > > > + > > > +// tls_model should be local-dynamic due to hidden visibility. > > > +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-dynamic" > > > "whole-program" } } */ > > > diff --git a/gcc/testsuite/c-c++-common/tls-pragma-hidden-gd.c > > > b/gcc/testsuite/c-c++-common/tls-pragma-hidden-gd.c > > > new file mode 100644 > > > index 00000000000..3649b6f7272 > > > --- /dev/null > > > +++ b/gcc/testsuite/c-c++-common/tls-pragma-hidden-gd.c > > > @@ -0,0 +1,17 @@ > > > +/* { dg-do compile } */ > > > +/* { dg-require-effective-target fpic } */ > > > +/* { dg-require-effective-target tls } */ > > > +/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program" } */ > > > + > > > + > > > +#pragma GCC visibility push(hidden) > > > + > > > +__attribute__((tls_model("global-dynamic"))) > > > +__thread int x; > > > + > > > +#pragma GCC visibility pop > > > + > > > +void reference() { x++; } > > > + > > > +// tls_model should be local-dynamic due to hidden visibility. > > > +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-dynamic" > > > "whole-program" } } */ > > > diff --git a/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c > > > b/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c > > > index e32565588c8..05b04cc774b 100644 > > > --- a/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c > > > +++ b/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c > > > @@ -1,7 +1,7 @@ > > > /* { dg-do compile } */ > > > /* { dg-require-effective-target fpic } */ > > > /* { dg-require-effective-target tls } */ > > > -/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program" } */ > > > +/* { dg-options "-O2 -fPIC -fno-ipa-tls-access -fdump-ipa-whole-program" > > > } */ > > > > > > // tls_model should be global-dynamic due to explicitly specified > > > attribute > > > __attribute__((visibility("hidden"))) > > > diff --git a/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c > > > b/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c > > > index cad41e0c8e6..85ee07fb563 100644 > > > --- a/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c > > > +++ b/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c > > > @@ -1,7 +1,7 @@ > > > /* { dg-do compile } */ > > > /* { dg-require-effective-target fpic } */ > > > /* { dg-require-effective-target tls } */ > > > -/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program -fvisibility=hidden" > > > } */ > > > +/* { dg-options "-O2 -fPIC -fno-ipa-tls-access -fdump-ipa-whole-program > > > -fvisibility=hidden" } */ > > > > > > > > > // tls_model should be global-dynamic due to explicitly specified > > > attribute > > > diff --git a/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c > > > b/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c > > > index 3b3598134fe..7b0a01b8629 100644 > > > --- a/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c > > > +++ b/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c > > > @@ -1,7 +1,7 @@ > > > /* { dg-do compile } */ > > > /* { dg-require-effective-target fpic } */ > > > /* { dg-require-effective-target tls } */ > > > -/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program" } */ > > > +/* { dg-options "-O2 -fPIC -fno-ipa-tls-access -fdump-ipa-whole-program" > > > } */ > > > > > > > > > #pragma GCC visibility push(hidden) > > > -- > > > 2.51.0 > > > > > > > PING. > > > > -- > > H.J. > > PING. > > -- > H.J.
PING. -- H.J.
