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

Reply via email to