On Tue, Mar 17, 2026 at 9:28 AM Yangyu Chen <[email protected]> wrote:
>
>
>
> On 17/3/2026 16:26, Uros Bizjak wrote:
> > On Tue, Mar 17, 2026 at 9:06 AM Yangyu Chen <[email protected]> wrote:
> >>
> >>
> >>
> >>> On 2 Mar 2026, at 15:09, Yangyu Chen <[email protected]> wrote:
> >>>
> >>> When a target_clones function is inlined, the resolver function's
> >>> assembler name must be properly registered in the symbol table.
> >>> Using SET_DECL_ASSEMBLER_NAME only updates the tree node without
> >>> notifying the symbol table, which can lead to an ICE during IPA
> >>> inlining when the assembler name hash becomes inconsistent.
> >>>
> >>> Replace SET_DECL_ASSEMBLER_NAME with symtab->change_decl_assembler_name
> >>> in make_resolver_func to properly update the symbol table's assembler
> >>> name mapping.
> >>>
> >>> This only happens on x86, other targets already uses
> >>> symtab->change_decl_assembler_name.
> >>>
> >>> Fixes: b500cd2634 ("x86: fmv: Refactor FMV name mangling.")
> >>> Signed-off-by: Yangyu Chen <[email protected]>
> >>>
> >>
> >> Ping.
> >
> > I have already OK'd this patch [1].
> >
> > [1] https://gcc.gnu.org/pipermail/gcc-patches/2026-March/709609.html
> >
> > Please also read [2], especially the second paragraph in the "Pinging
> > patches, Getting patches applied" chapter.
> >
> > [2] https://gcc.gnu.org/contribute.html
> >
>
> OK sorry. I don't have the write access to GCC. Could you help me commit
> it to trunk?
Pushed.
Thanks,
Uros.
>
> Thanks,
> Yangyu Chen
>
> > Uros.
> >
> >>
> >>> gcc/ChangeLog:
> >>>
> >>> * config/i386/i386-features.cc (make_resolver_func): Use
> >>> symtab->change_decl_assembler_name instead of
> >>> SET_DECL_ASSEMBLER_NAME to properly update the symbol table.
> >>>
> >>> gcc/testsuite/ChangeLog:
> >>>
> >>> * gcc.target/i386/tct-ipa-inline-ice.c: New test.
> >>> ---
> >>> To reproduce the ICE in the test, we need to allow inlining of
> >>> target_clones functions, just apply the following patch to c-attribs.cc:
> >>>
> >>> diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
> >>> index 10d9a51418e..8428e303f08 100644
> >>> --- a/gcc/c-family/c-attribs.cc
> >>> +++ b/gcc/c-family/c-attribs.cc
> >>> @@ -6439,9 +6439,6 @@ handle_target_clones_attribute (tree *node, tree
> >>> name, tree ARG_UNUSED (args),
> >>> "single %<target_clones%> attribute is ignored");
> >>> *no_add_attrs = true;
> >>> }
> >>> - else
> >>> - /* Do not inline functions with multiple clone targets. */
> >>> - DECL_UNINLINABLE (*node) = 1;
> >>> }
> >>> else
> >>> {
> >>>
> >>> ---
> >>> gcc/config/i386/i386-features.cc | 2 +-
> >>> .../gcc.target/i386/tct-ipa-inline-ice.c | 48 +++++++++++++++++++
> >>> 2 files changed, 49 insertions(+), 1 deletion(-)
> >>> create mode 100644 gcc/testsuite/gcc.target/i386/tct-ipa-inline-ice.c
> >>>
> >>> diff --git a/gcc/config/i386/i386-features.cc
> >>> b/gcc/config/i386/i386-features.cc
> >>> index 0e4fdcd2853..9200e0c076c 100644
> >>> --- a/gcc/config/i386/i386-features.cc
> >>> +++ b/gcc/config/i386/i386-features.cc
> >>> @@ -5601,7 +5601,7 @@ make_resolver_func (const tree default_decl,
> >>>
> >>> tree id = ix86_mangle_decl_assembler_name
> >>> (decl, node->function_version ()->assembler_name);
> >>> - SET_DECL_ASSEMBLER_NAME (decl, id);
> >>> + symtab->change_decl_assembler_name (decl, id);
> >>>
> >>> DECL_NAME (decl) = DECL_NAME (default_decl);
> >>> TREE_USED (decl) = 1;
> >>> diff --git a/gcc/testsuite/gcc.target/i386/tct-ipa-inline-ice.c
> >>> b/gcc/testsuite/gcc.target/i386/tct-ipa-inline-ice.c
> >>> new file mode 100644
> >>> index 00000000000..b8f77372e00
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.target/i386/tct-ipa-inline-ice.c
> >>> @@ -0,0 +1,48 @@
> >>> +/* Test function multiversioning and inlining of a function with a
> >>> + target_clones attribute. Note, we need to allow inlining of
> >>> + target_clones functions, see
> >>> + "Do not inline functions with multiple clone targets." in
> >>> c-attribs.cc,
> >>> + otherwise the test would not trigger the ICE. */
> >>> +/* { dg-do assemble } */
> >>> +/* { dg-require-ifunc "" } */
> >>> +/* { dg-options "-O3" } */
> >>> +
> >>> +struct range_state
> >>> +{
> >>> + unsigned int n;
> >>> + unsigned int s[58];
> >>> + unsigned int *q[58];
> >>> +};
> >>> +
> >>> +struct coder_state
> >>> +{
> >>> + struct range_state r;
> >>> + unsigned int t;
> >>> + unsigned int x[12];
> >>> +};
> >>> +
> >>> +inline void
> >>> +bar(struct range_state *r, unsigned int *ptr, unsigned int value)
> >>> +{
> >>> + r->s[r->n] = value;
> >>> + r->q[r->n] = ptr;
> >>> + ++r->n;
> >>> +}
> >>> +
> >>> +__attribute__((target_clones("default", "arch=x86-64-v2")))
> >>> +inline void
> >>> +foo(struct coder_state *c, unsigned int back)
> >>> +{
> >>> + if (back == ~0u) {
> >>> + bar(&c->r, &c->x[c->t], 0);
> >>> + }
> >>> +}
> >>> +
> >>> +__attribute__((target_clones("default", "arch=x86-64-v2")))
> >>> +int
> >>> +ice_trigger(struct coder_state *c, unsigned int back)
> >>> +{
> >>> + while (1) {
> >>> + foo(c, back);
> >>> + }
> >>> +}
> >>> --
> >>> 2.47.3
> >>
>
>