[gcc(refs/users/clyon/heads/mve-autovec)] arm: MVE vcmp auto-vectorization
Christophe Lyon
clyon@gcc.gnu.org
Mon Mar 1 22:00:47 GMT 2021
https://gcc.gnu.org/g:926004d51d97e6a1044468cfb7cd5426493e13d5
commit 926004d51d97e6a1044468cfb7cd5426493e13d5
Author: Christophe Lyon <christophe.lyon@linaro.org>
Date: Mon Mar 1 16:54:24 2021 +0000
arm: MVE vcmp auto-vectorization
Diff:
---
gcc/config/arm/arm.c | 7 ++--
gcc/config/arm/neon.md | 13 -------
gcc/config/arm/vec-common.md | 18 ++++++++++
gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c | 53 ++++++++++++++++++++++++++++
4 files changed, 76 insertions(+), 15 deletions(-)
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f3424800f24..8f7843a973f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -31038,8 +31038,11 @@ arm_expand_vcond (rtx *operands, machine_mode cmp_result_mode)
operands[4], operands[5], true);
if (inverted)
std::swap (operands[1], operands[2]);
- emit_insn (gen_neon_vbsl (GET_MODE (operands[0]), operands[0],
- mask, operands[1], operands[2]));
+ if (TARGET_NEON)
+ emit_insn (gen_neon_vbsl (GET_MODE (operands[0]), operands[0],
+ mask, operands[1], operands[2]));
+ else
+ emit_insn (gen_rtx_SET (operands[0], mask));
}
#define MAX_VECT_LEN 16
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 903f4b2d0eb..c6ca2859ec2 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -1439,19 +1439,6 @@
DONE;
})
-(define_expand "vcond_mask_<mode><v_cmp_result>"
- [(set (match_operand:VDQW 0 "s_register_operand")
- (if_then_else:VDQW
- (match_operand:<V_cmp_result> 3 "s_register_operand")
- (match_operand:VDQW 1 "s_register_operand")
- (match_operand:VDQW 2 "s_register_operand")))]
- "TARGET_NEON"
-{
- emit_insn (gen_neon_vbsl<mode> (operands[0], operands[3], operands[1],
- operands[2]));
- DONE;
-})
-
;; Patterns for builtins.
; good for plain vadd, vaddq.
diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md
index 9d784760a0d..5b13049b6a3 100644
--- a/gcc/config/arm/vec-common.md
+++ b/gcc/config/arm/vec-common.md
@@ -422,3 +422,21 @@
DONE;
})
+(define_expand "vcond_mask_<mode><v_cmp_result>"
+ [(set (match_operand:VDQW 0 "s_register_operand")
+ (if_then_else:VDQW
+ (match_operand:<V_cmp_result> 3 "s_register_operand")
+ (match_operand:VDQW 1 "s_register_operand")
+ (match_operand:VDQW 2 "s_register_operand")))]
+ "TARGET_NEON || TARGET_HAVE_MVE"
+{
+ if (TARGET_NEON) {
+ emit_insn (gen_neon_vbsl(<MODE>mode, operands[0], operands[3], operands[1],
+ operands[2]));
+ }
+ else if (TARGET_HAVE_MVE) {
+ emit_insn (gen_mve_vpselq(VPSELQ_S, <MODE>mode, operands[0], operands[1],
+ operands[2], operands[3]));
+ }
+ DONE;
+})
diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c
new file mode 100644
index 00000000000..49b864f292d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c
@@ -0,0 +1,53 @@
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O3" } */
+
+#include <stdint.h>
+
+#define FUNC(SIGN, TYPE, BITS, NB, OP, NAME) \
+ void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t * __restrict__ dest, TYPE##BITS##_t *a, TYPE##BITS##_t *b) { \
+ int i; \
+ for (i=0; i<NB; i++) { \
+ dest[i] = a[i] OP b[i]; \
+ } \
+}
+
+#define ALL_FUNCS(OP, NAME) \
+ FUNC(s, int, 32, 2, OP, NAME) \
+ FUNC(u, uint, 32, 2, OP, NAME) \
+ FUNC(s, int, 16, 4, OP, NAME) \
+ FUNC(u, uint, 16, 4, OP, NAME) \
+ FUNC(s, int, 8, 8, OP, NAME) \
+ FUNC(u, uint, 8, 8, OP, NAME) \
+ FUNC(s, int, 32, 4, OP, NAME) \
+ FUNC(u, uint, 32, 4, OP, NAME) \
+ FUNC(s, int, 16, 8, OP, NAME) \
+ FUNC(u, uint, 16, 8, OP, NAME) \
+ FUNC(s, int, 8, 16, OP, NAME) \
+ FUNC(u, uint, 8, 16, OP, NAME)
+
+ALL_FUNCS(==, vcmpeq)
+ALL_FUNCS(!=, vcmpne)
+ALL_FUNCS(<, vcmplt)
+ALL_FUNCS(<=, vcmple)
+ALL_FUNCS(>, vcmpgt)
+ALL_FUNCS(>=, vcmpge)
+
+/* MVE has only 128-bit vectors, so we can vectorize only half of the
+ functions above. */
+/* Although float16 and float32 types are supported at assembly level,
+ we cannot test them with the '==' operator, so we check only the
+ integer variants. */
+/* { dg-final { scan-assembler-times {\tvcmp.i[0-9]+ eq, q[0-9]+, q[0-9]+\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i[0-9]+ ne, q[0-9]+, q[0-9]+\n} 6 } } */
+
+/* lt, le, gt, ge apply to signed types, cs and hi to unsigned types. */
+/* lt and le with unsigned types are replaced with the opposite condition, hence
+ the double number of matches for cs and hi. */
+/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ lt, q[0-9]+, q[0-9]+\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ le, q[0-9]+, q[0-9]+\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ gt, q[0-9]+, q[0-9]+\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ ge, q[0-9]+, q[0-9]+\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u[0-9]+ cs, q[0-9]+, q[0-9]+\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u[0-9]+ hi, q[0-9]+, q[0-9]+\n} 6 } } */
More information about the Gcc-cvs
mailing list