On Thu, Jul 24, 2025 at 9:30 PM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> On x86-64, __tls_get_addr is a normal function which doesn't preserve
> vector registers.  On i386, ___tls_get_addr preserve vector registers
> only with the commit:

Can you please rephrase the above part? What does it mean to be a
normal function in the context of this patch? Does the x86_64 compiler
emit the normal ABI call (so the caller has to save and restore
call-clobbered regs)? What is the difference to i386 ___tls_get_addr
call?

> 848f0e46f0 i386: Update ___tls_get_addr to preserve vector registers
>
> which fixed:
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=32996
>
> -mtls-dialect=gnu2 should be used instead with a fixed glibc for
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=31372
>
> with the commit:
>
> 0aac205a81 x86: Update _dl_tlsdesc_dynamic to preserve caller-saved registers
>
> Issue an error for -mtls-dialect=gnu with no_caller_saved_registers
> attribute and suggest -mtls-dialect=gnu2 when __tls_get_addr is used.

If these are fixed, why do we need to use -mtls-dialect=gnu2?

> gcc/
>
>         PR target/121208
>         * config/i386/i386.cc (ix86_tls_get_addr): Issue an error for
>         -mtls-dialect=gnu with no_caller_saved_registers attribute and
>         suggest -mtls-dialect=gnu2.
>
> gcc/testsuite/
>
>         PR target/121208
>         * gcc.target/i386/pr121208-1a.c: New test.
>         * gcc.target/i386/pr121208-1b.c: Likewise.
>         * gcc.target/i386/pr121208-2a.c: Likewise.
>         * gcc.target/i386/pr121208-2b.c: Likewise.
>         * gcc.target/i386/pr121208-3a.c: Likewise.
>         * gcc.target/i386/pr121208-3b.c: Likewise.
>
> Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
> ---
>  gcc/config/i386/i386.cc                     | 38 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr121208-1a.c | 15 ++++++++
>  gcc/testsuite/gcc.target/i386/pr121208-1b.c |  4 +++
>  gcc/testsuite/gcc.target/i386/pr121208-2a.c | 17 +++++++++
>  gcc/testsuite/gcc.target/i386/pr121208-2b.c |  4 +++
>  gcc/testsuite/gcc.target/i386/pr121208-3a.c | 17 +++++++++
>  gcc/testsuite/gcc.target/i386/pr121208-3b.c |  4 +++
>  7 files changed, 99 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr121208-1a.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr121208-1b.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr121208-2a.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr121208-2b.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr121208-3a.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr121208-3b.c
>
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index 4682db85ce4..7a2037ab6b4 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -12442,6 +12442,44 @@ static GTY(()) rtx ix86_tls_symbol;
>  static rtx
>  ix86_tls_get_addr (void)
>  {
> +  if (cfun->machine->call_saved_registers
> +      == TYPE_NO_CALLER_SAVED_REGISTERS)
> +    {
> +      /* On x86-64, __tls_get_addr is a normal function which doesn't
> +        preserve vector registers.  On i386, ___tls_get_addr preserve
> +        vector registers only with the commit:
> +
> +        848f0e46f0 i386: Update ___tls_get_addr to preserve vector registers
> +
> +        which fixed:
> +
> +        https://sourceware.org/bugzilla/show_bug.cgi?id=32996
> +
> +        -mtls-dialect=gnu2 should be used instead with a fixed glibc
> +        for
> +
> +        https://sourceware.org/bugzilla/show_bug.cgi?id=31372
> +
> +        with the commit:
> +
> +        0aac205a81 x86: Update _dl_tlsdesc_dynamic to preserve caller-saved 
> registers

The comment here does not need to be so verbose.

Uros.

> +
> +       */
> +      if (cfun->machine->func_type != TYPE_NORMAL)
> +       error (cfun->machine->func_type == TYPE_EXCEPTION
> +              ? G_("%<-mtls-dialect=gnu2%> must be used with an"
> +                   " exception service routine")
> +              : G_("%<-mtls-dialect=gnu2%> must be used with an"
> +                   " interrupt service routine"));
> +      else
> +       error (G_("%<-mtls-dialect=gnu2%> must be used with a function"
> +                 " with the %<no_caller_saved_registers%> attribute"));
> +      /* Don't issue the same error twice.  */
> +      cfun->machine->func_type = TYPE_NORMAL;
> +      cfun->machine->call_saved_registers
> +       = TYPE_DEFAULT_CALL_SAVED_REGISTERS;
> +    }
> +
>    if (!ix86_tls_symbol)
>      {
>        const char *sym
> diff --git a/gcc/testsuite/gcc.target/i386/pr121208-1a.c 
> b/gcc/testsuite/gcc.target/i386/pr121208-1a.c
> new file mode 100644
> index 00000000000..ac851cb50d8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr121208-1a.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fPIC -mtls-dialect=gnu" } */
> +
> +extern __thread int bar;
> +extern void func (void);
> +
> +__attribute__((no_caller_saved_registers))
> +void
> +foo (int error)
> +{
> +  bar = 1; /* { dg-error -mtls-dialect=gnu2 } */
> +  if (error == 0)
> +    func ();
> +  bar = 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr121208-1b.c 
> b/gcc/testsuite/gcc.target/i386/pr121208-1b.c
> new file mode 100644
> index 00000000000..b97ac715c65
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr121208-1b.c
> @@ -0,0 +1,4 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fPIC -mtls-dialect=gnu2" } */
> +
> +#include "pr121208-1a.c"
> diff --git a/gcc/testsuite/gcc.target/i386/pr121208-2a.c 
> b/gcc/testsuite/gcc.target/i386/pr121208-2a.c
> new file mode 100644
> index 00000000000..c1891ae322c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr121208-2a.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fPIC -mtls-dialect=gnu" } */
> +
> +typedef unsigned int uword_t __attribute__ ((mode (__word__)));
> +extern __thread int bar;
> +extern void func (void);
> +
> +__attribute__((target("general-regs-only")))
> +__attribute__((interrupt))
> +void
> +foo (void *frame, uword_t error)
> +{
> +  bar = 1; /* { dg-error -mtls-dialect=gnu2 } */
> +  if (error == 0)
> +    func ();
> +  bar = 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr121208-2b.c 
> b/gcc/testsuite/gcc.target/i386/pr121208-2b.c
> new file mode 100644
> index 00000000000..269b120f990
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr121208-2b.c
> @@ -0,0 +1,4 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fPIC -mtls-dialect=gnu2" } */
> +
> +#include "pr121208-2a.c"
> diff --git a/gcc/testsuite/gcc.target/i386/pr121208-3a.c 
> b/gcc/testsuite/gcc.target/i386/pr121208-3a.c
> new file mode 100644
> index 00000000000..26fe6870155
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr121208-3a.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fPIC -mtls-dialect=gnu" } */
> +
> +typedef unsigned int uword_t __attribute__ ((mode (__word__)));
> +extern __thread int bar;
> +extern void func (void);
> +
> +__attribute__((target("general-regs-only")))
> +__attribute__((interrupt))
> +void
> +foo (void *frame)
> +{
> +  bar = 1; /* { dg-error -mtls-dialect=gnu2 } */
> +  if (frame == 0)
> +    func ();
> +  bar = 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr121208-3b.c 
> b/gcc/testsuite/gcc.target/i386/pr121208-3b.c
> new file mode 100644
> index 00000000000..b672d751d7f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr121208-3b.c
> @@ -0,0 +1,4 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fPIC -mtls-dialect=gnu2" } */
> +
> +#include "pr121208-3a.c"
> --
> 2.50.1
>

Reply via email to