diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-27 21:39:11 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-27 21:39:11 +0000 |
commit | d2b033bbe3dfc420c052e10519c60be50f56a779 (patch) | |
tree | 915e4fd9c2d5575df891eb9167257b3854256772 /gcc | |
parent | d2c38221df05656977231152a91b0957b86ba86c (diff) | |
download | gcc-d2b033bbe3dfc420c052e10519c60be50f56a779.tar.gz |
PR optimization/7520
* cfganal.c (flow_active_insn_p): New.
(forwarder_block_p): Use it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57593 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cfganal.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20020927-1.c | 26 |
3 files changed, 58 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 30a220d8f21..ebf0d324635 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2002-09-27 Richard Henderson <rth@redhat.com> + PR optimization/7520 + * cfganal.c (flow_active_insn_p): New. + (forwarder_block_p): Use it. + +2002-09-27 Richard Henderson <rth@redhat.com> + * emit-rtl.c (active_insn_p): Revert last change. 2002-09-27 Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/cfganal.c b/gcc/cfganal.c index bc8fff2510b..10c6bcf2922 100644 --- a/gcc/cfganal.c +++ b/gcc/cfganal.c @@ -54,7 +54,31 @@ static void flow_dfs_compute_reverse_finish PARAMS ((depth_first_search_ds)); static void remove_fake_successors PARAMS ((basic_block)); static bool need_fake_edge_p PARAMS ((rtx)); +static bool flow_active_insn_p PARAMS ((rtx)); +/* Like active_insn_p, except keep the return value clobber around + even after reload. */ + +static bool +flow_active_insn_p (insn) + rtx insn; +{ + if (active_insn_p (insn)) + return true; + + /* A clobber of the function return value exists for buggy + programs that fail to return a value. It's effect is to + keep the return value from being live across the entire + function. If we allow it to be skipped, we introduce the + possibility for register livetime aborts. */ + if (GET_CODE (PATTERN (insn)) == CLOBBER + && GET_CODE (XEXP (PATTERN (insn), 0)) == REG + && REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0))) + return true; + + return false; +} + /* Return true if the block has no effect and only forwards control flow to its single destination. */ @@ -69,12 +93,12 @@ forwarder_block_p (bb) return false; for (insn = bb->head; insn != bb->end; insn = NEXT_INSN (insn)) - if (INSN_P (insn) && active_insn_p (insn)) + if (INSN_P (insn) && flow_active_insn_p (insn)) return false; return (!INSN_P (insn) || (GET_CODE (insn) == JUMP_INSN && simplejump_p (insn)) - || !active_insn_p (insn)); + || !flow_active_insn_p (insn)); } /* Return nonzero if we can reach target from src by falling through. */ diff --git a/gcc/testsuite/gcc.c-torture/compile/20020927-1.c b/gcc/testsuite/gcc.c-torture/compile/20020927-1.c new file mode 100644 index 00000000000..b93d8a18d5e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20020927-1.c @@ -0,0 +1,26 @@ +/* PR optimization/7520 */ +/* ICE at -O3 on x86 due to register life problems caused by + the return-without-value in bar. */ + +int +foo () +{ + int i; + long long int j; + + while (1) + { + if (j & 1) + ++i; + j >>= 1; + if (j) + return i; + } +} + +int +bar () +{ + if (foo ()) + return; +} |