commit: 9d05dcbe0d03e364397647c8e06d4d3827ec65b7 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Sat Aug 16 23:06:10 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Sat Aug 16 23:06:36 2025 +0000 URL: https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=9d05dcbe
16.0.0: add TLS patch Bug: https://gcc.gnu.org/PR121572 Signed-off-by: Sam James <sam <AT> gentoo.org> ...he-TLS-call-before-all-FLAGS_REG-setting-.patch | 202 +++++++++++++++++++++ 16.0.0/gentoo/README.history | 4 + 2 files changed, 206 insertions(+) diff --git a/16.0.0/gentoo/86_all_PR121572_x86-Place-the-TLS-call-before-all-FLAGS_REG-setting-.patch b/16.0.0/gentoo/86_all_PR121572_x86-Place-the-TLS-call-before-all-FLAGS_REG-setting-.patch new file mode 100644 index 0000000..62ccbe9 --- /dev/null +++ b/16.0.0/gentoo/86_all_PR121572_x86-Place-the-TLS-call-before-all-FLAGS_REG-setting-.patch @@ -0,0 +1,202 @@ +https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121572#c4 + +From caceadf47fe1b278311c73d5cbd062dca62298ac Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" <[email protected]> +Date: Sat, 16 Aug 2025 14:04:33 -0700 +Subject: [PATCH] x86: Place the TLS call before all FLAGS_REG setting BBs + +We can't place a TLS call before a conditional jump in a basic block like + +(code_label 13 11 14 4 2 (nil) [1 uses]) +(note 14 13 16 4 [bb 4] NOTE_INSN_BASIC_BLOCK) +(jump_insn 16 14 17 4 (set (pc) + (if_then_else (le (reg:CCNO 17 flags) + (const_int 0 [0])) + (label_ref 27) + (pc))) "x.c":10:21 discrim 1 1462 {*jcc} + (expr_list:REG_DEAD (reg:CCNO 17 flags) + (int_list:REG_BR_PROB 628353713 (nil))) + -> 27) + +since the TLS call will clobber flags register. Instead, we should place +such call before all register setting basic blocks which dominate the +current basic block. + +NB: GNU2 TLS: + +(insn 66 2 5 2 (parallel [ + (set (reg:DI 116) + (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 ("tv_cache") [flags 0x5a]) + ] UNSPEC_DTPOFF)))) + (clobber (reg:CC 17 flags))]) 1678 {*tls_dynamic_gnu2_combine_64_di} + (nil)) + +only clobbers flags register. + +gcc/ + + PR target/121572 + * config/i386/i386-features.cc (ix86_place_single_tls_call): Also + search for REG_DEAD notes if flag register is alive. Place the + TLS call before all FLAGS_REG setting BBs for conditional jump. + +gcc/testsuite/ + + PR target/121572 + * gcc.target/i386/pr121572-1a.c: New test. + * gcc.target/i386/pr121572-1b.c: Likewise. + +Signed-off-by: H.J. Lu <[email protected]> +--- + gcc/config/i386/i386-features.cc | 41 ++++++++++++++++++++- + gcc/testsuite/gcc.target/i386/pr121572-1a.c | 40 ++++++++++++++++++++ + gcc/testsuite/gcc.target/i386/pr121572-1b.c | 18 +++++++++ + 3 files changed, 98 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/i386/pr121572-1a.c + create mode 100644 gcc/testsuite/gcc.target/i386/pr121572-1b.c + +diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc +index f0bdc5c1880..7cdf98c5778 100644 +--- a/gcc/config/i386/i386-features.cc ++++ b/gcc/config/i386/i386-features.cc +@@ -3748,6 +3748,7 @@ ix86_place_single_tls_call (rtx dest, rtx val, x86_cse_kind kind, + bb = get_immediate_dominator (CDI_DOMINATORS, + bb->loop_father->header); + ++place_tls_call: + rtx_insn *insn = BB_HEAD (bb); + while (insn && !NONDEBUG_INSN_P (insn)) + { +@@ -3837,7 +3838,7 @@ ix86_place_single_tls_call (rtx dest, rtx val, x86_cse_kind kind, + && bitmap_bit_p (in, i)) + bitmap_set_bit (live_caller_saved_regs, i); + +- if (!bitmap_empty_p (live_caller_saved_regs)) ++ if (flags_live_p || !bitmap_empty_p (live_caller_saved_regs)) + { + /* Search for REG_DEAD notes in this basic block. */ + FOR_BB_INSNS (bb, insn) +@@ -3845,6 +3846,44 @@ ix86_place_single_tls_call (rtx dest, rtx val, x86_cse_kind kind, + if (!NONDEBUG_INSN_P (insn)) + continue; + ++ if (JUMP_P (insn)) ++ { ++ /* This must be a conditional jump. */ ++ rtx label = JUMP_LABEL (insn); ++ if (label == nullptr ++ || ANY_RETURN_P (label) ++ || !(LABEL_P (label) || SYMBOL_REF_P (label))) ++ gcc_unreachable (); ++ ++ rtx_insn *set_insn; ++ basic_block set_bb; ++ auto_bitmap set_bbs; ++ ++ /* Get all BBs which define FLAGS_REG and dominate the ++ current BB from all DEFs of FLAGS_REG. */ ++ for (df_ref def = DF_REG_DEF_CHAIN (FLAGS_REG); ++ def; ++ def = DF_REF_NEXT_REG (def)) ++ if (!DF_REF_IS_ARTIFICIAL (def) ++ && !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER) ++ && !DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER)) ++ { ++ set_insn = DF_REF_INSN (def); ++ set = single_set (set_insn); ++ gcc_assert (set); ++ set_bb = DF_REF_BB (def); ++ if (dominated_by_p (CDI_DOMINATORS, bb, set_bb)) ++ bitmap_set_bit (set_bbs, set_bb->index); ++ } ++ ++ /* Place the call before all FLAGS_REG setting BBs since ++ we can't place a call before nor after a conditional ++ jump. */ ++ bb = nearest_common_dominator_for_set (CDI_DOMINATORS, ++ set_bbs); ++ goto place_tls_call; ++ } ++ + /* Check if FLAGS register is live. */ + set = single_set (insn); + if (set) +diff --git a/gcc/testsuite/gcc.target/i386/pr121572-1a.c b/gcc/testsuite/gcc.target/i386/pr121572-1a.c +new file mode 100644 +index 00000000000..179a1a9e66c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/pr121572-1a.c +@@ -0,0 +1,40 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O0 -fpic -fplt -mtls-dialect=gnu" } */ ++/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ ++/* { dg-final { check-function-bodies "**" "" "" { target { ! ia32 } } {^\t?\.} } } */ ++ ++/* ++**bug: ++**.LFB[0-9]+: ++**... ++** leaq tv_cache@tlsld\(%rip\), %rdi ++** call __tls_get_addr@PLT ++** movl \$-1, %edi ++** mov[l|q] %[e|r]ax, %[e|r]bx ++** call val@PLT ++**... ++*/ ++ ++extern __thread int tv_cache __attribute__ ((visibility("hidden"))); ++extern void use_cache (int); ++extern int val (int v); ++ ++__attribute__((optimize(2))) ++void ++bug (void) ++{ ++ int compared = val(-1); ++ ++ if (compared == 0 || (compared > 0 && val(2) == 0)) ++ { ++ __builtin_trap(); ++ } ++ ++ if (compared < 0) { ++ use_cache(tv_cache); ++ return; ++ } ++ ++ use_cache(tv_cache); ++ __builtin_trap(); ++} +diff --git a/gcc/testsuite/gcc.target/i386/pr121572-1b.c b/gcc/testsuite/gcc.target/i386/pr121572-1b.c +new file mode 100644 +index 00000000000..8a6089109f5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/pr121572-1b.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O0 -fpic -fplt -mtls-dialect=gnu2" } */ ++/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ ++/* { dg-final { check-function-bodies "**" "" "" { target { ! ia32 } } {^\t?\.} } } */ ++ ++/* ++**bug: ++**.LFB[0-9]+: ++**... ++** lea[l|q] tv_cache@TLSDESC\(%rip\), %[e|r]ax ++** movl \$-1, %edi ++** call \*tv_cache@TLSCALL\(%[e|r]ax\) ++** mov[l|q] %[e|r]ax, %[e|r]bx ++** call val@PLT ++**... ++*/ ++ ++#include "pr121572-1a.c" +-- +2.50.1 diff --git a/16.0.0/gentoo/README.history b/16.0.0/gentoo/README.history index 4c3a42a..64aa256 100644 --- a/16.0.0/gentoo/README.history +++ b/16.0.0/gentoo/README.history @@ -1,3 +1,7 @@ +10 ??? + + + 86_all_PR121572_x86-Place-the-TLS-call-before-all-FLAGS_REG-setting-.patch + 9 5 August 2025 - 86_all_PR121190-vect-Fix-insufficient-alignment-requirement-for-spec.patch
