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)))) + *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; +} -- 2.43.0