aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/gcse.c8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr24257.c26
4 files changed, 47 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0e8ee82..e7961fe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2006-01-14 Steven Bosscher <stevenb.gcc@gmail.com>
+ Richard Guenther <rguenther@suse.de>
+
+ PR rtl-optimization/24257
+ * gcse.c (find_moveable_store): Only consider a store movable
+ when the SET_SRC of the insn can be assigned to a register.
+
2006-01-14 Ian Lance Taylor <ian@airs.com>
* tree.c (tree_not_class_check_failed): New function.
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 5966694..290f70e 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -5664,6 +5664,14 @@ find_moveable_store (rtx insn, int *regs_set_before, int *regs_set_after)
if (find_reg_note (insn, REG_EH_REGION, NULL_RTX))
return;
+ /* Make sure that the SET_SRC of this store insns can be assigned to
+ a register, or we will fail later on in replace_store_insn, which
+ assumes that we can do this. But sometimes the target machine has
+ oddities like MEM read-modify-write instruction. See for example
+ PR24257. */
+ if (!can_assign_to_reg_p (SET_SRC (set)))
+ return;
+
ptr = ldst_entry (dest);
if (!ptr->pattern_regs)
ptr->pattern_regs = extract_mentioned_regs (dest);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cca26ea..66a7b7f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2006-01-14 Steven Bosscher <stevenb.gcc@gmail.com>
+ Richard Guenther <rguenther@suse.de>
+
+ PR rtl-optimization/24257
+ * gcc.dg/torture/pr24257.c: New testcase.
+
2006-01-13 Adam Nemet <anemet@caviumnetworks.com>
* gcc.c-torture/execute/20060110-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr24257.c b/gcc/testsuite/gcc.dg/torture/pr24257.c
new file mode 100644
index 0000000..200bd18
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr24257.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fgcse -fgcse-sm" } */
+
+typedef struct A {
+ int buf, left;
+} A;
+
+static void flush(A *s, int n)
+{
+ s->buf <<= n;
+
+ while (s->left < 32) {
+ s->buf <<= 8;
+ s->left += 8;
+ }
+
+ s->buf=0;
+}
+
+void oof(A *s, int n)
+{
+ s->buf = n;
+ s->left = n;
+
+ flush(s, n);
+}