diff options
author | Richard Sandiford <rsandifo@redhat.com> | 2004-07-06 18:27:35 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2004-07-06 18:27:35 +0000 |
commit | 60e20b9079b630a17b18d19bffd01097454061de (patch) | |
tree | 1284532d79574aa97537f07b98681c409f9ae900 /gcc | |
parent | 37bcf311cf08d695ad850647cc757e637e1e59c0 (diff) | |
download | gcc-60e20b9079b630a17b18d19bffd01097454061de.zip gcc-60e20b9079b630a17b18d19bffd01097454061de.tar.gz gcc-60e20b9079b630a17b18d19bffd01097454061de.tar.bz2 |
re PR rtl-optimization/16380 (Use of uninitialised register after dbra conversion)
PR rtl-optimization/16380
* loop.c (check_dbra_loop): Sink comparison instructions if they
do something other than set cc0.
From-SVN: r84161
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/loop.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20040706-1.c | 9 |
4 files changed, 34 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9f2d1c1..c9e0250 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2004-07-06 Richard Sandiford <rsandifo@redhat.com> + + PR rtl-optimization/16380 + * loop.c (check_dbra_loop): Sink comparison instructions if they + do something other than set cc0. + 2004-07-06 James E Wilson <wilson@specifixinc.com> * doc/interface.texi (longjmp and automatic variables): Delete @@ -8284,6 +8284,7 @@ check_dbra_loop (struct loop *loop, int insn_count) enum rtx_code cmp_code; int comparison_const_width; unsigned HOST_WIDE_INT comparison_sign_mask; + bool keep_first_compare; add_val = INTVAL (bl->biv->add_val); comparison_value = XEXP (comparison, 1); @@ -8476,13 +8477,26 @@ check_dbra_loop (struct loop *loop, int insn_count) not delete the label. */ LABEL_NUSES (XEXP (jump_label, 0))++; + /* If we have a separate comparison insn that does more + than just set cc0, the result of the comparison might + be used outside the loop. */ + keep_first_compare = (compare_and_branch == 2 +#ifdef HAVE_CC0 + && sets_cc0_p (first_compare) <= 0 +#endif + ); + /* Emit an insn after the end of the loop to set the biv's proper exit value if it is used anywhere outside the loop. */ - if ((REGNO_LAST_UID (bl->regno) != INSN_UID (first_compare)) + if (keep_first_compare + || (REGNO_LAST_UID (bl->regno) != INSN_UID (first_compare)) || ! bl->init_insn || REGNO_FIRST_UID (bl->regno) != INSN_UID (bl->init_insn)) loop_insn_sink (loop, gen_load_of_final_value (reg, final_value)); + if (keep_first_compare) + loop_insn_sink (loop, PATTERN (first_compare)); + /* Delete compare/branch at end of loop. */ delete_related_insns (PREV_INSN (loop_end)); if (compare_and_branch == 2) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4f62f1a..4168a68 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-07-06 Richard Sandiford <rsandifo@redhat.com> + + * gcc.c-torture/execute/20040706-1.c: New test. + 2004-07-06 Giovanni Bajo <giovannibajo@gcc.gnu.org> PR c++/3671 diff --git a/gcc/testsuite/gcc.c-torture/execute/20040706-1.c b/gcc/testsuite/gcc.c-torture/execute/20040706-1.c new file mode 100644 index 0000000..6b0ab36 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20040706-1.c @@ -0,0 +1,9 @@ +int main () +{ + int i; + for (i = 0; i < 10; i++) + continue; + if (i < 10) + abort (); + exit (0); +} |