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 Issue an error for -mtls-dialect=gnu with no_caller_saved_registers attribute and suggest -mtls-dialect=gnu2 when __tls_get_addr is used. 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 + + */ + 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