diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-04-16 10:26:26 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-04-16 10:26:26 +0200 |
commit | 234b5365c5485a0606a0d2faac7e9f1e30ce8303 (patch) | |
tree | 147f1985df30d9d59b8e88e486e3c2c03cd5ff39 /gcc/dce.c | |
parent | 41b5808d56c2f4c98cf783b13d97b775f59f123c (diff) | |
download | gcc-234b5365c5485a0606a0d2faac7e9f1e30ce8303.zip gcc-234b5365c5485a0606a0d2faac7e9f1e30ce8303.tar.gz gcc-234b5365c5485a0606a0d2faac7e9f1e30ce8303.tar.bz2 |
re PR rtl-optimization/90082 (ICE in delete_unmarked_insns, at dce.c:653)
PR rtl-optimization/90082
* dce.c (can_delete_call): New function.
(deletable_insn_p, mark_insn): Use it.
* gcc.dg/pr90082.c: New test.
From-SVN: r270380
Diffstat (limited to 'gcc/dce.c')
-rw-r--r-- | gcc/dce.c | 32 |
1 files changed, 28 insertions, 4 deletions
@@ -87,6 +87,32 @@ deletable_insn_p_1 (rtx body) } } +/* Don't delete calls that may throw if we cannot do so. */ + +static bool +can_delete_call (rtx_insn *insn) +{ + if (cfun->can_delete_dead_exceptions && can_alter_cfg) + return true; + if (!insn_nothrow_p (insn)) + return false; + if (can_alter_cfg) + return true; + /* If we can't alter cfg, even when the call can't throw exceptions, it + might have EDGE_ABNORMAL_CALL edges and so we shouldn't delete such + calls. */ + gcc_assert (CALL_P (insn)); + if (BLOCK_FOR_INSN (insn) && BB_END (BLOCK_FOR_INSN (insn)) == insn) + { + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, BLOCK_FOR_INSN (insn)->succs) + if ((e->flags & EDGE_ABNORMAL_CALL) != 0) + return false; + } + return true; +} /* Return true if INSN is a normal instruction that can be deleted by the DCE pass. */ @@ -111,8 +137,7 @@ deletable_insn_p (rtx_insn *insn, bool fast, bitmap arg_stores) && (RTL_CONST_OR_PURE_CALL_P (insn) && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)) /* Don't delete calls that may throw if we cannot do so. */ - && ((cfun->can_delete_dead_exceptions && can_alter_cfg) - || insn_nothrow_p (insn))) + && can_delete_call (insn)) return find_call_stack_args (as_a <rtx_call_insn *> (insn), false, fast, arg_stores); @@ -206,8 +231,7 @@ mark_insn (rtx_insn *insn, bool fast) && !SIBLING_CALL_P (insn) && (RTL_CONST_OR_PURE_CALL_P (insn) && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)) - && ((cfun->can_delete_dead_exceptions && can_alter_cfg) - || insn_nothrow_p (insn))) + && can_delete_call (insn)) find_call_stack_args (as_a <rtx_call_insn *> (insn), true, fast, NULL); } } |