diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-26 10:12:35 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-26 10:12:35 +0000 |
commit | 21951fbd4a7b88ef7ba76537f81a97c5b7e3358a (patch) | |
tree | 44fbb99e75e09d9b2374c79fd95d10119f0db2d6 | |
parent | 32eca732897e9d19bf26f1283582ee3ff120ffed (diff) | |
download | ppe42-gcc-21951fbd4a7b88ef7ba76537f81a97c5b7e3358a.tar.gz ppe42-gcc-21951fbd4a7b88ef7ba76537f81a97c5b7e3358a.zip |
2012-10-26 Richard Biener <rguenther@suse.de>
PR middle-end/54824
* tree-optimize.c (execute_fixup_cfg): Insert __builtin_unreachable
at the end of blocks with no successors.
* gcc.dg/torture/pr54824.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192841 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr54824.c | 16 | ||||
-rw-r--r-- | gcc/tree-optimize.c | 19 |
4 files changed, 46 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4d0f9e00dc6..96e604565a7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-10-26 Richard Biener <rguenther@suse.de> + + PR middle-end/54824 + * tree-optimize.c (execute_fixup_cfg): Insert __builtin_unreachable + at the end of blocks with no successors. + 2012-10-26 Alexander Ivchenko <alexander.ivchenko@intel.com> Uros Bizjak <ubizjak@gmail.com> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 918af7526fe..c3badec964f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-10-26 Richard Biener <rguenther@suse.de> + + PR middle-end/54824 + * gcc.dg/torture/pr54824.c: New testcase. + 2012-10-26 Alexander Ivchenko <alexander.ivchenko@intel.com> * gcc.target/i386/fxsave-1.c: New. diff --git a/gcc/testsuite/gcc.dg/torture/pr54824.c b/gcc/testsuite/gcc.dg/torture/pr54824.c new file mode 100644 index 00000000000..82b822b0993 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr54824.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-w" } */ + +void __attribute__((noreturn)) bar(void) +{ +} + +void foo(int i, char *p, char *q) +{ + while (*p++) { + if (i) + p++; + if (!*q++) + bar(); + } +} diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index d13c04f783c..3e7ca89e94d 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -180,6 +180,25 @@ execute_fixup_cfg (void) FOR_EACH_EDGE (e, ei, bb->succs) e->count = (e->count * count_scale + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE; + + /* If we have a basic block with no successors that does not + end with a control statement or a noreturn call end it with + a call to __builtin_unreachable. This situation can occur + when inlining a noreturn call that does in fact return. */ + if (EDGE_COUNT (bb->succs) == 0) + { + gimple stmt = last_stmt (bb); + if (!stmt + || (!is_ctrl_stmt (stmt) + && (!is_gimple_call (stmt) + || (gimple_call_flags (stmt) & ECF_NORETURN) == 0))) + { + stmt = gimple_build_call + (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0); + gimple_stmt_iterator gsi = gsi_last_bb (bb); + gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); + } + } } if (count_scale != REG_BR_PROB_BASE) compute_function_frequency (); |