aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-07-06 18:27:35 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-07-06 18:27:35 +0000
commit60e20b9079b630a17b18d19bffd01097454061de (patch)
tree1284532d79574aa97537f07b98681c409f9ae900 /gcc
parent37bcf311cf08d695ad850647cc757e637e1e59c0 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/loop.c16
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040706-1.c9
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
diff --git a/gcc/loop.c b/gcc/loop.c
index 17955b4..e0af19d 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -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);
+}