[Bug ipa/85960] -fipa-pta and ifunc are incompatible
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed May 30 13:43:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85960
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |wrong-code
CC| |hubicka at gcc dot gnu.org
Version|unknown |8.1.1
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue seems to be that the multiver stuff is
multiver_test/35 (multiver_test) @0x7ff2d74c62e0
Type: function definition analyzed alias
Visibility: externally_visible public
References: resolve_multiver/34 (alias)
Referring:
Availability: overwritable
First run: 0
Function flags:
Called by: main/37 (955630223 (estimated locally),8.09 per call)
Calls:
resolve_multiver/34 (resolve_multiver) @0x7ff2d74c6170
Type: function definition analyzed
Visibility: prevailing_def_ironly
References: multiver_default/33 (addr)
Referring: multiver_test/35 (alias)
Availability: available
First run: 0
Function flags: count: 1073741826 (estimated locally) body nonfreeing_fn
Called by:
Calls:
multiver_default/33 (multiver_default) @0x7ff2d74c6000
Type: function definition analyzed
Visibility: prevailing_def_ironly
Address is taken.
References:
Referring: resolve_multiver/34 (addr)
Availability: available
First run: 0
Function flags: count: 1073741826 (estimated locally) body nonfreeing_fn hot
Called by:
Calls:
so multiver_test is an alias of resolve_multiver which means we get constraints
for resolve_multiver instead of the union of resolve_multiver and
multiver_default.
In IPA PTA we do
/* Build the constraints. */
FOR_EACH_DEFINED_FUNCTION (node)
{
...
node->call_for_symbol_thunks_and_aliases
(associate_varinfo_to_alias, vi, true);
where we "merge" aliases into the DEFINED copy. How we represent ifuncs wrecks
with this it seems. We use the resolve_multiver data for calls to
multiver_test. We probably can add a ifunc attribute lookup but IMHO
the cgraph representation is just bogus. It looks like the multiver_test
cgraph node has ifunc_resolver set to 1(!?) but resolve_multiver doesn't.
/* Set when symbol is an IFUNC resolver. */
unsigned ifunc_resolver : 1;
I expected resolve_multiver to be the IFUNC resolver.
So without actually understanding this mess the following "fixes" the issue:
Index: gcc/tree-ssa-structalias.c
===================================================================
--- gcc/tree-ssa-structalias.c (revision 260950)
+++ gcc/tree-ssa-structalias.c (working copy)
@@ -7713,7 +7713,8 @@ associate_varinfo_to_alias (struct cgrap
if ((node->alias
|| (node->thunk.thunk_p
&& ! node->global.inlined_to))
- && node->analyzed)
+ && node->analyzed
+ && !node->ifunc_resolver)
insert_vi_for_tree (node->decl, (varinfo_t)data);
return false;
}
My point is that multiver_test doesn't call resolve_multiver but it calls
one of the functions returned by the resolver.
So - a different fix from the above would handle this at the point
we generate constraints for the call to multiver_test and emit constraints
for fn = resolve_multiver (); (*fn) (args...). That looks needed because
if you make multiver_test static the constraints still look wrong. We still
need to avoid associating one decl with the other like above.
And we need to get the clobbers on the ifunc call correct...
Half-way patch where the points-to sets look good but the clobbers/uses are
still broken:
Index: gcc/tree-ssa-structalias.c
===================================================================
--- gcc/tree-ssa-structalias.c (revision 260950)
+++ gcc/tree-ssa-structalias.c (working copy)
@@ -3903,7 +3903,7 @@ get_function_part_constraint (varinfo_t
c.offset = 0;
c.type = SCALAR;
}
- else if (TREE_CODE (fi->decl) == FUNCTION_DECL)
+ else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL)
{
varinfo_t ai = first_vi_for_offset (fi, part);
if (ai)
@@ -4732,6 +4732,30 @@ find_func_aliases_for_call (struct funct
return;
fi = get_fi_for_callee (t);
+ /* First process an ifunc resolver if we run into one. */
+ if (fndecl)
+ {
+ cgraph_node *node = cgraph_node::get (fndecl);
+ if (node->ifunc_resolver)
+ {
+ fi = get_vi_for_tree (node->get_alias_target ()->decl);
+ if (fi->is_fn_info)
+ {
+ constraint_expr rhs
+ = get_function_part_constraint (fi, fi_result);
+ fi = new_var_info (NULL_TREE, "ifuncres", true);
+ fi->is_reg_var = true;
+ constraint_expr lhs;
+ lhs.type = SCALAR;
+ lhs.var = fi->id;
+ lhs.offset = 0;
+ process_constraint (new_constraint (lhs, rhs));
+ }
+ else
+ fi = get_varinfo (anything_id);
+ fndecl = NULL_TREE;
+ }
if (!in_ipa_mode
|| (fndecl && !fi->is_fn_info))
{
@@ -7713,7 +7737,8 @@ associate_varinfo_to_alias (struct cgrap
if ((node->alias
|| (node->thunk.thunk_p
&& ! node->global.inlined_to))
- && node->analyzed)
+ && node->analyzed
+ && !node->ifunc_resolver)
insert_vi_for_tree (node->decl, (varinfo_t)data);
return false;
}
More information about the Gcc-bugs
mailing list