aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-05-12 07:18:58 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-05-12 07:18:58 +0000
commit44ab146a7230d473f0b138abe428e923376d7b53 (patch)
tree6128def514d0e208db50df8ed14b675c2610e908
parentb5aa474d1e94543a2878bef474dc5c6242711f33 (diff)
downloadgcc-44ab146a7230d473f0b138abe428e923376d7b53.zip
gcc-44ab146a7230d473f0b138abe428e923376d7b53.tar.gz
gcc-44ab146a7230d473f0b138abe428e923376d7b53.tar.bz2
re PR tree-optimization/70986 (ICE on valid code at -O3 on x86_64-linux-gnu in combine_blocks, at tree-if-conv.c:2219)
2016-05-12 Richard Biener <rguenther@suse.de> PR tree-optimization/70986 * cfganal.c: Include cfgloop.h. (dfs_find_deadend): Prefer to take edges exiting loops. * gcc.dg/torture/pr70986-1.c: New testcase. * gcc.dg/torture/pr70986-2.c: Likewise. * gcc.dg/torture/pr70986-3.c: Likewise. From-SVN: r236158
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cfganal.c17
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70986-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70986-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70986-3.c18
6 files changed, 89 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a81766..da2a10c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-05-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70986
+ * cfganal.c: Include cfgloop.h.
+ (dfs_find_deadend): Prefer to take edges exiting loops.
+
2016-05-11 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* gcc.target/powerpc/pr70963.c: Require at least power8 at both
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index 189762c..a4bdef6 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfghooks.h"
#include "timevar.h"
#include "cfganal.h"
+#include "cfgloop.h"
/* Store the data structures necessary for depth-first search. */
struct depth_first_search_ds {
@@ -747,7 +748,21 @@ dfs_find_deadend (basic_block bb)
return bb;
}
- bb = EDGE_SUCC (bb, 0)->dest;
+ /* If we are in an analyzed cycle make sure to try exiting it.
+ Note this is a heuristic only and expected to work when loop
+ fixup is needed as well. */
+ if (! bb->loop_father
+ || ! loop_outer (bb->loop_father))
+ bb = EDGE_SUCC (bb, 0)->dest;
+ else
+ {
+ edge_iterator ei;
+ edge e;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (loop_exit_edge_p (bb->loop_father, e))
+ break;
+ bb = e ? e->dest : EDGE_SUCC (bb, 0)->dest;
+ }
}
gcc_unreachable ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b9c541f..ce5dfea 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2016-05-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70986
+ * gcc.dg/torture/pr70986-1.c: New testcase.
+ * gcc.dg/torture/pr70986-2.c: Likewise.
+ * gcc.dg/torture/pr70986-3.c: Likewise.
+
2016-05-11 Mikhail Maltsev <maltsevm@gmail.com>
PR c/43651
diff --git a/gcc/testsuite/gcc.dg/torture/pr70986-1.c b/gcc/testsuite/gcc.dg/torture/pr70986-1.c
new file mode 100644
index 0000000..4da1f54
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70986-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+int a, g;
+char b, c;
+short d, e, f;
+
+char
+fn1 ()
+{
+ return a ? a : 1;
+}
+
+void
+fn2 ()
+{
+ char h;
+ for (; d;)
+ for (; e; e++)
+ c = (fn1 () && h) & !(f |= 9 ^ (b > (g = c)));
+ for (;;)
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr70986-2.c b/gcc/testsuite/gcc.dg/torture/pr70986-2.c
new file mode 100644
index 0000000..2f4d2b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70986-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+int gi, dg;
+
+void
+fe (void)
+{
+ int ka = gi;
+
+ for (;;)
+ {
+ if (ka != 0)
+ {
+ if (dg != 0)
+ gi = 0;
+ ++ka;
+ }
+ ++dg;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr70986-3.c b/gcc/testsuite/gcc.dg/torture/pr70986-3.c
new file mode 100644
index 0000000..5b722d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70986-3.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+int a, b;
+int
+fn1 (int p1)
+{
+ return p1 < 0 ? p1 : a;
+}
+
+void
+fn2 ()
+{
+lbl_100:
+ b = 1;
+ for (; b != 21; b = fn1 (b))
+ ;
+ goto lbl_100;
+}