------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-07 
21:57 -------
Subject: [PR target/20126, RFC] loop DEST_ADDR biv replacement may fail

loop attempts to eliminate a biv represented by a pseudo in favor of a
giv represented by (plus (reg) (const_int -1)).  Unfortunately, the
biv pseudo appears in an insn that doesn't accept anything but a
register, so validate_change fails and the error goes unnoticed.

The patch below fixes the problem and passed bootstrap on
x86_64-linux-gnu (testing still pending), but I'm not very comfortable
with the use of location for the assignment.  Is this a safe change?
Any loop experts around willing to take a second look on this?  Thanks
in advance,

Index: gcc/ChangeLog
from  Alexandre Oliva  <[EMAIL PROTECTED]>

        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 and leave the insn alone.

Index: gcc/loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.c,v
retrieving revision 1.522
diff -u -p -r1.522 loop.c
--- gcc/loop.c 17 Jan 2005 08:46:15 -0000 1.522
+++ gcc/loop.c 7 Mar 2005 21:37:43 -0000
@@ -5470,9 +5470,16 @@ loop_givs_rescan (struct loop *loop, str
        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 (v->insn, v->location, v->new_reg, 0))
+           /* Not replaceable; emit an insn to set the original giv reg from
+              the reduced giv.  */
+           v->insn = loop_insn_emit_before (loop, 0, v->insn,
+                                            gen_move_insn (*v->location,
+                                                           v->new_reg));
+       }
       else if (v->replaceable)
        {
          reg_map[REGNO (v->dest_reg)] = v->new_reg;

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   [EMAIL PROTECTED], gcc.gnu.org}
Free Software Evangelist  [EMAIL PROTECTED], gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20126

Reply via email to