mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
i386: Fix ICE with target_clones inlining
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.")
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.
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
This commit is contained in:
@@ -5629,7 +5629,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;
|
||||
|
||||
48
gcc/testsuite/gcc.target/i386/tct-ipa-inline-ice.c
Normal file
48
gcc/testsuite/gcc.target/i386/tct-ipa-inline-ice.c
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user