From 44ab146a7230d473f0b138abe428e923376d7b53 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 12 May 2016 07:18:58 +0000 Subject: [PATCH] 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 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 --- gcc/ChangeLog | 6 ++++++ gcc/cfganal.c | 17 ++++++++++++++++- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gcc.dg/torture/pr70986-1.c | 22 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr70986-2.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr70986-3.c | 18 ++++++++++++++++++ 6 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr70986-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr70986-2.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr70986-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3a817667a5f..da2a10c0356 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-05-12 Richard Biener + + PR tree-optimization/70986 + * cfganal.c: Include cfgloop.h. + (dfs_find_deadend): Prefer to take edges exiting loops. + 2016-05-11 Bill Schmidt * gcc.target/powerpc/pr70963.c: Require at least power8 at both diff --git a/gcc/cfganal.c b/gcc/cfganal.c index 189762cba8e..a4bdef60305 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 b9c541f8c5a..ce5dfea8cba 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-05-12 Richard Biener + + 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 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 00000000000..4da1f54eef0 --- /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 00000000000..2f4d2b645e0 --- /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 00000000000..5b722d590a0 --- /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; +}