Neon vector comparisons have a dedicated version when comparing with constant zero: it means its cost is free.
Adjust the cost in arm_rtx_costs_internal accordingly, for Neon only, since MVE does not support this. 2021-01-26 Christophe Lyon <christophe.l...@linaro.org> gcc/ PR target/98730 * config/arm/arm.c (arm_rtx_costs_internal): Adjust cost of vector of constant zero for comparisons. gcc/testsuite/ PR target/98730 * gcc.target/arm/simd/vceqzq_p64.c: Update expected result. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 4a5f265..9c5c0df 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -11544,7 +11544,28 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode))) || TARGET_HAVE_MVE) && simd_immediate_valid_for_move (x, mode, NULL, NULL)) - *cost = COSTS_N_INSNS (1); + { + *cost = COSTS_N_INSNS (1); + + /* Neon has special instructions when comparing with 0 (vceq, vcge, + vcgt, vcle and vclt). */ + if (TARGET_NEON && (x == CONST0_RTX (mode))) + { + switch (outer_code) + { + case EQ: + case GE: + case GT: + case LE: + case LT: + *cost = COSTS_N_INSNS (0); + break; + + default: + break; + } + } + } else *cost = COSTS_N_INSNS (4); return true; diff --git a/gcc/testsuite/gcc.target/arm/simd/vceqzq_p64.c b/gcc/testsuite/gcc.target/arm/simd/vceqzq_p64.c index 640754c..a99bb8a 100644 --- a/gcc/testsuite/gcc.target/arm/simd/vceqzq_p64.c +++ b/gcc/testsuite/gcc.target/arm/simd/vceqzq_p64.c @@ -15,4 +15,4 @@ void func() result2 = vceqzq_p64 (v2); } -/* { dg-final { scan-assembler-times "vceq\.i32\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+\n" 2 } } */ +/* { dg-final { scan-assembler-times "vceq\.i32\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+, #0\n" 2 } } */
arm-rtx-cost-vceq.patch2
Description: Binary data