> This has passed bootstrap and regtesting on powerpc64le-linux with no > regressions. Is this ok for mainline? > > Peter > > gcc/ > PR rtl-optimization/87507 > * lower-subreg.c (simple_move_operator): New function. > (simple_move): Strip simple operators. > (find_pseudo_copy): Likewise. > (resolve_simple_move): Strip simple operators and swap operands. > > gcc/testsuite/ > PR rtl-optimization/87507 > * gcc.target/powerpc/pr87507.c: New test. > * gcc.target/powerpc/pr68805.c: Update expected results.
OK for mainline modulo the following nits: > Index: gcc/lower-subreg.c > =================================================================== > --- gcc/lower-subreg.c (revision 265971) > +++ gcc/lower-subreg.c (working copy) > @@ -320,6 +320,24 @@ simple_move_operand (rtx x) > return true; > } > > +/* If X is an operator that can be treated as a simple move that we > + can split, then return the operand that is operated on. */ > + > +static rtx > +simple_move_operator (rtx x) > +{ > + /* A word sized rotate of a register pair is equivalent to swapping > + the registers in the register pair. */ > + if (GET_CODE (x) == ROTATE > + && GET_MODE (x) == twice_word_mode > + && simple_move_operand (XEXP (x, 0)) > + && CONST_INT_P (XEXP (x, 1)) > + && INTVAL (XEXP (x, 1)) == BITS_PER_WORD) > + return XEXP (x, 0);; > + > + return NULL_RTX; > +} > + Superfluous semi-colon. Given that the function returns an operand, its name is IMO misleading, so maybe [get_]operand_for_simple_move_operator. > @@ -876,6 +901,33 @@ resolve_simple_move (rtx set, rtx_insn * > > real_dest = NULL_RTX; > > + if ((src_op = simple_move_operator (src)) != NULL_RTX) > + { > + if (resolve_reg_p (dest)) > + { > + /* DEST is a CONCATN, so swap its operands and strip > + SRC's operator. */ > + rtx concatn = copy_rtx (dest); > + rtx op0 = XVECEXP (concatn, 0, 0); > + rtx op1 = XVECEXP (concatn, 0, 1); > + XVECEXP (concatn, 0, 0) = op1; > + XVECEXP (concatn, 0, 1) = op0; > + dest = concatn; > + src = src_op; > + } > + else if (resolve_reg_p (src_op)) > + { > + /* SRC is an operation on a CONCATN, so strip the operator and > + swap the CONCATN's operands. */ > + rtx concatn = copy_rtx (src_op); > + rtx op0 = XVECEXP (concatn, 0, 0); > + rtx op1 = XVECEXP (concatn, 0, 1); > + XVECEXP (concatn, 0, 0) = op1; > + XVECEXP (concatn, 0, 1) = op0; > + src = concatn; > + } > + } > + Can we factor out the duplicate manipulation into a function here, for example resolve_operand_for_simple_move_operator? -- Eric Botcazou