Kenneth Zadeck <zad...@naturalbridge.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)) { 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