Richard Sandiford <rdsandif...@googlemail.com> writes:
> Jeff Law <l...@redhat.com> writes:
> > On 01/15/15 03:13, Robert Suchanek wrote:
> >>> Robert, can you look at reload.c::reload_inner_reg_of_subreg and
> >>> verify that the comment just before its return statement is
> >>> effectively the situation you're in.
> >>>
> >>> There are certainly cases where a SUBREG needs to be treated as an
> >>> in-out operand.  We walked through them eons ago when we were poking
> >>> at SSA for RTL.  But the details have long since faded from memory.
> >>
> >> The comment pretty much applies to my situation.  The only difference
> >> I can see is that reload would have had hard registers at this point.
> >> In the testcase, LRA does not have hard registers assigned to the
> >> concerned pseudo(s), thus, it can't rely on the information in
> >> hard_regno_nregs to check if the number of registers in INNER is
> >> different to the number of words in INNER.
> 
> But the code you quote is:
> 
> if (GET_CODE (*loc) == SUBREG)
>   {
>     reg = SUBREG_REG (*loc);
>     byte = SUBREG_BYTE (*loc);
>     if (REG_P (reg)
>         /* Strict_low_part requires reload the register not
>            the sub-register.  */
>         && (curr_static_id->operand[i].strict_low
>             || (GET_MODE_SIZE (mode)
>                 <= GET_MODE_SIZE (GET_MODE (reg))
>                 && (hard_regno
>                     = get_try_hard_regno (REGNO (reg))) >= 0
>                 && (simplify_subreg_regno
>                     (hard_regno,
>                      GET_MODE (reg), byte, mode) < 0)
>                 && (goal_alt[i] == NO_REGS
>                     || (simplify_subreg_regno
>                         (ira_class_hard_regs[goal_alt[i]][0],
>                          GET_MODE (reg), byte, mode) >= 0))))
> 
> Here we do have a hard register, but it isn't valid to form the subreg
> on that hard register.  Reload had to cope with that case too.
> 
> Since the subreg on the original hard register is invalid, we can't use
> it to decide whether the intention was to write to only a part of the
> inner register.  But I don't think we need to use the hard register
> here.  The original register was a psuedo and I'm pretty sure...
> 
> > The differences (hard vs pseudo regs) are primarily an implementation
> > detail.  I was really looking to see if there was existing code which
> > would turn an output reload into an in-out reload for these subregs.
> >
> > The in-out nature of certain subregs is something I've personally
> > stumbled over in various contexts (for example, this also came up
> > during RTL-SSA investigations years ago).
> 
> ...the rule for pseudos is that words of a multiword pseudo can be
> accessed independently but subword pieces of an individual word can't.
> This obviously isn't ideal if a mode is intended for wider-than-word
> registers, since not all words will be independently addressable when
> allocated to those registers.  The code above is partly dealing with the
> fallout from that.  It's also why we have strict_lowpart for cases like
> al on i386.
> 
> So IMO the patch is too broad.  I think it should only use INOUT reloads
> for !strict_low if the inner mode is wider than a word and the outer
> mode is strictly narrower than the inner mode.  That's on top of Vlad's
> comment about only converting OP_OUTs, of course.

This sounds correct/sensible. The change as committed will be turning
some OP_OUT reloads into OP_INOUT unnecessarily. Checking for !strict_low
is however probably redundant as strict_low must be OP_INOUT and never
OP_OUT but we could mask backend bugs by converting strict_low subregs.

I think this should be resolved for GCC 5 if others agree it is an issue.

Matthew

Reply via email to