This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: regression in simd-4.c on darwin6.1


> Cc: gcc@gcc.gnu.org
> Date: Fri, 11 Oct 2002 21:51:06 -0400
> From: David Edelsohn <dje@watson.ibm.com>

> 	This failure occurs on AIX (-O2, -O3, -Os) as well and was
> introduced by the cse.c patch from Stuart.  The recent correction to the
> patch removing the warning does not affect the failure.

On Darwin, it happens only at -Os, and it seems that the patch is
doing the right thing.  It's just that the patch changes the insn
sequence which changes register allocation.

The problematic instruction is:

(insn:HI 120 97 129 0 0xe24330 (set (subreg:SF (reg:V4SF 130) 12)
        (plus:SF (subreg:SF (reg:SI 124) 0)
            (subreg:SF (reg:SI 129) 0))) 169 {*rs6000.md:5157}
        (insn_list:REG_DEP_OUTPUT 97 (insn_list 26 (insn_list 16 (nil))))
    (expr_list:REG_DEAD (reg:SI 124)
        (expr_list:REG_DEAD (reg:SI 129)
            (nil))))

Reg-alloc can't put any of these into FP registers, because neither
vector modes nor SImode can go into FP registers.  So it picks integer
registers for r130 and r124, which is reasonable.

Less reasonably, r129 gets CTR, possibly because REGISTER_MOVE_COST
claims that it costs the same to move from CTR to a FP register as it
costs to move from a GPR to a FP register, which is not the case.

The insn gets these reloads:

Reload 0: FLOAT_REGS, RELOAD_FOR_OUTPUT (opnum = 0)
        reload_out_reg: (subreg:SF (reg:V4SF 5 r5 [130]) 12)
Reload 1: reload_in (SF) = (reg:SF 13 r13)
        FLOAT_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine
        reload_in_reg: (subreg:SF (reg:SI 13 r13 [124]) 0)
Reload 2: GENERAL_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 2), can't
        combine, secondary_reload_p
Reload 3: reload_in (SI) = (reg:SI 66 ctr [129])
        reload_out (SF) = (reg:SF 8 r8)
        FLOAT_REGS, RELOAD_OTHER (opnum = 2)
        reload_in_reg: (reg:SI 66 ctr [129])
        reload_out_reg: (subreg:SF (reg:V4SF 5 r5 [130]) 12)
        secondary_in_reload = 2

The reload that fails is the last one.  It is asking for a SImode
reload into FLOAT_REGS.  This is impossible.  If it was asking for a
SFmode reload from CTR, that's impossible too.

The underlying problem is that reload can't cope with moves where
a mode change must happen in a secondary reload.  The correct sequence
here is like

(set GENERAL_REGS:SI COUNT_REGS:SI)
(set MEM:SI GENERAL_REGS:SI)  // or possibly SF with an appropriate SUBREG
(set FLOAT_REGS:SF MEM:SF)

A simple testcase which shows the problem (no vectors, breaks at -O0,
with or without Stuart's patch) is:

typedef union {
  float f;
  int i;
} fi;

int test(void)
{ 
  register fi a asm ("ctr");
  fi b, c;

  asm ("" : "=c" (a.i));
  asm ("" : "=r" (b.i));
  c.f = a.f + b.f;
  return c.i;
}

Entertainingly, if you make "c" be in CTR rather than "a", you get a
different failure that's probably a different bug.

-- 
- Geoffrey Keating <geoffk@geoffk.org>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]