Mark Mitchell wrote:
> H.J. Lu wrote:
> 
> > http://gcc.gnu.org/ml/gcc-patches/2007-08/msg01865.html
> > 
> > which involves reload.
> 
> I'm not going to try to wade into reload.  Ulrich, Eric, Ian -- would
> one of you please review this patch?

@@ -1821,6 +1835,18 @@ find_reg (struct insn_chain *chain, int 
            this_cost--;
          if (rl->out && REG_P (rl->out) && REGNO (rl->out) == regno)
            this_cost--;
+#ifdef SECONDARY_MEMORY_NEEDED
+         /* If a memory location is needed for rl->in and dest_reg
+            is usable, we will favor it.  */
+         else if (dest_reg == regno
+                  && rl->in
+                  && REG_P (rl->in)
+                  && REGNO (rl->in) < FIRST_PSEUDO_REGISTER
+                  && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (rl->in)),
+                                              rl->class,
+                                              rl->mode))
+           this_cost = 0;
+#endif


Hmm, this isn't really related to secondary memory.  In general,
if we have a simple move with input reload, the destination of 
the move should be the preferred reload register.  In fact, there
already is code in find_reloads that is supposed to address this
problem:

  /* Special case a simple move with an input reload and a
     destination of a hard reg, if the hard reg is ok, use it.  */
  for (i = 0; i < n_reloads; i++)
    if (rld[i].when_needed == RELOAD_FOR_INPUT
        && GET_CODE (PATTERN (insn)) == SET
        && REG_P (SET_DEST (PATTERN (insn)))
        && SET_SRC (PATTERN (insn)) == rld[i].in
        && !elimination_target_reg_p (SET_DEST (PATTERN (insn))))
      {

This does not trigger in the given test case because the SUBREG
interferes:

Reloads for insn # 6
Reload 0: reload_in (DF) = (reg:DF 5 di)
        SSE_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine
        reload_in_reg: (subreg:DF (reg/v:DI 5 di [orig:59 in ] [59]) 0)

(insn:HI 6 3 10 2 xxx.i:4
        (set (reg:DF 21 xmm0 [orig:58 <result> ] [58])
        (subreg:DF (reg/v:DI 5 di [orig:59 in ] [59]) 0)) 102
 {*movdf_integer_rex64} (expr_list:REG_DEAD (reg/v:DI 5 di [orig:59 in ] [59])
        (nil)))

Note how reload_in is not equal to the SET_SRC, but reload_in_reg is.
In that case, the same special case should apply.

The following patch fixes the test case for me:

Index: gcc/reload.c
===================================================================
--- gcc/reload.c        (revision 129925)
+++ gcc/reload.c        (working copy)
@@ -4462,7 +4462,8 @@
     if (rld[i].when_needed == RELOAD_FOR_INPUT
        && GET_CODE (PATTERN (insn)) == SET
        && REG_P (SET_DEST (PATTERN (insn)))
-       && SET_SRC (PATTERN (insn)) == rld[i].in
+       && (SET_SRC (PATTERN (insn)) == rld[i].in
+           || SET_SRC (PATTERN (insn)) == rld[i].in_reg)
        && !elimination_target_reg_p (SET_DEST (PATTERN (insn))))
       {
        rtx dest = SET_DEST (PATTERN (insn));


H.J., could you verify that this solves your problem?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  [EMAIL PROTECTED]

Reply via email to