This is the mail archive of the
mailing list for the GCC project.
Re: [PATCH/RFC] Avoid invalid subregs during reload, call for testers
On Mon, Dec 04, 2006 at 09:53:59PM +0000, Joseph S. Myers wrote:
> On Mon, 4 Dec 2006, Rask Ingemann Lambertsen wrote:
> > This patch tries to address two cases where reload would call
> > subreg_regno_offset() with invalid parameters. It also adds a gcc_assert()
> > to catch new uses of subreg_regno_offset() with invalid parameters.
> I think there are rather more cases where subreg_regno_offset may get
> called for an unrepresentable case.
> PowerPC E500 double is very good at producing such cases. You get such
> things as (subreg:DI (reg:DF)) and (subreg:DF (reg:DI)) to handle
> conversion between a double in a single 64-bit register (used for
> arithmetic) and in the low parts of two 32-bit registers (used for
> argument passing). These subregs can't be converted directly to hard
> registers, but there are special instruction patterns (in spe.md) to
> handle moves to and from them.
IMHO you could try modelling the E500 GPRs accordingly: As two 32-bit
parts. HARD_REGNO_NREGS (GPR+1, SImode) = 1, HARD_REGNO_NREGS (GPR+0,
DImode) = 4 and HARD_REGNO_NREGS (GPR+0, DFmode) = 2. The tricky part is
what to return for HARD_REGNO_NREGS (GPR+0, SImode). 1 or 2? I'd say 1
because writing the lower 32-bit part doesn't clobber the upper one.
(Yes, I realize you'd most likely have to split E500 out from PowerPC as
a separate backend to do so. But the model would be more accurate.)
> It turns out there are two different sorts of callers of
> subreg_regno_offset and subreg_regno. One sort requires the subreg to be
> representable as a hard reg; for this, the assert is correct. The other
> sort doesn't, it only wishes to know what range of hard registers may be
> involved in a given subreg. There are a lot of callers of the latter
> sort, computing a range of registers.
Why would the assert not be correct for the latter sort? If using
start_reg = subreg_regno_offset (innermode, innerreg, outermode, offset);
end_reg = start_reg + hard_regno_nregs[start_reg][outer_mode] - 1;
surely your subreg needs to be representable for start_reg and end_reg to be
correct? I'm also curious as to which callers are of the latter sort.
> My conclusion was that subreg_regno_offset and
> subreg_offset_representable_p should be combined into a single function
> that computes information about a subreg such as the offset, the number of
> hard registers and whether it is representable as a hard reg. Those two
> functions would then become wrappers.
I agree. They would tend to have much of their code in common.
Rask Ingemann Lambertsen