Kenneth Zadeck <[email protected]> writes:
> I have figured out what the root cause of pr52543, but i need some
> advise as to how to fix it.
> The bug only happens if the source or destination of the move is a
> hard register. lower-subreg never breaks up pseudo to pseudo moves
> that are larger than word mode. According to richard sandiford, this
> bug also appears on the neon, but i do not know if there is a bugzilla
> for it. It also appears on my private port, which is why i am
> interested in it.
>
> in the particular case of pr52543 and my port, this happens because
> the input arguments are hard regs.
>
> The offending code is in can_decompose_p. The problem is that if the
> reg is a hard reg, it completely blows off all of the information that
> it accumulated during the first pass and unconditionally splits the
> register (assuming it is legal to do so).
>
> My question for the list, what is the predicate that we want to
> replace the code that always decomposes hardregs (assuming it is
> legal). In the case of the neon and my port, decomposing costs 4x
> more than using a wide move. I assume the avr is similar.
I don't think can_decompose_p would be the right thing to change. If
that function returns false, resolve_simple_move is still going to split
up the move. You need to change resolve_simple_move. In fact, looking
at resolve_simple_move, I don't think it will break up the register
unless it has already decided to do so:
/* If we didn't have any big SUBREGS of decomposed registers, and
neither side of the move is a register we are decomposing, then
we don't have to do anything here. */
if (src == SET_SRC (set)
&& dest == SET_DEST (set)
&& !resolve_reg_p (src)
&& !resolve_subreg_p (src)
&& !resolve_reg_p (dest)
&& !resolve_subreg_p (dest))
{
end_sequence ();
return insn;
}
So I think you need to analyze this a bit more. I don't think that is
the offending code.
Ian