commit:     3593100a40de80ef4b25dc04b016a8e75e46f6fc
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Thu Aug 28 05:26:30 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 28 05:26:52 2025 +0000
URL:        https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=3593100a

16.0.0: update TLS patches

Signed-off-by: Sam James <sam <AT> gentoo.org>

 ...fault-to-mtls-dialect-gnu2-if-appropriate.patch |  41 +-
 ...er-compare-source-operands-of-tls_dynamic.patch | 234 ------------
 ...Improve-source-operand-check-for-TLS_CALL.patch | 424 +++++++++++++++++++++
 16.0.0/gentoo/README.history                       |   2 +-
 4 files changed, 442 insertions(+), 259 deletions(-)

diff --git 
a/16.0.0/gentoo/86_all_PR120933-i386-default-to-mtls-dialect-gnu2-if-appropriate.patch
 
b/16.0.0/gentoo/86_all_PR120933-i386-default-to-mtls-dialect-gnu2-if-appropriate.patch
index cdcb655..dfd673c 100644
--- 
a/16.0.0/gentoo/86_all_PR120933-i386-default-to-mtls-dialect-gnu2-if-appropriate.patch
+++ 
b/16.0.0/gentoo/86_all_PR120933-i386-default-to-mtls-dialect-gnu2-if-appropriate.patch
@@ -1,5 +1,5 @@
-From 02616942358bd045b21a69c0c866687150080d12 Mon Sep 17 00:00:00 2001
-Message-ID: 
<02616942358bd045b21a69c0c866687150080d12.1756094106.git....@gentoo.org>
+From 06ade1197723d083766db2ea37af464492795b07 Mon Sep 17 00:00:00 2001
+Message-ID: 
<06ade1197723d083766db2ea37af464492795b07.1756358799.git....@gentoo.org>
 From: Sam James <[email protected]>
 Date: Sun, 24 Aug 2025 00:30:45 +0100
 Subject: [PATCH] i386: default to -mtls-dialect=gnu2 if appropriate
@@ -45,9 +45,6 @@ Some implementation notes:
   machinery is added to glibc and bfd. This makes the separate position of
   the check (not with some of the others) a bit more palatable IMO.
 
-TODO: Handle -x32
-TODO: Test i686
-
 gcc/ChangeLog:
        PR target/120933
        * configure: Regenerate.
@@ -57,12 +54,12 @@ gcc/ChangeLog:
        (with_tls): Default to 'gnu2' if --with-tls is not passed and
        gcc_cv_libc_x86_tlsdesc_call is 'yes'.
 ---
- gcc/configure    | 219 +++++++++++++++++++++++++++++++----------------
- gcc/configure.ac | 114 ++++++++++++++++++------
- 2 files changed, 233 insertions(+), 100 deletions(-)
+ gcc/configure    | 217 +++++++++++++++++++++++++++++++----------------
+ gcc/configure.ac | 112 ++++++++++++++++++------
+ 2 files changed, 229 insertions(+), 100 deletions(-)
 
 diff --git a/gcc/configure b/gcc/configure
-index 4a751d969bab..067e95eeedd2 100755
+index 4a751d969bab..ba303469613c 100755
 --- a/gcc/configure
 +++ b/gcc/configure
 @@ -737,7 +737,6 @@ libgcc_visibility
@@ -81,7 +78,7 @@ index 4a751d969bab..067e95eeedd2 100755
  objext
  manext
  LIBICONV_DEP
-@@ -12927,6 +12927,147 @@ if test "x$enable_win32_utf8_manifest" != xno; then
+@@ -12927,6 +12927,145 @@ if test "x$enable_win32_utf8_manifest" != xno; then
    host_extra_objs_mingw=utf8-mingw32.o
  fi
  
@@ -168,15 +165,13 @@ index 4a751d969bab..067e95eeedd2 100755
 +      # for this behavior and binaries will depend on GLIBC_ABI_GNU2_TLS and 
fixed
 +      # glibc.  Hence the presence of GLIBC_ABI_GNU2_TLS tells us if we can 
safely
 +      # default to GNU2 TLS descriptors.
-+      #
-+      # TODO: x32
 +      conftest_S='
 +              .section        .text.startup,"ax",@progbits
 +              .p2align 4
 +              .globl  main
 +              .type   main, @function
 +              main:
-+                #ifdef __x86_64__
++              #ifdef __x86_64__
 +                      leaq    foo@TLSDESC(%rip), %rax
 +                      call    *foo@TLSCALL(%rax)
 +                      movl    %fs:(%rax), %eax
@@ -229,25 +224,25 @@ index 4a751d969bab..067e95eeedd2 100755
  # --------------------------------------------------------
  # Build, host, and target specific configuration fragments
  # --------------------------------------------------------
-@@ -21484,7 +21625,7 @@ else
+@@ -21484,7 +21623,7 @@ else
    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
    lt_status=$lt_dlunknown
    cat > conftest.$ac_ext <<_LT_EOF
 -#line 21487 "configure"
