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; > +}