aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/ifcvt.c5
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr52881.c35
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr52913.c18
5 files changed, 69 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 24efa85..62a4e88 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
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
* tree-ssa-threadupdate.c (thread_block): Tell the cfg
manipulation code we are threading through a loop header
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index e4e13ab..79e2738 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0829316..7176e6a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
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
* gcc.dg/torture/pr52912.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/torture/pr52881.c b/gcc/testsuite/gcc.dg/torture/pr52881.c
new file mode 100644
index 0000000..c101c80
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr52881.c
@@ -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
index 0000000..ad99884
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr52913.c
@@ -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;
+}