arm: Add missing vec_cmp and vcond patterns
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 1 Oct 2020 16:41:15 +0000 (17:41 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Thu, 1 Oct 2020 16:41:15 +0000 (17:41 +0100)
commitc2978b3405884e38429c1937f416753ca88d3cd6
treefe6e29c08a7fdea3978d40ea566b34a25f356093
parent92f2c04d382c325f9930ab12e1b7c7d680222ae3
arm: Add missing vec_cmp and vcond patterns

This patch does several things at once:

(1) Add vector compare patterns (vec_cmp and vec_cmpu).

(2) Add vector selects between floating-point modes when the
    values being compared are integers (affects vcond and vcondu).

(3) Add vector selects between integer modes when the values being
    compared are floating-point (affects vcond).

(4) Add standalone vector select patterns (vcond_mask).

(5) Tweak the handling of compound comparisons with zeros.

Unfortunately it proved too difficult (for me) to separate this
out into a series of smaller patches, since everything is so
inter-related.  Defining only some of the new patterns does
not leave things in a happy state.

The handling of comparisons is mostly taken from the vcond patterns.
This means that it remains non-compliant with IEEE: “quiet” comparisons
use signalling instructions.  But that shouldn't matter for floats,
since we require -funsafe-math-optimizations to vectorize for them
anyway.

It remains the case that comparisons and selects aren't implemented
at all for HF vectors.  Implementing those feels like separate work.

gcc/
PR target/96528
PR target/97288
* config/arm/arm-protos.h (arm_expand_vector_compare): Declare.
(arm_expand_vcond): Likewise.
* config/arm/arm.c (arm_expand_vector_compare): New function.
(arm_expand_vcond): Likewise.
* config/arm/neon.md (vec_cmp<VDQW:mode><v_cmp_result>): New pattern.
(vec_cmpu<VDQW:mode><VDQW:mode>): Likewise.
(vcond<VDQW:mode><VDQW:mode>): Require operand 5 to be a register
or zero.  Use arm_expand_vcond.
(vcond<V_cvtto><V32:mode>): New pattern.
(vcondu<VDQIW:mode><VDQIW:mode>): Generalize to...
(vcondu<VDQW:mode><v_cmp_result): ...this.  Require operand 5
to be a register or zero.  Use arm_expand_vcond.
(vcond_mask_<VDQW:mode><v_cmp_result>): New pattern.
(neon_vc<cmp_op><mode>, neon_vc<cmp_op><mode>_insn): Add "@" marker.
(neon_vbsl<mode>): Likewise.
(neon_vc<cmp_op>u<mode>): Reexpress as...
(@neon_vc<code><mode>): ...this.

gcc/testsuite/
* lib/target-supports.exp (check_effective_target_vect_cond_mixed): Add
arm neon targets.
* gcc.target/arm/neon-compare-1.c: New test.
* gcc.target/arm/neon-compare-2.c: Likewise.
* gcc.target/arm/neon-compare-3.c: Likewise.
* gcc.target/arm/neon-compare-4.c: Likewise.
* gcc.target/arm/neon-compare-5.c: Likewise.
* gcc.target/arm/neon-vcond-gt.c: Expect comparisons with zero.
* gcc.target/arm/neon-vcond-ltgt.c: Likewise.
* gcc.target/arm/neon-vcond-unordered.c: Likewise.
12 files changed:
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/neon.md
gcc/testsuite/gcc.target/arm/neon-compare-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/neon-compare-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/neon-compare-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/neon-compare-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/neon-compare-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/neon-vcond-gt.c
gcc/testsuite/gcc.target/arm/neon-vcond-ltgt.c
gcc/testsuite/gcc.target/arm/neon-vcond-unordered.c
gcc/testsuite/lib/target-supports.exp