diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/gcse.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr24257.c | 26 |
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. @@ -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); +} |