re PR ipa/92421 (ICE in inline_small_functions, at ipa-inline.c:2001 since r277759)
authorJan Hubicka <hubicka@ucw.cz>
Wed, 13 Nov 2019 21:02:11 +0000 (22:02 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 13 Nov 2019 21:02:11 +0000 (21:02 +0000)
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
gcc/ipa-inline-analysis.c
gcc/ipa-inline.c
gcc/ipa-prop.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr92421.C [new file with mode: 0644]

index 6d8e7c6..42229be 100644 (file)
@@ -1,5 +1,16 @@
 2019-11-13  Jan Hubicka  <hubicka@ucw.cz>
 
+       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  <hubicka@ucw.cz>
+
        PR ipa/92498
        * ipa-profile.c (check_argument_count): Do not ICE when descriptors
        is NULL.
index 2acb2be..b45063b 100644 (file)
@@ -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
        {
index f3e880c..78ec0ec 100644 (file)
@@ -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 ())
index 312b210..2cb8c58 100644 (file)
@@ -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
index 33c16d5..3778788 100644 (file)
@@ -1,3 +1,8 @@
+2019-11-13  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR c++/92421
+       * g++.dg/torture/pr92421.C: New testcase.
+
 2019-11-13  David Edelsohn  <dje.gcc@gmail.com>
 
        * 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 (file)
index 0000000..7adf53f
--- /dev/null
@@ -0,0 +1,174 @@
+/* { dg-do compile } */
+typedef long a;
+void *b, *c;
+template <typename, typename> class d {};
+template <typename e, typename f> bool operator!=(d<e, f>, d<e, f>);
+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 bk> 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<int, int> 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<w>;
+}