From b914768c1968d924d77bbe3f4e707c6105f3682c Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 13 Nov 2019 22:02:11 +0100 Subject: [PATCH] re PR ipa/92421 (ICE in inline_small_functions, at ipa-inline.c:2001 since r277759) PR c++/92421 * ipa-prop.c (update_indirect_edges_after_inlining): Mark parameter as used. * ipa-inline.c (recursive_inlining): Reset node cache after inlining. (inline_small_functions): Remove checking ifdef. * ipa-inline-analysis.c (do_estimate_edge_time): Verify cache consistency. * g++.dg/torture/pr92421.C: New testcase. From-SVN: r278159 --- gcc/ChangeLog | 11 ++ gcc/ipa-inline-analysis.c | 13 ++ gcc/ipa-inline.c | 10 +- gcc/ipa-prop.c | 5 + gcc/testsuite/ChangeLog | 5 + gcc/testsuite/g++.dg/torture/pr92421.C | 174 +++++++++++++++++++++++++ 6 files changed, 213 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr92421.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6d8e7c63c17..42229be0f14 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-11-13 Jan Hubicka + + PR c++/92421 + * ipa-prop.c (update_indirect_edges_after_inlining): + Mark parameter as used. + * ipa-inline.c (recursive_inlining): Reset node cache + after inlining. + (inline_small_functions): Remove checking ifdef. + * ipa-inline-analysis.c (do_estimate_edge_time): Verify + cache consistency. + 2019-11-13 Jan Hubicka PR ipa/92498 diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 2acb2bebacc..b45063b224d 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -210,6 +210,19 @@ do_estimate_edge_time (struct cgraph_edge *edge) time = e->entry.time; nonspec_time = e->entry.nonspec_time; hints = e->entry.hints; + if (flag_checking) + { + sreal chk_time, chk_nonspec_time; + int chk_size, chk_min_size; + + ipa_hints chk_hints; + ctx.estimate_size_and_time (&chk_size, &chk_min_size, + &chk_time, &chk_nonspec_time, + &chk_hints); + gcc_assert (chk_size == size && chk_time == time + && chk_nonspec_time == nonspec_time + && chk_hints == hints); + } } else { diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index f3e880c3e93..78ec0ec685f 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1633,6 +1633,7 @@ recursive_inlining (struct cgraph_edge *edge, } inline_call (curr, false, new_edges, &overall_size, true); + reset_node_cache (node); lookup_recursive_calls (node, curr->callee, &heap); n++; } @@ -1982,11 +1983,10 @@ inline_small_functions (void) if (!edge->inline_failed || !edge->callee->analyzed) continue; -#if CHECKING_P /* Be sure that caches are maintained consistent. This check is affected by scaling roundoff errors when compiling for IPA this we skip it in that case. */ - if (!edge->callee->count.ipa_p () + if (flag_checking && !edge->callee->count.ipa_p () && (!max_count.initialized_p () || !max_count.nonzero_p ())) { sreal cached_badness = edge_badness (edge, false); @@ -1997,6 +1997,9 @@ inline_small_functions (void) if (edge_growth_cache != NULL) edge_growth_cache->remove (edge); + reset_node_cache (edge->caller->inlined_to + ? edge->caller->inlined_to + : edge->caller); gcc_assert (old_size_est == estimate_edge_size (edge)); gcc_assert (old_time_est == estimate_edge_time (edge)); /* FIXME: @@ -2021,9 +2024,6 @@ inline_small_functions (void) } else current_badness = edge_badness (edge, false); -#else - current_badness = edge_badness (edge, false); -#endif if (current_badness != badness) { if (edge_heap.min () && current_badness > edge_heap.min_key ()) diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 312b2108f84..2cb8c585c24 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -3537,6 +3537,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, if (ici->polymorphic && !ipa_get_jf_ancestor_type_preserved (jfunc)) ici->vptr_changed = true; + ipa_set_param_used_by_indirect_call (new_root_info, + ici->param_index, true); + if (ici->polymorphic) + ipa_set_param_used_by_polymorphic_call (new_root_info, + ici->param_index, true); } } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 33c16d5ecb3..3778788e80c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-11-13 Jan Hubicka + + PR c++/92421 + * g++.dg/torture/pr92421.C: New testcase. + 2019-11-13 David Edelsohn * gcc.target/powerpc/pr92090.c: Limit -mbig to powerpc64le-*-*. diff --git a/gcc/testsuite/g++.dg/torture/pr92421.C b/gcc/testsuite/g++.dg/torture/pr92421.C new file mode 100644 index 00000000000..7adf53f7299 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr92421.C @@ -0,0 +1,174 @@ +/* { dg-do compile } */ +typedef long a; +void *b, *c; +template class d {}; +template bool operator!=(d, d); +class g { +public: + g(char *); +}; +class j { +public: + j(); + void h(); + void i(); + void aj(); +}; +class m { +public: + m(bool); +}; +class n { +public: + operator a(); +}; +class o { +public: + long am(); +}; +class H { +public: + class p {}; + virtual bool accept(const char *, unsigned long, p *, bool); +}; +class q : H { +public: + class r { + public: + enum at { au, av, aw }; + }; + enum { ax }; + virtual void ay(char *, int, const char *, r::at, char *); + virtual bool az(const g &, unsigned = ax); + virtual bool ba(const int &, p *, bool); + void bb(char *bc, long bd, char *, long be) { + class bf : public p { + public: + bf(long); + } bg(be); + accept(bc, bd, &bg, true); + } +}; +class s { + q *bi; + bool bj(); +}; +template class t : q { + bool accept(const char *, unsigned long bd, p *bg, bool) { + bool k(bp || bq), cl = false, err = false; + if (br) + ay("", 1, __func__, r::au, ""); + if (bs) + ay("", 6, __func__, r::av, ""); + char bt[1], cd[1]; + long bu = sizeof(int) + bd, ce = sizeof(L) + bd; + char *bw = bu > sizeof(bt) ? new char : bt, + *cf = ce > sizeof(cd) ? new char : cd; + __builtin___memcpy_chk(b, c, bd, 0); + a by[1]; + int bz = 0; + u cb = *cc((int *)bw, true, by, &bz); + ay("", 1, __func__, r::aw, ""); + if (bw != bt) + delete bw; + __builtin___memcpy_chk(b, c, bd, 0); + cb.ch.i(); + bool ci = cj((L *)cf, bg); + bool atran = bq && bp && cb.ck; + if (atran && !ci && cm(&cb)) + if (cn > co) { + int cp = cb.cq % 6; + v cs = *(ct + cp); + if (cu(&cs)) + cl = true; + } + if (ci) + if (k) + cv.aj(); + cv.h(); + b = cc((int *)bw, false, by, &bz); + if (b) + if (cw(&cb, by, bz)) + if (atran && bp && cx()) + cv.aj(); + if (cl) + if (k) + cv.aj(); + cv.h(); + int cp = cb.cq % 6; + v cs = *(ct + cp); + if (cy()) + err = true; + O da = *(db + cp); + if (da.dc->am() > cs.dc->am() + cs.dd->am() + 1 && de(&da)) + cv.aj(); + return !err; + } + bool ba(const int &, p *, bool) { + d kit, df; + while (kit != df) + ; + cx(); + } + bool az(const g &, unsigned) { + t dj; + int cur; + while (cur) { + int dk, dl; + char dbuf; + dj.bb(&dbuf, dl, &dbuf, dk); + } + } + struct L {}; + struct u { + j ch; + a cq; + bool ck; + }; + struct v { + o *dd; + o *dc; + }; + struct O { + o *dc; + }; + bool cy(); + bool cu(v *); + bool cj(L *, p *); + bool de(O *); + u *cc(int *, bool, a *, int *); + bool cw(u *, a *, int); + bool cx() { + dm.dn(); + bool err = false; + if (dm.l()) + err = true; + return !err; + } + bool cm(u *); + j cv; + int br; + bool bs; + bool bq; + bk dm; + a co; + n cn; + v ct[6]; + O db[6]; + bool bp; +}; +class w : q { +public: + void dn(); + bool l() { + m(true); + if (br) + ay("", 1087, __func__, r::au, ""); + return false; + } + int br; +}; +bool s::bj() { + bi->az(""); + new t; +} -- 2.30.2