> 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