This is the mail archive of the
mailing list for the GCC project.
- From: Ian Lance Taylor <iant at google dot com>
- To: Kenneth Zadeck <zadeck at naturalbridge dot com>
- Cc: gcc-patches <gcc at gcc dot gnu dot org>, Richard Sandiford <r dot sandiford at uk dot ibm dot com>, Mike Stump <mikestump at comcast dot net>, Kenneth Zadeck <Kenneth dot Zadeck at NaturalBridge dot com>, avr at gjlay dot de
- Date: Mon, 19 Mar 2012 22:13:56 -0700
- Subject: Re: pr52543
- References: <4F67D595.firstname.lastname@example.org>
Kenneth Zadeck <email@example.com> 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))
So I think you need to analyze this a bit more. I don't think that is
the offending code.