Hi Zdenek,

    (parallel [
              (set (pc)
                   (if_then_else (lt:SI (reg:SI 45)    <---
                                        (reg:SI 26))
                                 (label_ref:HI 129)
                                 (pc)))
              (clobber (reg:SI 45))                    <-- must be the same
              (clobber (scratch:BI))
              ])

actually, I probably misunderstood what you meant.  The problem is that
invariant motion rewrites just part of the considered insn, changing
reg:45 to another register in if_then_else, but leaving it the same in
the clobber?

Correct.  I originally had a patch like this

Index: gcc/loop-invariant.c
===================================================================
--- gcc/loop-invariant.c        (revision 125308)
+++ gcc/loop-invariant.c        (working copy)
@@ -1212,7 +1212,14 @@ move_invariant_reg (struct loop *loop, u
   if (inv->def)
     {
       for (use = inv->def->uses; use; use = use->next)
-       *use->pos = reg;
+       {
+         rtx orig = *use->pos;
+
+         /* Use replace_rtx() in case there are other references to
+            ORIG inside the insn which are not recorded in the USE
+            list.  eg references inside CLOBBERs.  */
+         replace_rtx (use->insn, orig, reg);
+       }
     }

   return true;

which I thought would solve the problem, but I found that it introduced regressions into the gcc testsuite for an x86_64-linux-gnulibc toolchain, so I abandoned it. (I did not investigate why it caused regressions, I just assumed that my approach was wrong).

Cheers
  Nick

Reply via email to