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
