arm: Auto-vectorization for MVE: vcmp
authorChristophe Lyon <christophe.lyon@linaro.org>
Mon, 17 May 2021 12:29:42 +0000 (12:29 +0000)
committerChristophe Lyon <christophe.lyon@linaro.org>
Mon, 17 May 2021 12:30:20 +0000 (12:30 +0000)
commita6eacbf1055520e968d1a25f6d30d6ff4b66272d
tree8722d4dbe99fdb161c30bbd13d8a0c481157fd15
parent45063c0506a00f2673049d46f12a6061dca4692f
arm: Auto-vectorization for MVE: vcmp

Since MVE has a different set of vector comparison operators from
Neon, we have to update the expansion to take into account the new
ones, for instance 'NE' for which MVE does not require to use 'EQ'
with the inverted condition.

Conversely, Neon supports comparisons with #0, MVE does not.

For:
typedef long int vs32 __attribute__((vector_size(16)));
vs32 cmp_eq_vs32_reg (vs32 a, vs32 b) { return a == b; }

we now generate:
cmp_eq_vs32_reg:
vldr.64 d4, .L123       @ 8     [c=8 l=4]  *mve_movv4si/8
vldr.64 d5, .L123+8
vldr.64 d6, .L123+16    @ 9     [c=8 l=4]  *mve_movv4si/8
vldr.64 d7, .L123+24
vcmp.i32  eq, q0, q1    @ 7     [c=16 l=4]  mve_vcmpeqq_v4si
vpsel q0, q3, q2        @ 15    [c=8 l=4]  mve_vpselq_sv4si
bx      lr      @ 26    [c=8 l=4]  *thumb2_return
.L124:
.align  3
.L123:
.word   0
.word   0
.word   0
.word   0
.word   1
.word   1
.word   1
.word   1

For some reason emit_move_insn (zero, CONST0_RTX (cmp_mode)) produces
a pair of vldr instead of vmov.i32, qX, #0

2021-05-17  Christophe Lyon  <christophe.lyon@linaro.org>

gcc/
* config/arm/arm-protos.h (arm_expand_vector_compare): Update
prototype.
* config/arm/arm.c (arm_expand_vector_compare): Add support for
MVE.
(arm_expand_vcond): Likewise.
* config/arm/iterators.md (supf): Remove VCMPNEQ_S, VCMPEQQ_S,
VCMPEQQ_N_S, VCMPNEQ_N_S.
(VCMPNEQ, VCMPEQQ, VCMPEQQ_N, VCMPNEQ_N): Remove.
* config/arm/mve.md (@mve_vcmp<mve_cmp_op>q_<mode>): Add '@' prefix.
(@mve_vcmp<mve_cmp_op>q_f<mode>): Likewise.
(@mve_vcmp<mve_cmp_op>q_n_f<mode>): Likewise.
(@mve_vpselq_<supf><mode>): Likewise.
(@mve_vpselq_f<mode>"): Likewise.
* config/arm/neon.md (vec_cmp<mode><v_cmp_result): Enable for MVE
and move to vec-common.md.
(vec_cmpu<mode><mode>): Likewise.
(vcond<mode><mode>): Likewise.
(vcond<V_cvtto><mode>): Likewise.
(vcondu<mode><v_cmp_result>): Likewise.
(vcond_mask_<mode><v_cmp_result>): Likewise.
* config/arm/unspecs.md (VCMPNEQ_U, VCMPNEQ_S, VCMPEQQ_S)
(VCMPEQQ_N_S, VCMPNEQ_N_S, VCMPEQQ_U, CMPEQQ_N_U, VCMPNEQ_N_U)
(VCMPGEQ_N_S, VCMPGEQ_S, VCMPGTQ_N_S, VCMPGTQ_S, VCMPLEQ_N_S)
(VCMPLEQ_S, VCMPLTQ_N_S, VCMPLTQ_S, VCMPCSQ_N_U, VCMPCSQ_U)
(VCMPHIQ_N_U, VCMPHIQ_U): Remove.
* config/arm/vec-common.md (vec_cmp<mode><v_cmp_result): Moved
from neon.md.
(vec_cmpu<mode><mode>): Likewise.
(vcond<mode><mode>): Likewise.
(vcond<V_cvtto><mode>): Likewise.
(vcondu<mode><v_cmp_result>): Likewise.
(vcond_mask_<mode><v_cmp_result>): Likewise. Added unsafe math
condition.

gcc/testsuite
* gcc.target/arm/simd/mve-compare-1.c: New test with GCC vectors.
* gcc.target/arm/simd/mve-compare-2.c: New test with GCC vectors.
* gcc.target/arm/simd/mve-compare-scalar-1.c: New test with GCC
vectors.
* gcc.target/arm/simd/mve-vcmp-f32.c: New test for
auto-vectorization.
* gcc.target/arm/simd/mve-vcmp.c: New test for auto-vectorization.
12 files changed:
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/iterators.md
gcc/config/arm/mve.md
gcc/config/arm/neon.md
gcc/config/arm/unspecs.md
gcc/config/arm/vec-common.md
gcc/testsuite/gcc.target/arm/simd/mve-compare-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/mve-compare-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/mve-compare-scalar-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/mve-vcmp-f32.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c [new file with mode: 0644]