-+#line 21628 "configure"
++#line 21626 "configure"
  #include "confdefs.h"
  
  #if HAVE_DLFCN_H
-@@ -21590,7 +21731,7 @@ else
+@@ -21590,7 +21729,7 @@ else
    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
    lt_status=$lt_dlunknown
    cat > conftest.$ac_ext <<_LT_EOF
 -#line 21593 "configure"
-+#line 21734 "configure"
++#line 21732 "configure"
  #include "confdefs.h"
  
  #if HAVE_DLFCN_H
-@@ -25419,78 +25560,6 @@ else
+@@ -25419,78 +25558,6 @@ else
  $as_echo "$gcc_cv_objdump" >&6; }
  fi
  
@@ -327,10 +322,10 @@ index 4a751d969bab..067e95eeedd2 100755
  if ${gcc_cv_otool+:} false; then :
  
 diff --git a/gcc/configure.ac b/gcc/configure.ac
-index 4532c5c22fe5..5c60c47d36be 100644
+index 4532c5c22fe5..4c268d565d72 100644
 --- a/gcc/configure.ac
 +++ b/gcc/configure.ac
-@@ -1886,6 +1886,95 @@ if test "x$enable_win32_utf8_manifest" != xno; then
+@@ -1886,6 +1886,93 @@ if test "x$enable_win32_utf8_manifest" != xno; then
    host_extra_objs_mingw=utf8-mingw32.o
  fi
  
@@ -372,15 +367,13 @@ index 4532c5c22fe5..5c60c47d36be 100644
 +      # for this behavior and binaries will depend on GLIBC_ABI_GNU2_TLS and 
fixed
 +      # glibc.  Hence the presence of GLIBC_ABI_GNU2_TLS tells us if we can 
safely
 +      # default to GNU2 TLS descriptors.
-+      #
-+      # TODO: x32
 +      conftest_S='
 +              .section        .text.startup,"ax",@progbits
 +              .p2align 4
 +              .globl  main
 +              .type   main, @function
 +              main:
-+                #ifdef __x86_64__
++              #ifdef __x86_64__
 +                      leaq    foo@TLSDESC(%rip), %rax
 +                      call    *foo@TLSCALL(%rax)
 +                      movl    %fs:(%rax), %eax
@@ -426,7 +419,7 @@ index 4532c5c22fe5..5c60c47d36be 100644
  # --------------------------------------------------------
  # Build, host, and target specific configuration fragments
  # --------------------------------------------------------
-@@ -2934,31 +3023,6 @@ else
+@@ -2934,31 +3021,6 @@ else
        AC_MSG_RESULT($gcc_cv_objdump)
  fi
  

diff --git 
a/16.0.0/gentoo/88_all-x86-64-Better-compare-source-operands-of-tls_dynamic.patch
 
