diff options
author | Jan Hubicka <jh@suse.cz> | 2021-11-24 22:27:17 +0100 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2021-11-24 22:28:12 +0100 |
commit | 16e85390507ea92331c9052393b591202007f5ab (patch) | |
tree | f45d5516d2fd429adcc4c84a7d82fa1f904402b3 /gcc | |
parent | 9e026da720091704ca0456d405f16a3bc5f3a799 (diff) | |
download | gcc-16e85390507ea92331c9052393b591202007f5ab.zip gcc-16e85390507ea92331c9052393b591202007f5ab.tar.gz gcc-16e85390507ea92331c9052393b591202007f5ab.tar.bz2 |
Fix handling of static chain in ipa_merge_modref_summary_after_inlining
gcc/ChangeLog:
2021-11-24 Jan Hubicka <hubicka@ucw.cz>
* ipa-modref.c (implicit_eaf_flags_for_edge_and_arg): Break out from...
(modref_merge_call_site_flags): ... here.
(ipa_merge_modref_summary_after_inlining): Use it.
gcc/testsuite/ChangeLog:
2021-11-24 Jan Hubicka <hubicka@ucw.cz>
* gcc.c-torture/execute/pr103405.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ipa-modref.c | 68 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr103405.c | 37 |
2 files changed, 88 insertions, 17 deletions
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c index 923ae6c..c2edc0d 100644 --- a/gcc/ipa-modref.c +++ b/gcc/ipa-modref.c @@ -4827,6 +4827,30 @@ modref_propagate_dump_scc (cgraph_node *component_node) } } +/* Determine EAF flags know for call E with CALLEE_ECF_FLAGS and ARG. */ + +int +implicit_eaf_flags_for_edge_and_arg (cgraph_edge *e, int callee_ecf_flags, + bool ignore_stores, int arg) +{ + /* Returning the value is already accounted to at local propagation. */ + int implicit_flags = EAF_NOT_RETURNED_DIRECTLY + | EAF_NOT_RETURNED_INDIRECTLY; + if (ignore_stores) + implicit_flags |= ignore_stores_eaf_flags; + if (callee_ecf_flags & ECF_PURE) + implicit_flags |= implicit_pure_eaf_flags; + if (callee_ecf_flags & (ECF_CONST | ECF_NOVOPS)) + implicit_flags |= implicit_const_eaf_flags; + class fnspec_summary *fnspec_sum = fnspec_summaries->get (e); + if (fnspec_sum) + { + attr_fnspec fnspec (fnspec_sum->fnspec); + implicit_flags |= fnspec.arg_eaf_flags (arg); + } + return implicit_flags; +} + /* Process escapes in SUM and merge SUMMARY to CUR_SUMMARY and SUMMARY_LTO to CUR_SUMMARY_LTO. Return true if something changed. */ @@ -4857,9 +4881,8 @@ modref_merge_call_site_flags (escape_summary *sum, { int flags = 0; int flags_lto = 0; - /* Returning the value is already accounted to at local propagation. */ - int implicit_flags = EAF_NOT_RETURNED_DIRECTLY - | EAF_NOT_RETURNED_INDIRECTLY; + int implicit_flags = implicit_eaf_flags_for_edge_and_arg + (e, callee_ecf_flags, ignore_stores, ee->arg); if (summary && ee->arg < summary->arg_flags.length ()) flags = summary->arg_flags[ee->arg]; @@ -4995,6 +5018,7 @@ modref_propagate_flags_in_scc (cgraph_node *component_node) if (ecf_flags & (ECF_CONST | ECF_NOVOPS) || !callee_edge->inline_failed) continue; + /* Get the callee and its summary. */ enum availability avail; callee = callee_edge->callee->function_or_virtual_thunk_symbol @@ -5081,6 +5105,9 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge) class modref_summary_lto *callee_info_lto = summaries_lto ? summaries_lto->get (edge->callee) : NULL; int flags = flags_from_decl_or_type (edge->callee->decl); + /* Combine in outer flags. */ + for (cgraph_node *n = edge->caller; n->inlined_to; n = n->callers->caller) + flags |= flags_from_decl_or_type (edge->callee->decl); bool ignore_stores = ignore_stores_p (edge->caller->decl, flags); if (!callee_info && to_info) @@ -5148,10 +5175,11 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge) FOR_EACH_VEC_ELT (sum->esc, i, ee) { bool needed = false; - /* TODO: We do not have jump functions for return slots, so we - never propagate them to outer function. */ - if (ee->parm_index < 0) - continue; + int implicit_flags = implicit_eaf_flags_for_edge_and_arg + (edge, flags, ignore_stores, + ee->arg); + if (!ee->direct) + implicit_flags = deref_flags (implicit_flags, ignore_stores); if (to_info && (int)to_info->arg_flags.length () > ee->parm_index) { int flags = callee_info @@ -5159,11 +5187,14 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge) ? callee_info->arg_flags[ee->arg] : 0; if (!ee->direct) flags = deref_flags (flags, ignore_stores); - else if (ignore_stores) - flags |= ignore_stores_eaf_flags; - flags |= ee->min_flags; - to_info->arg_flags[ee->parm_index] &= flags; - if (to_info->arg_flags[ee->parm_index]) + flags |= ee->min_flags | implicit_flags; + eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM + ? to_info->retslot_flags + : ee->parm_index == MODREF_STATIC_CHAIN_PARM + ? to_info->static_chain_flags + : to_info->arg_flags[ee->parm_index]; + f &= flags; + if (f) needed = true; } if (to_info_lto @@ -5174,11 +5205,14 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge) ? callee_info_lto->arg_flags[ee->arg] : 0; if (!ee->direct) flags = deref_flags (flags, ignore_stores); - else if (ignore_stores) - flags |= ignore_stores_eaf_flags; - flags |= ee->min_flags; - to_info_lto->arg_flags[ee->parm_index] &= flags; - if (to_info_lto->arg_flags[ee->parm_index]) + flags |= ee->min_flags | implicit_flags; + eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM + ? to_info_lto->retslot_flags + : ee->parm_index == MODREF_STATIC_CHAIN_PARM + ? to_info_lto->static_chain_flags + : to_info_lto->arg_flags[ee->parm_index]; + f &= flags; + if (f) needed = true; } struct escape_map entry = {ee->parm_index, ee->direct}; diff --git a/gcc/testsuite/gcc.c-torture/execute/pr103405.c b/gcc/testsuite/gcc.c-torture/execute/pr103405.c new file mode 100644 index 0000000..f6005dc --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr103405.c @@ -0,0 +1,37 @@ +typedef __SIZE_TYPE__ size_t; +void *malloc(size_t); + +static inline int *starter(int a) +{ + int *b = malloc(sizeof(int)); + *b = a; + return b; +} + +static inline _Bool equal(int *l, int *r) +{ + if (l == 0) + __builtin_abort(); + if (r == 0) + __builtin_abort(); + return *r == *l; +} + +int main(void) +{ + int *i; + int *j; + void check(_Bool a) + { + _Bool t = equal(i, j); + if (a && t) __builtin_abort (); + _Bool t1 = equal(i, j); + if (!a && !t1) __builtin_abort (); + } + i = starter(1); + j = starter(0); + check(1); + i = starter(0); + check(0); + +} |