ipa/96806 - Fix ICE in ipa-cp due to integer addition overflow
authorFeng Xue <fxue@os.amperecomputing.com>
Mon, 31 Aug 2020 07:00:52 +0000 (15:00 +0800)
committerFeng Xue <fxue@os.amperecomputing.com>
Mon, 31 Aug 2020 08:34:56 +0000 (16:34 +0800)
2020-08-31  Feng Xue  <fxue@os.amperecomputing.com>

gcc/
PR tree-optimization/96806
* ipa-cp.c (decide_about_value): Use safe_add to avoid cost addition
overflow.

gcc/testsuite/
PR tree-optimization/96806
* g++.dg/ipa/pr96806.C: New test.

gcc/ipa-cp.c
gcc/testsuite/g++.dg/ipa/pr96806.C [new file with mode: 0644]

index 7ae6c883a1d0d2af998b336305616aef5f6fcf7f..b3e7d41ea10108db9ab62b389d0a829d7b7dd462 100644 (file)
@@ -5481,11 +5481,11 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
                                   freq_sum, count_sum,
                                   val->local_size_cost)
       && !good_cloning_opportunity_p (node,
-                                     val->local_time_benefit
-                                     + val->prop_time_benefit,
+                                     safe_add (val->local_time_benefit,
+                                               val->prop_time_benefit),
                                      freq_sum, count_sum,
-                                     val->local_size_cost
-                                     + val->prop_size_cost))
+                                     safe_add (val->local_size_cost,
+                                               val->prop_size_cost)))
     return false;
 
   if (dump_file)
diff --git a/gcc/testsuite/g++.dg/ipa/pr96806.C b/gcc/testsuite/g++.dg/ipa/pr96806.C
new file mode 100644 (file)
index 0000000..28fdf77
--- /dev/null
@@ -0,0 +1,53 @@
+/* { dg-do compile } */                                                                        
+/* { dg-options "-std=c++11 -O -fipa-cp -fipa-cp-clone --param=ipa-cp-max-recursive-depth=94 --param=logical-op-non-short-circuit=0" } */
+
+enum a {};
+struct m;
+struct n {
+  a d;
+};
+int o(int, int);
+struct p {
+  char d;
+  char aa;
+  p *ab;
+  bool q() const {
+    int h = d & 4;
+    return h;
+  }
+  char r() const { return aa; }
+  int s(const m *, bool) const;
+} l;
+struct t {
+  p *ac;
+  p *u() { return ac; }
+  p *v(int);
+};
+int w(const p *, const p *, const m *, int = 0);
+struct m : n {
+  struct {
+    t *ad;
+  } ae;
+  char x() const;
+  p *y(int z) const { return ae.ad ? nullptr : ae.ad->v(z); }
+} j;
+int w(const p *z, const p *af, const m *ag, int ah) {
+  int a, g = z->s(ag, true), i = af->s(ag, true);
+  if (af->q()) {
+    if (ag->x())
+      return 0;
+    ah++;
+    char b = af->r();
+    p *c = ag->y(b), *e = ag->ae.ad->u();
+    int d = w(z, c, ag, ah), f = w(z, af ? e : af->ab, ag, ah);
+    a = f ? d : f;
+    return a;
+  }
+  if (g || i == 1)
+    return ag->d ? o(g, i) : o(g, i);
+  return 0;
+}
+void ai() {
+  for (p k;;)
+    w(&k, &l, &j);
+}