From: Richard Biener Date: Fri, 1 Jun 2018 08:20:08 +0000 (+0000) Subject: re PR ipa/85960 (-fipa-pta and ifunc are incompatible) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=07205c411f31eb5f433049461e0622f4681b2dca;p=gcc.git re PR ipa/85960 (-fipa-pta and ifunc are incompatible) 2018-06-01 Richard Biener PR ipa/85960 * tree-ssa-structalias.c (get_function_part_constraint): Handle NULL fi->decl. (find_func_aliases_for_call): Properly handle indirect fi from direct call. (find_func_clobbers): Likewise. (ipa_pta_execute): Likewise. (create_variable_info_for): For functions that are ifunc_resolver resolve to a varinfo that contains the result of the resolver call. (associate_varinfo_to_alias): Do not treat ifunc resolvers as aliases. * gcc.dg/ipa/ipa-pta-19.c: New testcase. From-SVN: r261056 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 956fbde816b..7adafede7ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2018-06-01 Richard Biener + + PR ipa/85960 + * tree-ssa-structalias.c (get_function_part_constraint): + Handle NULL fi->decl. + (find_func_aliases_for_call): Properly handle indirect + fi from direct call. + (find_func_clobbers): Likewise. + (ipa_pta_execute): Likewise. + (create_variable_info_for): For functions that are ifunc_resolver + resolve to a varinfo that contains the result of the resolver + call. + (associate_varinfo_to_alias): Do not treat ifunc resolvers as + aliases. + 2018-05-31 Michael Collison * config/aarch64/aarch64.md: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 677d8e00d18..cec80a5d238 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-06-01 Richard Biener + + PR ipa/85960 + * gcc.dg/ipa/ipa-pta-19.c: New testcase. + 2018-05-31 Qing Zhao PR middle-end/78809 diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-19.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-19.c new file mode 100644 index 00000000000..ae47cb053b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-19.c @@ -0,0 +1,46 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O2 -fipa-pta" } */ + +#include +#include + +#define hot __attribute__((hot)) + +static hot void multiver_default(unsigned int in, bool *ret) +{ + if ( in & 1 ) { + *ret = false; + }else{ + *ret = true; + } +} + +static void (*resolve_multiver(void))(unsigned int in, bool *out) +{ + return &multiver_default; +} + +__attribute__ ((ifunc("resolve_multiver"))) +static void multiver_test(unsigned int val, bool *ret); + +static hot bool do_test(unsigned int val) +{ + bool ret = false; + + multiver_test(val, &ret); + + return (ret == !(val & 0x1)); +} + +volatile unsigned int x = 2; +int main() +{ + int i; + for(i = 1; i < x; i++) { + unsigned int val = x; + if ( !do_test(val) ) + abort (); + } + return 0; +} diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 14ab83a9469..73e500bb616 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -3903,7 +3903,7 @@ get_function_part_constraint (varinfo_t fi, unsigned part) 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) @@ -4735,7 +4735,7 @@ find_func_aliases_for_call (struct function *fn, gcall *t) fi = get_fi_for_callee (t); if (!in_ipa_mode - || (fndecl && !fi->is_fn_info)) + || (fi->decl && fndecl && !fi->is_fn_info)) { auto_vec rhsc; int flags = gimple_call_flags (t); @@ -5352,7 +5352,7 @@ find_func_clobbers (struct function *fn, gimple *origt) /* For callees without function info (that's external functions), ESCAPED is clobbered and used. */ - if (gimple_call_fndecl (t) + if (cfi->decl && !cfi->is_fn_info) { varinfo_t vi; @@ -6115,6 +6115,27 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id, static unsigned int create_variable_info_for (tree decl, const char *name, bool add_id) { + /* First see if we are dealing with an ifunc resolver call and + assiociate that with a call to the resolver function result. */ + cgraph_node *node; + if (in_ipa_mode + && TREE_CODE (decl) == FUNCTION_DECL + && (node = cgraph_node::get (decl))->ifunc_resolver) + { + varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl); + 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)); + insert_vi_for_tree (decl, fi); + return fi->id; + } + varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL); unsigned int id = vi->id; @@ -7715,7 +7736,8 @@ associate_varinfo_to_alias (struct cgraph_node *node, void *data) 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; } @@ -8087,7 +8109,7 @@ ipa_pta_execute (void) (node->decl, first_vi_for_offset (fi, fi_uses)); } /* Handle direct calls to external functions. */ - else if (decl) + else if (decl && (!fi || fi->decl)) { pt = gimple_call_use_set (stmt); if (gimple_call_flags (stmt) & ECF_CONST) @@ -8132,8 +8154,7 @@ ipa_pta_execute (void) } } /* Handle indirect calls. */ - else if (!decl - && (fi = get_fi_for_callee (stmt))) + else if ((fi = get_fi_for_callee (stmt))) { /* We need to accumulate all clobbers/uses of all possible callees. */ @@ -8189,6 +8210,8 @@ ipa_pta_execute (void) } } } + else + gcc_unreachable (); } }