This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Non-representable subregs of subword pseudoregs
- From: Jan Hubicka <jh at suse dot cz>
- To: Eric Botcazou <ebotcazou at libertysurf dot fr>
- Cc: gcc at gcc dot gnu dot org, Jan Hubicka <jh at suse dot cz>
- Date: Sat, 13 Nov 2004 14:17:17 +0100
- Subject: Re: Non-representable subregs of subword pseudoregs
- References: <200411120930.37626.ebotcazou@libertysurf.fr>
> Hello,
>
> I've run into a surprising (to me) behavior of the reload pass: it apparently
> doesn't know how to reload non-representable subregs of subword pseudoregs.
> For example on SPARC64:
>
> (insn 22 21 23 1 (set (reg:SI 109 [ D.1130 ])
> (subreg:SI (reg:DI 126) 0)) 51 {*movsi_insn} (nil)
> (nil))
>
> leads to
>
> Reloads for insn # 22
> Reload 0: reload_in (SI) = (reg:SI 1 %g1)
> GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine
> reload_in_reg: (subreg:SI (reg:DI 1 %g1 [126]) 0)
> reload_reg_rtx: (reg:SI 5 %g5)
>
> (insn 61 21 22 1 (set (reg:SI 5 %g5)
> (reg:SI 1 %g1)) 51 {*movsi_insn} (nil)
> (nil))
>
> (insn 22 61 23 1 (set (reg:SI 4 %g4 [orig:109 D.1130 ] [109])
> (reg:SI 5 %g5)) 51 {*movsi_insn} (nil)
> (nil))
>
> which is of course wrong since the target is big-endian.
>
>
> A reload is scheduled because find_reload correctly diagnoses that the subreg
> is not representable:
>
> while (GET_CODE (operand) == SUBREG)
> {
> /* Offset only matters when operand is a REG and
> it is a hard reg. This is because it is passed
> to reg_fits_class_p if it is a REG and all pseudos
> return 0 from that function. */
> if (REG_P (SUBREG_REG (operand))
> && REGNO (SUBREG_REG (operand)) < FIRST_PSEUDO_REGISTER)
> {
> if (!subreg_offset_representable_p
> (REGNO (SUBREG_REG (operand)),
> GET_MODE (SUBREG_REG (operand)),
> SUBREG_BYTE (operand),
> GET_MODE (operand)))
> force_reload = 1;
>
> However, reload_inner_reg_of_subreg returns false for it (for 2 reasons: it's
> an input reload and the function only looks at output reloads, and subregs of
> subword regs are rejected) so push_reload silently turns the invalid subreg
> into the low part:
>
> /* If IN is a SUBREG of a hard register, make a new REG. This
> simplifies some of the cases below. */
>
> if (in != 0 && GET_CODE (in) == SUBREG && REG_P (SUBREG_REG (in))
> && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
> && ! dont_remove_subreg)
> in = gen_rtx_REG (GET_MODE (in), subreg_regno (in));
>
>
> Is this a known limitation of the reload pass or am I missing anything else?
> [Jan, I've CCed you because you devised subreg_offset_representable_p.]
>
>
> The non-representable subreg is created by emit_move_insn_1 when it is invoked
> on pseudo regs and CONCATs with complex modes. Note that it already has a
> special provision in order not to create non-representable subregs of hard
> regs:
>
> /* If this is a complex value with each part being smaller than a
> word, the usual calling sequence will likely pack the pieces into
> a single register. Unfortunately, SUBREG of hard registers only
> deals in terms of words, so we have a problem converting input
> arguments to the CONCAT of two registers that is used elsewhere
> for complex values. If this is before reload, we can copy it into
> memory and reload. FIXME, we should see about using extract and
> insert on integer registers, but complex short and complex char
> variables should be rarely used. */
> if (GET_MODE_BITSIZE (mode) < 2 * BITS_PER_WORD
> && (reload_in_progress | reload_completed) == 0)
> {
> int packed_dest_p
> = (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER);
> int packed_src_p
> = (REG_P (y) && REGNO (y) < FIRST_PSEUDO_REGISTER);
>
> if (packed_dest_p || packed_src_p)
>
> but it doesn't apply here because we are dealing with pseudo regs.
>
>
> How is this supposed to work? Is it simply illegal to create non-lowpart
> subregs of subword pseudo regs?
I really don't know. We seem to be really chaotic about handing the
subregs here. I've added the representability bits mostly to make
reload to something instead of leaking the subregs in code to be ignored
later by subreg stripping pass.
The sollution I used for SSE was to avoid these subregs from existence
as far as I can remember.
Honza
>
> Thanks in advance.
>
> --
> Eric Botcazou