b/16.0.0/gentoo/88_all-x86-64-Better-compare-source-operands-of-tls_dynamic.patch
deleted file mode 100644
index 44865e7..0000000
--- 
a/16.0.0/gentoo/88_all-x86-64-Better-compare-source-operands-of-tls_dynamic.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From ec4cc64262841e49967c2bf69dcd095985c2e304 Mon Sep 17 00:00:00 2001
-Message-ID: 
<ec4cc64262841e49967c2bf69dcd095985c2e304.1756251629.git....@gentoo.org>
-In-Reply-To: 
<ca5a4b3eea207904c64e638a4ecefd347f386abb.1756251629.git....@gentoo.org>
-References: 
<ca5a4b3eea207904c64e638a4ecefd347f386abb.1756251629.git....@gentoo.org>
-From: "H.J. Lu" <[email protected]>
-Date: Tue, 26 Aug 2025 15:31:34 -0700
-Subject: [PATCH 2/2] x86-64: Better compare source operands of
- *tls_dynamic_gnu2_call_64_di
-
-Source operands of 2 *tls_dynamic_gnu2_call_64_di patterns in
-
-(insn 10 9 11 3 (set (reg:DI 100)
-        (unspec:DI [
-                (symbol_ref:DI ("caml_state") [flags 0x10]  <var_decl 
0x7fe10e1d9e40 caml_state>)
-            ] UNSPEC_TLSDESC)) "x.c":7:16 1674 {*tls_dynamic_gnu2_lea_64_di}
-     (nil))
-(insn 11 10 12 3 (parallel [
-            (set (reg:DI 99)
-                (unspec:DI [
-                        (symbol_ref:DI ("caml_state") [flags 0x10]  <var_decl 
0x7fe10e1d9e40 caml_state>)
-                        (reg:DI 100)
-                        (reg/f:DI 7 sp)
-                    ] UNSPEC_TLSDESC))
-            (clobber (reg:CC 17 flags))
-        ]) "x.c":7:16 1676 {*tls_dynamic_gnu2_call_64_di}
-     (expr_list:REG_DEAD (reg:DI 100)
-        (expr_list:REG_UNUSED (reg:CC 17 flags)
-            (nil))))
-
-and
-
-(insn 19 17 20 4 (set (reg:DI 104)
-        (unspec:DI [
-                (symbol_ref:DI ("caml_state") [flags 0x10]  <var_decl 
0x7fe10e1d9e40 caml_state>)
-            ] UNSPEC_TLSDESC)) "x.c":6:10 discrim 1 1674 
{*tls_dynamic_gnu2_lea_64_di}
-     (nil))
-(insn 20 19 21 4 (parallel [
-            (set (reg:DI 103)
-                (unspec:DI [
-                        (symbol_ref:DI ("caml_state") [flags 0x10]  <var_decl 
0x7fe10e1d9e40 caml_state>)
-                        (reg:DI 104)
-                        (reg/f:DI 7 sp)
-                    ] UNSPEC_TLSDESC))
-            (clobber (reg:CC 17 flags))
-        ]) "x.c":6:10 discrim 1 1676 {*tls_dynamic_gnu2_call_64_di}
-     (expr_list:REG_DEAD (reg:DI 104)
-        (expr_list:REG_UNUSED (reg:CC 17 flags)
-            (nil))))
-
-are the same even though rtx_equal_p returns false since (reg:DI 100)
-and (reg:DI 104) are set from the same symbol.  Add x86_cse_rtx_equal_p
-to compare source operands of *tls_dynamic_gnu2_call_64_di patterns and
-return true if only source operands differ and they are set from the
-same symbol.
-
-gcc/
-
-       * config/i386/i386-features.cc
-       (pass_x86_cse::x86_cse_rtx_equal_p): New.
-       (pass_x86_cse::tls_set_insn_from_symbol): Likewise.
-       (pass_x86_cse::candidate_gnu2_tls_p): Call
-       tls_set_insn_from_symbol.
-       (pass_x86_cse::x86_cse): Call x86_cse_rtx_equal_p, instead of
-       rtx_equal_p, to compare 2 values.
-
-gcc/testsuite/
-
-       * gcc.target/i386/pr121668-1b.c: New test.
-
-Signed-off-by: H.J. Lu <[email protected]>
----
- gcc/config/i386/i386-features.cc            | 116 +++++++++++++++-----
- gcc/testsuite/gcc.target/i386/pr121668-1b.c |   6 +
- 2 files changed, 95 insertions(+), 27 deletions(-)
- create mode 100644 gcc/testsuite/gcc.target/i386/pr121668-1b.c
-
-diff --git a/gcc/config/i386/i386-features.cc 
b/gcc/config/i386/i386-features.cc
-index 93e20947edf3..ce77e91c1203 100644
---- a/gcc/config/i386/i386-features.cc
-+++ b/gcc/config/i386/i386-features.cc
-@@ -4168,8 +4168,95 @@ private:
-   bool candidate_gnu_tls_p (rtx_insn *, attr_tls64);
-   bool candidate_gnu2_tls_p (rtx, attr_tls64);
-   bool candidate_vector_p (rtx);
-+  bool x86_cse_rtx_equal_p (const_rtx, const_rtx);
-+  rtx_insn *tls_set_insn_from_symbol (const_rtx, rtx *);
- }; // class pass_x86_cse
- 
-+/* Return true if X and Y are equal.  */
-+
-+bool
-+pass_x86_cse::x86_cse_rtx_equal_p (const_rtx x, const_rtx y)
-+{
-+  if (kind == X86_CSE_TLSDESC
-+      && GET_CODE (x) == UNSPEC
-+      && XINT (x, 1) == UNSPEC_TLSDESC
-+      && SYMBOL_REF_P (XVECEXP (x, 0, 0)))
-+    {
-+     /* Compare
-+
-+      (unspec:DI [
-+        (symbol_ref:DI ("caml_state") [flags 0x10] <var_decl 0x7fffe99d9e40 
caml_state>)
-+        (reg:DI 100)
-+        (reg/f:DI 7 sp)
-+      ] UNSPEC_TLSDESC)
-+
-+      against
-+
-+      (unspec:DI [
-+        (symbol_ref:DI ("caml_state") [flags 0x10] <var_decl 0x7fffe99d9e40 
caml_state>)
-+        (reg:DI 104)
-+        (reg/f:DI 7 sp)
-+      ] UNSPEC_TLSDESC)
-+
-+      If (reg:DI 100) and (reg:DI 104) are defined from the same source,
-+      they are equal.  */
-+
-+      if (GET_CODE (y) != UNSPEC
-+        || XINT (y, 1) != UNSPEC_TLSDESC
-+        || !SYMBOL_REF_P (XVECEXP (y, 0, 0))
-+        || !rtx_equal_p (XVECEXP (x, 0, 0), XVECEXP (y, 0, 0)))
-+      return false;
-+
-+      x = XVECEXP (x, 0, 1);
-+      y = XVECEXP (y, 0, 1);
-+      if (rtx_equal_p (x, y))
-+      return true;
-+
-+      rtx tls_symbol = nullptr;
-+      return (tls_set_insn_from_symbol (x, &tls_symbol)
-+            && tls_symbol
-+            && tls_set_insn_from_symbol (y, &tls_symbol));
-+    }
-+
-+  return rtx_equal_p (x, y);
-+}
-+
-+/* Return the instruction which sets REG from one symbol and store the
-+   symbol in *TLS_SYMBOL_P if *TLS_SYMBOL_P is nullptr.  */
-+
-+rtx_insn *
-+pass_x86_cse::tls_set_insn_from_symbol (const_rtx reg, rtx *tls_symol_p)
-+{
-+  rtx_insn *set_insn = nullptr;
-+  rtx tls_symbol = *tls_symol_p;
-+  for (df_ref ref = DF_REG_DEF_CHAIN (REGNO (reg));
-+       ref;
-+       ref = DF_REF_NEXT_REG (ref))
-+    {
-+      if (DF_REF_IS_ARTIFICIAL (ref))
-+      return nullptr;
-+
-+      set_insn = DF_REF_INSN (ref);
-+      if (get_attr_tls64 (set_insn) != TLS64_LEA)
-+      return nullptr;
-+
-+      rtx tls_set = PATTERN (set_insn);
-+      rtx tls_src = XVECEXP (SET_SRC (tls_set), 0, 0);
-+      if (tls_symbol == nullptr)
-+      {
-+        if (!SYMBOL_REF_P (tls_src))
-+          return nullptr;
-+
-+        tls_symbol = tls_src;
-+        *tls_symol_p = tls_src;
-+      }
-+      else if (!rtx_equal_p (tls_symbol, tls_src))
-+      return nullptr;
-+    }
-+
-+  return set_insn;
-+}
-+
- /* Return true and output def_insn, val, mode, scalar_mode and kind if
-    INSN is UNSPEC_TLS_GD or UNSPEC_TLS_LD_BASE.  */
- 
-@@ -4283,32 +4370,7 @@ pass_x86_cse::candidate_gnu2_tls_p (rtx set, attr_tls64 
tls64)
- 
-        */
- 
--      df_ref ref;
--      rtx_insn *set_insn = nullptr;
--      for (ref = DF_REG_DEF_CHAIN (REGNO (src));
--         ref;
--         ref = DF_REF_NEXT_REG (ref))
--      {
--        if (DF_REF_IS_ARTIFICIAL (ref))
--          break;
--
--        set_insn = DF_REF_INSN (ref);
--        tls64 = get_attr_tls64 (set_insn);
--        if (tls64 != TLS64_LEA)
--          {
--            set_insn = nullptr;
--            break;
--          }
--
--        rtx tls_set = PATTERN (set_insn);
--        rtx tls_src = XVECEXP (SET_SRC (tls_set), 0, 0);
--        if (!rtx_equal_p (tls_symbol, tls_src))
--          {
--            set_insn = nullptr;
--            break;
--          }
--      }
--
-+      rtx_insn *set_insn = tls_set_insn_from_symbol (src, &tls_symbol);
-       if (!set_insn)
-       return false;
- 
-@@ -4436,7 +4498,7 @@ pass_x86_cse::x86_cse (void)
-                   /* Non all 0s/1s vector load must be in the same
-                      basic block if it is in a recursive call.  */
-                   || !recursive_call_p)
--              && rtx_equal_p (load->val, val))
-+              && x86_cse_rtx_equal_p (load->val, val))
-             {
-               /* Record instruction.  */
-               bitmap_set_bit (load->insns, INSN_UID (insn));
-diff --git a/gcc/testsuite/gcc.target/i386/pr121668-1b.c 
b/gcc/testsuite/gcc.target/i386/pr121668-1b.c
-new file mode 100644
-index 000000000000..54a277506f83
---- /dev/null
-+++ b/gcc/testsuite/gcc.target/i386/pr121668-1b.c
-@@ -0,0 +1,6 @@
-+/* { dg-do compile { target *-*-linux* } } */
-+/* { dg-options "-Og -g -fpic -fplt -mtls-dialect=gnu2" } */
-+
-+#include "pr121668-1a.c"
-+
-+/* { dg-final { scan-assembler-times "call\[ 
\t\]\\*caml_state@TLSCALL\\(%(?:r|e)ax\\)" 1 { target { ! ia32 } } } } */
--- 
-2.51.0
-

diff --git 
a/16.0.0/gentoo/88_all-x86-64-Improve-source-operand-check-for-TLS_CALL.patch 
b/16.0.0/gentoo/88_all-x86-64-Improve-source-operand-check-for-TLS_CALL.patch
new file mode 100644
index 0000000..7177603
--- /dev/null
+++ 
b/16.0.0/gentoo/88_all-x86-64-Improve-source-operand-check-for-TLS_CALL.patch
@@ -0,0 +1,424 @@
+From ec2e1fe2a6d5b004d5666e0a5f8dc00b8f0e2985 Mon Sep 17 00:00:00 2001
+Message-ID: 
<ec2e1fe2a6d5b004d5666e0a5f8dc00b8f0e2985.1756358733.git....@gentoo.org>
+From: "H.J. Lu" <[email protected]>
+Date: Wed, 27 Aug 2025 19:14:13 -0700
+Subject: [PATCH] x86-64: Improve source operand check for TLS_CALL
+
+Source operands of 2 TLS_CALL patterns in
+
+(insn 10 9 11 3 (set (reg:DI 100)
+        (unspec:DI [
+                (symbol_ref:DI ("caml_state") [flags 0x10]  <var_decl 
0x7fe10e1d9e40 caml_state>)
+            ] UNSPEC_TLSDESC)) "x.c":7:16 1674 {*tls_dynamic_gnu2_lea_64_di}
+     (nil))
+(insn 11 10 12 3 (parallel [
+            (set (reg:DI 99)
+                (unspec:DI [
+                        (symbol_ref:DI ("caml_state") [flags 0x10]  <var_decl 
0x7fe10e1d9e40 caml_state>)
+                        (reg:DI 100)
+                        (reg/f:DI 7 sp)
+                    ] UNSPEC_TLSDESC))
+            (clobber (reg:CC 17 flags))
+        ]) "x.c":7:16 1676 {*tls_dynamic_gnu2_call_64_di}
+     (expr_list:REG_DEAD (reg:DI 100)
+        (expr_list:REG_UNUSED (reg:CC 17 flags)
+            (nil))))
+
+and
+
+(insn 19 17 20 4 (set (reg:DI 104)
+        (unspec:DI [
+                (symbol_ref:DI ("caml_state") [flags 0x10]  <var_decl 
0x7fe10e1d9e40 caml_state>)
+            ] UNSPEC_TLSDESC)) "x.c":6:10 discrim 1 1674 
{*tls_dynamic_gnu2_lea_64_di}
+     (nil))
+(insn 20 19 21 4 (parallel [
+            (set (reg:DI 103)
+                (unspec:DI [
+                        (symbol_ref:DI ("caml_state") [flags 0x10]  <var_decl 
0x7fe10e1d9e40 caml_state>)
+                        (reg:DI 104)
+                        (reg/f:DI 7 sp)
+                    ] UNSPEC_TLSDESC))
+            (clobber (reg:CC 17 flags))
+        ]) "x.c":6:10 discrim 1 1676 {*tls_dynamic_gnu2_call_64_di}
+     (expr_list:REG_DEAD (reg:DI 104)
+        (expr_list:REG_UNUSED (reg:CC 17 flags)
+            (nil))))
+
+are the same even though rtx_equal_p returns false since (reg:DI 100)
+and (reg:DI 104) are set from the same symbol.  Use the UNSPEC_TLSDESC
+symbol
+
+(unspec:DI [(symbol_ref:DI ("caml_state") [flags 0x10])] UNSPEC_TLSDESC))
+
+to check if 2 TLS_CALL patterns have the same source.
+
+For TLS64_COMBINE, use both UNSPEC_TLSDESC and UNSPEC_DTPOFF unspecs to
+check if 2 TLS64_COMBINE patterns have the same source.
+
+gcc/
+
+       PR target/121694
+       * config/i386/i386-features.cc (redundant_pattern): Add
+       tlsdesc_val.
+       (pass_x86_cse): Likewise.
+       ((pass_x86_cse::tls_set_insn_from_symbol): New member function.
+       (pass_x86_cse::candidate_gnu2_tls_p): Set tlsdesc_val.  For
+       TLS64_COMBINE, match both UNSPEC_TLSDESC and UNSPEC_DTPOFF
+       symbols.  For TLS64_CALL, match the UNSPEC_TLSDESC sumbol.
+       (pass_x86_cse::x86_cse): Initialize the tlsdesc_val field in
+       load.  Pass the tlsdesc_val field to ix86_place_single_tls_call
+       for X86_CSE_TLSDESC.
+
+gcc/testsuite/
+
+       PR target/121694
+       * gcc.target/i386/pr121668-1b.c: New test.
+       * gcc.target/i386/pr121694-1a.c: Likewise.
+       * gcc.target/i386/pr121694-1b.c: Likewise.
+
+Signed-off-by: H.J. Lu <[email protected]>
+---
+ gcc/config/i386/i386-features.cc            | 201 ++++++++++++--------
+ gcc/testsuite/gcc.target/i386/pr121668-1b.c |   6 +
+ gcc/testsuite/gcc.target/i386/pr121694-1a.c |  19 ++
+ gcc/testsuite/gcc.target/i386/pr121694-1b.c |   6 +
+ 4 files changed, 154 insertions(+), 78 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.target/i386/pr121668-1b.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/pr121694-1a.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/pr121694-1b.c
+
+diff --git a/gcc/config/i386/i386-features.cc 
b/gcc/config/i386/i386-features.cc
+index 93e20947edf3..5440a02c442b 100644
+--- a/gcc/config/i386/i386-features.cc
++++ b/gcc/config/i386/i386-features.cc
+@@ -3103,6 +3103,8 @@ struct redundant_pattern
+   auto_bitmap insns;
+   /* The broadcast inner scalar.  */
+   rtx val;
++  /* The actual redundant source value for UNSPEC_TLSDESC.  */
++  rtx tlsdesc_val;
+   /* The inner scalar mode.  */
+   machine_mode mode;
+   /* The instruction which sets the inner scalar.  Nullptr if the inner
+@@ -4155,6 +4157,8 @@ public:
+ private:
+   /* The redundant source value.  */
+   rtx val;
++  /* The actual redundant source value for UNSPEC_TLSDESC.  */
++  rtx tlsdesc_val;
+   /* The instruction which defines the redundant value.  */
+   rtx_insn *def_insn;
+   /* Mode of the destination of the candidate redundant instruction.  */
+@@ -4168,8 +4172,36 @@ private:
+   bool candidate_gnu_tls_p (rtx_insn *, attr_tls64);
+   bool candidate_gnu2_tls_p (rtx, attr_tls64);
+   bool candidate_vector_p (rtx);
++  rtx_insn *tls_set_insn_from_symbol (const_rtx, const_rtx);
+ }; // class pass_x86_cse
+ 
++/* Return the instruction which sets REG from TLS_SYMBOL.  */
++
++rtx_insn *
++pass_x86_cse::tls_set_insn_from_symbol (const_rtx reg,
++                                      const_rtx tls_symbol)
++{
++  rtx_insn *set_insn = nullptr;
++  for (df_ref ref = DF_REG_DEF_CHAIN (REGNO (reg));
++       ref;
++       ref = DF_REF_NEXT_REG (ref))
++    {
++      if (DF_REF_IS_ARTIFICIAL (ref))
++      return nullptr;
++
++      set_insn = DF_REF_INSN (ref);
++      if (get_attr_tls64 (set_insn) != TLS64_LEA)
++      return nullptr;
++
++      rtx tls_set = PATTERN (set_insn);
++      rtx tls_src = XVECEXP (SET_SRC (tls_set), 0, 0);
++      if (!rtx_equal_p (tls_symbol, tls_src))
++      return nullptr;
++    }
++
++  return set_insn;
++}
++
+ /* Return true and output def_insn, val, mode, scalar_mode and kind if
+    INSN is UNSPEC_TLS_GD or UNSPEC_TLS_LD_BASE.  */
+ 
+@@ -4226,29 +4258,71 @@ pass_x86_cse::candidate_gnu2_tls_p (rtx set, 
attr_tls64 tls64)
+   if (!TARGET_64BIT || !cfun->machine->tls_descriptor_call_multiple_p)
+     return false;
+ 
+-  /* Record GNU2 TLS CALLs for 64-bit:
+-
+-     (set (reg/f:DI 104)
+-        (plus:DI (unspec:DI [
+-                    (symbol_ref:DI ("_TLS_MODULE_BASE_") [flags 0x10])
+-                    (reg:DI 114)
+-                    (reg/f:DI 7 sp)] UNSPEC_TLSDESC)
+-                 (const:DI (unspec:DI [
+-                              (symbol_ref:DI ("e") [flags 0x1a])
+-                           ] UNSPEC_DTPOFF))))
+-
+-     (set (reg/f:DI 104)
+-        (plus:DI (unspec:DI [
+-                    (symbol_ref:DI ("_TLS_MODULE_BASE_") [flags 0x10])
+-                    (unspec:DI [
+-                       (symbol_ref:DI ("_TLS_MODULE_BASE_") [flags 0x10])
+-                    ] UNSPEC_TLSDESC)
+-                    (reg/f:DI 7 sp)] UNSPEC_TLSDESC)
+-                 (const:DI (unspec:DI [
+-                              (symbol_ref:DI ("e") [flags 0x1a])
+-                           ] UNSPEC_DTPOFF))))
++  rtx tls_symbol;
++  rtx_insn *set_insn;
++  rtx src = SET_SRC (set);
++  val = src;
++  tlsdesc_val = src;
++  kind = X86_CSE_TLSDESC;
+ 
+-     and
++  if (tls64 == TLS64_COMBINE)
++    {
++      /* Record 64-bit TLS64_COMBINE:
++
++       (set (reg/f:DI 104)
++            (plus:DI (unspec:DI [
++                        (symbol_ref:DI ("_TLS_MODULE_BASE_") [flags 0x10])
++                        (reg:DI 114)
++                        (reg/f:DI 7 sp)] UNSPEC_TLSDESC)
++                     (const:DI (unspec:DI [
++                                  (symbol_ref:DI ("e") [flags 0x1a])
++                                ] UNSPEC_DTPOFF))))
++
++       (set (reg/f:DI 104)
++            (plus:DI (unspec:DI [
++                        (symbol_ref:DI ("_TLS_MODULE_BASE_") [flags 0x10])
++                        (unspec:DI [
++                           (symbol_ref:DI ("_TLS_MODULE_BASE_") [flags 0x10])
++                        ] UNSPEC_TLSDESC)
++                        (reg/f:DI 7 sp)] UNSPEC_TLSDESC)
++                     (const:DI (unspec:DI [
++                                  (symbol_ref:DI ("e") [flags 0x1a])
++                               ] UNSPEC_DTPOFF))))
++     */
++
++      scalar_mode = mode = GET_MODE (src);
++      rtx src0 = XEXP (src, 0);
++      tls_symbol = XVECEXP (src0, 0, 0);
++      rtx src1 = XVECEXP (src0, 0, 1);
++      if (REG_P (src1))
++      {
++        set_insn = tls_set_insn_from_symbol (src1, tls_symbol);
++        gcc_assert (set_insn);
++      }
++      else
++      {
++        set_insn = nullptr;
++        gcc_assert (GET_CODE (src1) == UNSPEC
++                    && XINT (src1, 1) == UNSPEC_TLSDESC
++                    && SYMBOL_REF_P (XVECEXP (src1, 0, 0))
++                    && rtx_equal_p (XVECEXP (src1, 0, 0), tls_symbol));
++      }
++
++      /* Use TLS_SYMBOL and
++
++       (const:DI (unspec:DI [
++                    (symbol_ref:DI ("e") [flags 0x1a])
++                 ] UNSPEC_DTPOFF))
++
++       as VAL to check if 2 patterns have the same source.  */
++
++      rtvec vec = gen_rtvec (2, tls_symbol, XEXP (src, 1));
++      val = gen_rtx_UNSPEC (mode, vec, UNSPEC_TLSDESC);
++      def_insn = set_insn;
++      return true;
++    }
++
++  /* Record 64-bit TLS_CALL:
+ 
+      (set (reg:DI 101)
+         (unspec:DI [(symbol_ref:DI ("foo") [flags 0x50])
+@@ -4257,70 +4331,33 @@ pass_x86_cse::candidate_gnu2_tls_p (rtx set, 
attr_tls64 tls64)
+ 
+    */
+ 
+-  rtx src = SET_SRC (set);
+-  val = src;
+-  if (tls64 != TLS64_CALL)
+-    src = XEXP (src, 0);
+-
+-  kind = X86_CSE_TLSDESC;
+   gcc_assert (GET_CODE (src) == UNSPEC);
+-  rtx tls_symbol = XVECEXP (src, 0, 0);
++  tls_symbol = XVECEXP (src, 0, 0);
+   src = XVECEXP (src, 0, 1);
+   scalar_mode = mode = GET_MODE (src);
+-  if (REG_P (src))
+-    {
+-      /* All definitions of reg:DI 129 in
+-
+-       (set (reg:DI 110)
+-            (unspec:DI [(symbol_ref:DI ("foo"))
+-                        (reg:DI 129)
+-                        (reg/f:DI 7 sp)] UNSPEC_TLSDESC))
+-
+-       should have the same source as in
++  gcc_assert (REG_P (src));
+ 
+-       (set (reg:DI 129)
+-            (unspec:DI [(symbol_ref:DI ("foo"))] UNSPEC_TLSDESC))
++  /* All definitions of reg:DI 129 in
+ 
+-       */
++     (set (reg:DI 110)
++        (unspec:DI [(symbol_ref:DI ("foo"))
++                    (reg:DI 129)
++                    (reg/f:DI 7 sp)] UNSPEC_TLSDESC))
+ 
+-      df_ref ref;
+-      rtx_insn *set_insn = nullptr;
+-      for (ref = DF_REG_DEF_CHAIN (REGNO (src));
+-         ref;
+-         ref = DF_REF_NEXT_REG (ref))
+-      {
+-        if (DF_REF_IS_ARTIFICIAL (ref))
+-          break;
++     should have the same source as in
+ 
+-        set_insn = DF_REF_INSN (ref);
+-        tls64 = get_attr_tls64 (set_insn);
+-        if (tls64 != TLS64_LEA)
+-          {
+-            set_insn = nullptr;
+-            break;
+-          }
++     (set (reg:DI 129)
++        (unspec:DI [(symbol_ref:DI ("foo"))] UNSPEC_TLSDESC))
+ 
+-        rtx tls_set = PATTERN (set_insn);
+-        rtx tls_src = XVECEXP (SET_SRC (tls_set), 0, 0);
+-        if (!rtx_equal_p (tls_symbol, tls_src))
+-          {
+-            set_insn = nullptr;
+-            break;
+-          }
+-      }
+-
+-      if (!set_insn)
+-      return false;
++   */
+ 
+-      def_insn = set_insn;
+-    }
+-  else if (GET_CODE (src) == UNSPEC
+-         && XINT (src, 1) == UNSPEC_TLSDESC
+-         && SYMBOL_REF_P (XVECEXP (src, 0, 0)))
+-    def_insn = nullptr;
+-  else
+-    gcc_unreachable ();
++  set_insn = tls_set_insn_from_symbol (src, tls_symbol);
++  if (!set_insn)
++    return false;
+ 
++  /* Use TLS_SYMBOL as VAL to check if 2 patterns have the same source.  */
++  val = tls_symbol;
++  def_insn = set_insn;
+   return true;
+ }
+ 
+@@ -4395,6 +4432,8 @@ pass_x86_cse::x86_cse (void)
+         if (!set && !CALL_P (insn))
+           continue;
+ 
++        tlsdesc_val = nullptr;
++
+         attr_tls64 tls64 = get_attr_tls64 (insn);
+         switch (tls64)
+           {
+@@ -4466,6 +4505,10 @@ pass_x86_cse::x86_cse (void)
+         load = new redundant_pattern;
+ 
+         load->val = copy_rtx (val);
++        if (tlsdesc_val)
++          load->tlsdesc_val = copy_rtx (tlsdesc_val);
++        else
++          load->tlsdesc_val = nullptr;
+         load->mode = scalar_mode;
+         load->size = GET_MODE_SIZE (mode);
+         load->def_insn = def_insn;
+@@ -4560,7 +4603,7 @@ pass_x86_cse::x86_cse (void)
+               {
+               case X86_CSE_TLSDESC:
+                 ix86_place_single_tls_call (load->broadcast_reg,
+-                                            load->val,
++                                            load->tlsdesc_val,
+                                             load->kind,
+                                             load->bbs,
+                                             updated_gnu_tls_insns,
+@@ -4606,7 +4649,9 @@ pass_x86_cse::x86_cse (void)
+               case X86_CSE_TLS_LD_BASE:
+               case X86_CSE_TLSDESC:
+                 ix86_place_single_tls_call (load->broadcast_reg,
+-                                            load->val,
++                                            (load->kind == X86_CSE_TLSDESC
++                                             ? load->tlsdesc_val
++                                             : load->val),
+                                             load->kind,
+                                             load->bbs,
+                                             updated_gnu_tls_insns,
+diff --git a/gcc/testsuite/gcc.target/i386/pr121668-1b.c 
b/gcc/testsuite/gcc.target/i386/pr121668-1b.c
+new file mode 100644
+index 000000000000..54a277506f83
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/pr121668-1b.c
+@@ -0,0 +1,6 @@
++/* { dg-do compile { target *-*-linux* } } */
++/* { dg-options "-Og -g -fpic -fplt -mtls-dialect=gnu2" } */
++
++#include "pr121668-1a.c"
++
++/* { dg-final { scan-assembler-times "call\[ 
\t\]\\*caml_state@TLSCALL\\(%(?:r|e)ax\\)" 1 { target { ! ia32 } } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/pr121694-1a.c 
b/gcc/testsuite/gcc.target/i386/pr121694-1a.c
+new file mode 100644
+index 000000000000..af9c65701341
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/pr121694-1a.c
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target *-*-linux* } } */
++/* { dg-options "-Og -fpic -fplt -mtls-dialect=gnu" } */
++
++extern void func1 (long *);
++extern int func2 (void);
++extern void func3 (void);
++static __thread long foo;
++static __thread long bar;
++long
++func (void)
++{
++  func1 (&foo);
++  func1 (&bar);
++  if (func2 ())
++    func3 ();
++  return foo + bar;
++}
++
++/* { dg-final { scan-assembler-times "call\[ \t\]__tls_get_addr@PLT" 1 { 
target { ! ia32 } } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/pr121694-1b.c 
b/gcc/testsuite/gcc.target/i386/pr121694-1b.c
+new file mode 100644
+index 000000000000..76ebbf7e90bd
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/pr121694-1b.c
+@@ -0,0 +1,6 @@
++/* { dg-do compile { target *-*-linux* } } */
++/* { dg-options "-Og -fpic -fplt -mtls-dialect=gnu2" } */
++
++#include "pr121694-1a.c"
++
++/* { dg-final { scan-assembler-times "call\[ 
\t\]\\*_TLS_MODULE_BASE_@TLSCALL\\(%(?:r|e)ax\\)" 1 { target { ! ia32 } } } } */
+
+base-commit: 6aa1cbb140bba220439d839207a23f09222c99df
+-- 
+2.51.0
+

diff --git a/16.0.0/gentoo/README.history b/16.0.0/gentoo/README.history
index a98dbcb..d0980b2 100644
--- a/16.0.0/gentoo/README.history
+++ b/16.0.0/gentoo/README.history
@@ -1,7 +1,7 @@
 13     ????
 
        U 86_all_PR120933-i386-default-to-mtls-dialect-gnu2-if-appropriate.patch
-       + 88_all-x86-64-Better-compare-source-operands-of-tls_dynamic.patch
+       + 88_all-x86-64-Improve-source-operand-check-for-TLS_CALL.patch
 
 12     24 August 2025
 

Reply via email to