summaryrefslogtreecommitdiff
path: root/gcc/loop.c
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-10 04:00:53 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-10 04:00:53 +0000
commitf5ab938764f423d8c01bfd9e9682af87e6be42e7 (patch)
tree24485e56e8b36a8e92b4e868e76b61bc02192114 /gcc/loop.c
parentbf9790b678ef6dfcb6799abe8eb293c41e7f53ab (diff)
downloadgcc-f5ab938764f423d8c01bfd9e9682af87e6be42e7.tar.gz
gcc/ChangeLog:
PR target/20126 * loop.c (loop_givs_rescan): If replacement of DEST_ADDR failed, set the original address pseudo to the correct value before the original insn, if possible, and leave the insn alone, otherwise create a new pseudo, set it and replace it in the insn. * recog.c (validate_change_maybe_volatile): New. * recog.h (validate_change_maybe_volatile): Declare. gcc/testsuite/ChangeLog: * gcc.dg/pr20126.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97939 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/loop.c')
-rw-r--r--gcc/loop.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/gcc/loop.c b/gcc/loop.c
index e2e6074ccc4..f432e68e592 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -5476,9 +5476,31 @@ loop_givs_rescan (struct loop *loop, struct iv_class *bl, rtx *reg_map)
mark_reg_pointer (v->new_reg, 0);
if (v->giv_type == DEST_ADDR)
- /* Store reduced reg as the address in the memref where we found
- this giv. */
- validate_change (v->insn, v->location, v->new_reg, 0);
+ {
+ /* Store reduced reg as the address in the memref where we found
+ this giv. */
+ if (validate_change_maybe_volatile (v->insn, v->location,
+ v->new_reg))
+ /* Yay, it worked! */;
+ /* Not replaceable; emit an insn to set the original
+ giv reg from the reduced giv. */
+ else if (REG_P (*v->location))
+ loop_insn_emit_before (loop, 0, v->insn,
+ gen_move_insn (*v->location,
+ v->new_reg));
+ else
+ {
+ /* If it wasn't a reg, create a pseudo and use that. */
+ rtx reg, seq;
+ start_sequence ();
+ reg = force_reg (v->mode, *v->location);
+ seq = get_insns ();
+ end_sequence ();
+ loop_insn_emit_before (loop, 0, v->insn, seq);
+ if (!validate_change_maybe_volatile (v->insn, v->location, reg))
+ gcc_unreachable ();
+ }
+ }
else if (v->replaceable)
{
reg_map[REGNO (v->dest_reg)] = v->new_reg;