aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/m32c/m32c.c36
2 files changed, 40 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3e6a75f..173cabf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-16 DJ Delorie <dj@redhat.com>
+
+ * config/m32c/m32c.c (m32c_compare_redundant): Avoid removing
+ compares that may be indirectly affected by previous instructions.
+
2009-07-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtins.c (do_mpc_arg2): New.
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index 9672dfa..46dc4dc 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -4167,6 +4167,40 @@ m32c_compare_redundant (rtx cmp, rtx *operands)
#endif
return false;
}
+
+ /* Check for comparisons against memory - between volatiles and
+ aliases, we just can't risk this one. */
+ if (GET_CODE (operands[0]) == MEM
+ || GET_CODE (operands[0]) == MEM)
+ {
+#if DEBUG_CMP
+ fprintf(stderr, "comparisons with memory:\n");
+ debug_rtx(prev);
+#endif
+ return false;
+ }
+
+ /* Check for PREV changing a register that's used to compute a
+ value in CMP, even if it doesn't otherwise change flags. */
+ if (GET_CODE (operands[0]) == REG
+ && rtx_referenced_p (SET_DEST (PATTERN (prev)), operands[0]))
+ {
+#if DEBUG_CMP
+ fprintf(stderr, "sub-value affected, op0:\n");
+ debug_rtx(prev);
+#endif
+ return false;
+ }
+ if (GET_CODE (operands[1]) == REG
+ && rtx_referenced_p (SET_DEST (PATTERN (prev)), operands[1]))
+ {
+#if DEBUG_CMP
+ fprintf(stderr, "sub-value affected, op1:\n");
+ debug_rtx(prev);
+#endif
+ return false;
+ }
+
} while (pflags == FLAGS_N);
#if DEBUG_CMP
fprintf(stderr, "previous flag-setting insn:\n");
@@ -4251,7 +4285,7 @@ m32c_output_compare (rtx insn, rtx *operands)
}
#if DEBUG_CMP
- fprintf(stderr, "cbranch: cmp needed: `%s'\n", templ);
+ fprintf(stderr, "cbranch: cmp needed: `%s'\n", templ + 1);
#endif
return templ + 1;
}