Andrew Pinski <quic_apin...@quicinc.com> writes:
> The middle-end uses rtx_cost on constants with the outer of being COMPARE
> to find out the cost of a constant formation for a comparison instruction.
> So for aarch64 backend, we would just return the cost of constant formation
> in general. We can improve this by seeing if the outer is COMPARE and if
> the constant fits the constraints of the cmp instruction just set the costs
> to being one instruction.
>
> Built and tested for aarch64-linux-gnu.
>
>       PR target/120372
>
> gcc/ChangeLog:
>
>       * config/aarch64/aarch64.cc (aarch64_rtx_costs <case CONST_INSN>): 
> Handle
>       if outer is COMPARE and the constant can be handled by the cmp 
> instruction.
>
> gcc/testsuite/ChangeLog:
>
>       * gcc.target/aarch64/imm_choice_comparison-2.c: New test.
>
> Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
> ---
>  gcc/config/aarch64/aarch64.cc                 |  7 ++
>  .../aarch64/imm_choice_comparison-2.c         | 90 +++++++++++++++++++
>  2 files changed, 97 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/imm_choice_comparison-2.c
>
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 1da615c8955..c747ad42ac4 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -14578,6 +14578,13 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int 
> outer ATTRIBUTE_UNUSED,
>        we don't need to consider that here.  */
>        if (x == const0_rtx)
>       *cost = 0;
> +      /* If the outer is a COMPARE which is used by the middle-end
> +      and the constant fits how the cmp instruction allows, say the cost
> +      is the same as 1 insn.  */
> +      else if (outer == COMPARE
> +            && (aarch64_uimm12_shift (INTVAL (x))
> +                || aarch64_uimm12_shift (- (unsigned HOST_WIDE_INT) INTVAL 
> (x))))

Would be shorter as -UINTVAL.

OK with that change, thanks.

Richard

> +     *cost = COSTS_N_INSNS (1);
>        else
>       {
>         /* To an approximation, building any other constant is
> diff --git a/gcc/testsuite/gcc.target/aarch64/imm_choice_comparison-2.c 
> b/gcc/testsuite/gcc.target/aarch64/imm_choice_comparison-2.c
> new file mode 100644
> index 00000000000..379fc50563c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/imm_choice_comparison-2.c
> @@ -0,0 +1,90 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +/* PR target/120372 */
> +
> +/* Go from 2 moves to none.  */
> +
> +/*
> +** GT:
> +**   ...
> +**   cmp     w0, 11182080
> +**   ...
> +*/
> +
> +int
> +GT (unsigned int x)
> +{
> +  return x > 0xaa9fff;
> +}
> +
> +/*
> +** LE:
> +**   ...
> +**   cmp     w0, 11182080
> +**   ...
> +*/
> +
> +int
> +LE (unsigned int x)
> +{
> +  return x <= 0xaa9fff;
> +}
> +
> +/*
> +** GE:
> +**   ...
> +**   cmp     x0, 11182080
> +**   ...
> +*/
> +
> +int
> +GE (long long x)
> +{
> +  return x >= 0xaaa000;
> +}
> +
> +/*
> +** LT:
> +**   ...
> +**   cmp     w0, 11182080
> +**   ...
> +*/
> +
> +int
> +LT (int x)
> +{
> +  return x < 0xaaa000;
> +}
> +
> +/* Optimize the immediate in conditionals.  */
> +
> +/*
> +** check:
> +**   ...
> +**   cmp     w0, 11182080
> +**   ...
> +*/
> +
> +int
> +check (int x, int y)
> +{
> +  if (x > y && GT (x))
> +    return 100;
> +
> +  return x;
> +}
> +
> +/*
> +** tern:
> +**   ...
> +**   cmp     w0, 11182080
> +**   ...
> +*/
> +
> +int
> +tern (int x)
> +{
> +  return x >= 0xaaa000 ? 5 : -3;
> +}

Reply via email to