> This is OK for trunk if you don't hear otherwise from Honza until the > end of this week.
Thanks, Richard. I haven't seen any further comments on V2, so I plan to push it to trunk on Wednesday, September 16. Longjun Richard Biener <[email protected]> 于2026年9月8日周二 17:16写道: > > On Fri, 21 Aug 2026, Longjun Luo wrote: > > > Since r167795, cfgexpand has resolved a function's section before RTL > > expansion. r168624 added resolve_unique_section to the direct thunk > > emission path, when thunks were still emitted directly as assembly. When > > r202592 added a GIMPLE thunk path, the call was retained in both paths. The > > direct assembler path still needs it, but the GIMPLE path later reaches > > cfgexpand, so its call is redundant. > > > > It can also be too early. IPA ICF can turn equivalent functions whose > > addresses matter into GIMPLE wrappers during WPA, before LTO privatizes > > their > > assembler names. The early call records a section based on the old name, > > and that stale section is streamed into LTRANS. IPA strub has the same > > problem in the GIMPLE wrapper code added in r14-6201. > > > > Remove the early calls for GIMPLE wrappers and let cfgexpand resolve their > > sections from the final assembler names. Keep the call for directly emitted > > assembler thunks; during LTO output it is reached only after privatization. > > Explicit and deliberately inherited section names remain unchanged. This > > fixes the stale name at its source instead of discarding an already-resolved > > section only when LTO privatizes a symbol. > > > > Bootstrapped and regression-tested on x86_64-pc-linux-gnu (C and C++ only), > > with no new failures. Both new tests fail without the change and pass with > > it. The complete gcc.dg/lto and g++.dg/lto suites, the strub tests, and > > g++.dg/other/pr47218* have no unexpected results. > > This is OK for trunk if you don't hear otherwise from Honza until the > end of this week. > > Thanks, > Richard. > > > PR lto/126841 > > > > gcc/ChangeLog: > > > > * doc/invoke.texi (-ffunction-sections): Document implicit function > > section names under LTO. > > * ipa-strub.cc (pass_ipa_strub::execute): Let cfgexpand resolve the > > GIMPLE wrapper section. > > * symtab-thunks.cc (expand_thunk): Likewise for generic GIMPLE thunks. > > Clarify the direct-assembler case. > > > > gcc/testsuite/ChangeLog: > > > > * gcc.dg/lto/pr126841-strub_0.c: New test. > > * gcc.dg/lto/pr126841-strub_1.c: New test. > > * gcc.dg/lto/pr126841_0.c: New test. > > * gcc.dg/lto/pr126841_1.c: New test. > > * gcc.dg/lto/pr126841_2.c: New test. > > * gcc.dg/lto/pr126841_3.c: New test. > > > > Signed-off-by: Longjun Luo <[email protected]> > > --- > > Changes in v2: > > - Fix the premature section resolution at the GIMPLE-wrapper construction > > sites instead of changing LTO streaming. > > - Cover the same issue in IPA strub with an independent regression test. > > - Narrow the documentation to implicit function sections and retain the > > exception for deliberate co-location. > > > > I tried the suggested lto_output_node approach. It needs exceptions for > > thunks and former thunks that deliberately inherit a section. Aliases are > > another issue because they have no body of their own to pass through > > cfgexpand. Removing the premature calls is narrower: these GIMPLE wrappers > > already pass through cfgexpand, while directly emitted assembler thunks > > retain their output-time call. This forgoes the possible reduction in > > streaming size, but avoids changing established section relationships. > > > > For functions that are not deliberately co-located, keeping one section per > > function matches the documented -ffunction-sections behavior. Here the > > final > > lto_priv names already provide the disambiguation discussed in comment #6; > > resolving from the pre-privatization name instead silently puts distinct > > functions in one section. > > > > I also compared explicit-section ICF and strub cases before and after the > > change; their LTRANS assembly is unchanged. The updated manual also builds > > successfully with makeinfo. > > > > gcc/doc/invoke.texi | 6 ++++++ > > gcc/ipa-strub.cc | 4 ---- > > gcc/symtab-thunks.cc | 7 ++----- > > gcc/testsuite/gcc.dg/lto/pr126841-strub_0.c | 21 ++++++++++++++++++++ > > gcc/testsuite/gcc.dg/lto/pr126841-strub_1.c | 7 +++++++ > > gcc/testsuite/gcc.dg/lto/pr126841_0.c | 22 +++++++++++++++++++++ > > gcc/testsuite/gcc.dg/lto/pr126841_1.c | 7 +++++++ > > gcc/testsuite/gcc.dg/lto/pr126841_2.c | 7 +++++++ > > gcc/testsuite/gcc.dg/lto/pr126841_3.c | 5 +++++ > > 9 files changed, 77 insertions(+), 9 deletions(-) > > create mode 100644 gcc/testsuite/gcc.dg/lto/pr126841-strub_0.c > > create mode 100644 gcc/testsuite/gcc.dg/lto/pr126841-strub_1.c > > create mode 100644 gcc/testsuite/gcc.dg/lto/pr126841_0.c > > create mode 100644 gcc/testsuite/gcc.dg/lto/pr126841_1.c > > create mode 100644 gcc/testsuite/gcc.dg/lto/pr126841_2.c > > create mode 100644 gcc/testsuite/gcc.dg/lto/pr126841_3.c > > > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > > index 01925ecf30d..ed341e88f48 100644 > > --- a/gcc/doc/invoke.texi > > +++ b/gcc/doc/invoke.texi > > @@ -16927,6 +16927,12 @@ file if the target supports arbitrary sections. > > The name of the > > function or the name of the data item determines the section's name > > in the output file. > > > > +With link-time optimization, an implicitly generated function section name > > is > > +derived from the final assembler name unless the compiler deliberately > > places > > +related functions, such as a thunk and its target, in the same section. > > The > > +final assembler name may include a compiler-generated suffix that > > distinguishes > > +identically named internal-linkage items from different translation units. > > + > > Use these options on systems where the linker can perform optimizations to > > improve locality of reference in the instruction space. Most systems > > using the > > ELF object format have linkers with such optimizations. On AIX, the linker > > diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc > > index b0156fe46f6..118c4a08082 100644 > > --- a/gcc/ipa-strub.cc > > +++ b/gcc/ipa-strub.cc > > @@ -3124,10 +3124,6 @@ pass_ipa_strub::execute (function *) > > > > current_function_decl = thunk_fndecl; > > > > - /* Ensure thunks are emitted in their correct sections. */ > > - resolve_unique_section (thunk_fndecl, 0, > > - flag_function_sections); > > - > > bitmap_obstack_initialize (NULL); > > > > /* Build the return declaration for the function. */ > > diff --git a/gcc/symtab-thunks.cc b/gcc/symtab-thunks.cc > > index fb4ff87c988..e0a8d5e9357 100644 > > --- a/gcc/symtab-thunks.cc > > +++ b/gcc/symtab-thunks.cc > > @@ -363,7 +363,8 @@ expand_thunk (cgraph_node *node, bool output_asm_thunks, > > > > current_function_decl = thunk_fndecl; > > > > - /* Ensure thunks are emitted in their correct sections. */ > > + /* This thunk is emitted directly and bypasses cfgexpand, so resolve > > + its section here. */ > > resolve_unique_section (thunk_fndecl, 0, > > flag_function_sections); > > > > @@ -432,10 +433,6 @@ expand_thunk (cgraph_node *node, bool > > output_asm_thunks, > > > > current_function_decl = thunk_fndecl; > > > > - /* Ensure thunks are emitted in their correct sections. */ > > - resolve_unique_section (thunk_fndecl, 0, > > - flag_function_sections); > > - > > bitmap_obstack_initialize (NULL); > > > > if (info->virtual_offset_p) > > diff --git a/gcc/testsuite/gcc.dg/lto/pr126841-strub_0.c > > b/gcc/testsuite/gcc.dg/lto/pr126841-strub_0.c > > new file mode 100644 > > index 00000000000..bd8e628ade5 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/lto/pr126841-strub_0.c > > @@ -0,0 +1,21 @@ > > +/* { dg-lto-do link } */ > > +/* { dg-require-effective-target elf } */ > > +/* { dg-require-effective-target named_sections } */ > > +/* { dg-require-effective-target fpic } */ > > +/* { dg-require-effective-target shared } */ > > +/* { dg-require-effective-target strub } */ > > +/* { dg-require-linker-plugin "" } */ > > +/* { dg-lto-options { { -O2 -flto -fPIC -shared -ffunction-sections > > -save-temps -fstrub=all -fno-ipa-icf } } } */ > > + > > +static int > > +same_fn (int x) > > +{ > > + return x * 33 + 7; > > +} > > + > > +int (*a_callback) (int) = same_fn; > > + > > +/* The strub wrappers must use sections derived from their privatized > > + assembler names. */ > > +/* { dg-final { scan-lto-assembler {\.section[ > > \t]+\.text\.same_fn\.lto_priv\.0[, \t"]} } } */ > > +/* { dg-final { scan-lto-assembler {\.section[ > > \t]+\.text\.same_fn\.lto_priv\.1[, \t"]} } } */ > > diff --git a/gcc/testsuite/gcc.dg/lto/pr126841-strub_1.c > > b/gcc/testsuite/gcc.dg/lto/pr126841-strub_1.c > > new file mode 100644 > > index 00000000000..39356acba71 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/lto/pr126841-strub_1.c > > @@ -0,0 +1,7 @@ > > +static int > > +same_fn (int x) > > +{ > > + return x * 33 + 7; > > +} > > + > > +int (*b_callback) (int) = same_fn; > > diff --git a/gcc/testsuite/gcc.dg/lto/pr126841_0.c > > b/gcc/testsuite/gcc.dg/lto/pr126841_0.c > > new file mode 100644 > > index 00000000000..a0222d3336f > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/lto/pr126841_0.c > > @@ -0,0 +1,22 @@ > > +/* { dg-lto-do link } */ > > +/* { dg-require-effective-target elf } */ > > +/* { dg-require-effective-target named_sections } */ > > +/* { dg-require-effective-target fpic } */ > > +/* { dg-require-effective-target shared } */ > > +/* { dg-require-linker-plugin "" } */ > > +/* { dg-lto-options { { -O2 -flto -fPIC -shared -ffunction-sections > > -save-temps } } } */ > > + > > +static int > > +same_fn (int x) > > +{ > > + return x * 33 + 7; > > +} > > + > > +int (*a_callback) (int) = same_fn; > > + > > +/* The exported function keeps the unsuffixed section, and each privatized > > + function must have its own section. */ > > +/* { dg-final { scan-lto-assembler {\.section[ \t]+\.text\.same_fn[, \t"]} > > } } */ > > +/* { dg-final { scan-lto-assembler {\.section[ > > \t]+\.text\.same_fn\.lto_priv\.0[, \t"]} } } */ > > +/* { dg-final { scan-lto-assembler {\.section[ > > \t]+\.text\.same_fn\.lto_priv\.1[, \t"]} } } */ > > +/* { dg-final { scan-lto-assembler {\.section[ > > \t]+\.text\.same_fn\.lto_priv\.2[, \t"]} } } */ > > diff --git a/gcc/testsuite/gcc.dg/lto/pr126841_1.c > > b/gcc/testsuite/gcc.dg/lto/pr126841_1.c > > new file mode 100644 > > index 00000000000..39356acba71 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/lto/pr126841_1.c > > @@ -0,0 +1,7 @@ > > +static int > > +same_fn (int x) > > +{ > > + return x * 33 + 7; > > +} > > + > > +int (*b_callback) (int) = same_fn; > > diff --git a/gcc/testsuite/gcc.dg/lto/pr126841_2.c > > b/gcc/testsuite/gcc.dg/lto/pr126841_2.c > > new file mode 100644 > > index 00000000000..369eb1836a6 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/lto/pr126841_2.c > > @@ -0,0 +1,7 @@ > > +static int > > +same_fn (int x) > > +{ > > + return x * 33 + 7; > > +} > > + > > +int (*c_callback) (int) = same_fn; > > diff --git a/gcc/testsuite/gcc.dg/lto/pr126841_3.c > > b/gcc/testsuite/gcc.dg/lto/pr126841_3.c > > new file mode 100644 > > index 00000000000..567eb29cda0 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/lto/pr126841_3.c > > @@ -0,0 +1,5 @@ > > +int > > +same_fn (int x) > > +{ > > + return x - 1; > > +} > > > > -- > Richard Biener <[email protected]> > SUSE Software Solutions Germany GmbH, > Frankenstrasse 146, 90461 Nuernberg, Germany; > GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)
