re PR middle-end/52881 (ICE due to null pointer deref in cfgloop.c)
authorRichard Guenther <rguenther@suse.de>
Wed, 11 Apr 2012 08:13:37 +0000 (08:13 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 11 Apr 2012 08:13:37 +0000 (08:13 +0000)
2012-04-11  Richard Guenther  <rguenther@suse.de>

PR rtl-optimization/52881
* ifcvt.c (find_if_case_2): Avoid speculating loop latches.

* gcc.dg/torture/pr52881.c: New testcase.
* gcc.dg/torture/pr52913.c: Likewise.

From-SVN: r186304

gcc/ChangeLog
gcc/ifcvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr52881.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr52913.c [new file with mode: 0644]

index 24efa857d85edeed6d475f457fe65ab632e2e0f4..62a4e88372400e1577175dab92e39b05bc9d9b5d 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-11  Richard Guenther  <rguenther@suse.de>
+
+       PR rtl-optimization/52881
+       * ifcvt.c (find_if_case_2): Avoid speculating loop latches.
+
 2012-04-11  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/52912
index e4e13abe0aa29830de89c0e2a8269e0487eee342..79e2738028315200e3e737aaf25858a5c254c519 100644 (file)
@@ -3927,6 +3927,11 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
   edge else_succ;
   int then_prob, else_prob;
 
+  /* We do not want to speculate (empty) loop latches.  */
+  if (current_loops
+      && else_bb->loop_father->latch == else_bb)
+    return FALSE;
+
   /* If we are partitioning hot/cold basic blocks, we don't want to
      mess up unconditional or indirect jumps that cross between hot
      and cold sections.
index 08293166910bdab32f29dd7255368c2d6d0410b2..7176e6a1f752e63e1d80d046fc711a9691c612c5 100644 (file)
@@ -1,3 +1,9 @@
+2012-04-11  Richard Guenther  <rguenther@suse.de>
+
+       PR rtl-optimization/52881
+       * gcc.dg/torture/pr52881.c: New testcase.
+       * gcc.dg/torture/pr52913.c: Likewise.
+
 2012-04-11  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/52912
diff --git a/gcc/testsuite/gcc.dg/torture/pr52881.c b/gcc/testsuite/gcc.dg/torture/pr52881.c
new file mode 100644 (file)
index 0000000..c101c80
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+
+int a, b, c, d, e, f, h, i, j, k, l, m, n, o;
+static int g;
+int
+fn1 () {
+    for (;; ++f)
+      if (e)
+       break;
+    return 0;
+}
+unsigned char fn2 ();
+void
+fn3 () {
+lbl_220:
+    if (j) {
+lbl_221:
+       l = (g || b) <= fn1 ();
+       for (;;) {
+           g = 0;
+           fn2 ();
+           if (k)
+             goto lbl_220;
+           break;
+       }
+       if (l)
+         goto lbl_221;
+    }
+}
+unsigned char
+fn2 () {
+    o = d ? 0 : c;
+    h = m | a % o != n;
+    return i;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr52913.c b/gcc/testsuite/gcc.dg/torture/pr52913.c
new file mode 100644 (file)
index 0000000..ad99884
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+int a, b, c, d, e;
+void
+fn1 ()
+{
+lbl_101:
+  e = 0;
+lbl_274:
+  for (c = 0; c < 1; c = a)
+    if (d)
+      if (b)
+       goto lbl_101;
+      else
+       break;
+  d = 1;
+  goto lbl_274;
+}