> 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

Reply via email to