aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDennis Zhang <dennis.zh@live.com>2020-10-22 01:27:31 +0100
committerDennis Zhang <dennis.zh@live.com>2020-10-22 01:27:31 +0100
commit76835dca95ab9f3f106a0db1e6152ad0740b38b3 (patch)
tree2256c95a661d1cda77d3fc324411095f5d4bb46b /gcc
parent966fdb2e12c0347aa3f9efaf5f4e1cd8237fa024 (diff)
downloadgcc-76835dca95ab9f3f106a0db1e6152ad0740b38b3.zip
gcc-76835dca95ab9f3f106a0db1e6152ad0740b38b3.tar.gz
gcc-76835dca95ab9f3f106a0db1e6152ad0740b38b3.tar.bz2
arm: Auto-vectorization for MVE: vmin/vmax
This patch enables MVE vmin/vmax instructions for auto-vectorization. MVE target is included in expander smin<mode>3, umin<mode>3, smax<mode>3 and umax<mode>3 for vectorization. Related insns for vmin/vmax in mve.md are modified to use smin, umin, smax and umax expressions instead of unspec to support the expanders. gcc/ChangeLog: 2020-10-22 Dennis Zhang <dennis.zhang@arm.com> * config/arm/mve.md (mve_vmaxq_<supf><mode>): Replace with ... (mve_vmaxq_s<mode>, mve_vmaxq_u<mode>): ... these new insns to use smax/umax instead of VMAXQ. (mve_vminq_<supf><mode>): Replace with ... (mve_vminq_s<mode>, mve_vminq_u<mode>): ... these new insns to use smin/umin instead of VMINQ. (mve_vmaxnmq_f<mode>): Use smax instead of VMAXNMQ_F. (mve_vminnmq_f<mode>): Use smin instead of VMINNMQ_F. * config/arm/vec-common.md (smin<mode>3): Use the new mode macros ARM_HAVE_<MODE>_ARITH. (umin<mode>3, smax<mode>3, umax<mode>3): Likewise. gcc/testsuite/ChangeLog: * gcc.target/arm/simd/mve-vminmax_1.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/arm/mve.md50
-rw-r--r--gcc/config/arm/vec-common.md26
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/mve-vminmax_1.c61
5 files changed, 121 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d6a326c..59fa1ad 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,19 @@
2020-10-22 Dennis Zhang <dennis.zhang@arm.com>
+ * config/arm/mve.md (mve_vmaxq_<supf><mode>): Replace with ...
+ (mve_vmaxq_s<mode>, mve_vmaxq_u<mode>): ... these new insns to
+ use smax/umax instead of VMAXQ.
+ (mve_vminq_<supf><mode>): Replace with ...
+ (mve_vminq_s<mode>, mve_vminq_u<mode>): ... these new insns to
+ use smin/umin instead of VMINQ.
+ (mve_vmaxnmq_f<mode>): Use smax instead of VMAXNMQ_F.
+ (mve_vminnmq_f<mode>): Use smin instead of VMINNMQ_F.
+ * config/arm/vec-common.md (smin<mode>3): Use the new mode macros
+ ARM_HAVE_<MODE>_ARITH.
+ (umin<mode>3, smax<mode>3, umax<mode>3): Likewise.
+
+2020-10-22 Dennis Zhang <dennis.zhang@arm.com>
+
* config/arm/mve.md (mve_vmulq<mode>): New entry for vmul instruction
using expression 'mult'.
(mve_vmulq_f<mode>): Use mult instead of VMULQ_F.
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 764e201..47c34b9 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -1329,15 +1329,25 @@
;;
;; [vmaxq_u, vmaxq_s])
;;
-(define_insn "mve_vmaxq_<supf><mode>"
+(define_insn "mve_vmaxq_s<mode>"
[
(set (match_operand:MVE_2 0 "s_register_operand" "=w")
- (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "w")
- (match_operand:MVE_2 2 "s_register_operand" "w")]
- VMAXQ))
+ (smax:MVE_2 (match_operand:MVE_2 1 "s_register_operand" "w")
+ (match_operand:MVE_2 2 "s_register_operand" "w")))
+ ]
+ "TARGET_HAVE_MVE"
+ "vmax.%#<V_s_elem>\t%q0, %q1, %q2"
+ [(set_attr "type" "mve_move")
+])
+
+(define_insn "mve_vmaxq_u<mode>"
+ [
+ (set (match_operand:MVE_2 0 "s_register_operand" "=w")
+ (umax:MVE_2 (match_operand:MVE_2 1 "s_register_operand" "w")
+ (match_operand:MVE_2 2 "s_register_operand" "w")))
]
"TARGET_HAVE_MVE"
- "vmax.<supf>%#<V_sz_elem>\t%q0, %q1, %q2"
+ "vmax.%#<V_u_elem>\t%q0, %q1, %q2"
[(set_attr "type" "mve_move")
])
@@ -1389,15 +1399,25 @@
;;
;; [vminq_s, vminq_u])
;;
-(define_insn "mve_vminq_<supf><mode>"
+(define_insn "mve_vminq_s<mode>"
[
(set (match_operand:MVE_2 0 "s_register_operand" "=w")
- (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "w")
- (match_operand:MVE_2 2 "s_register_operand" "w")]
- VMINQ))
+ (smin:MVE_2 (match_operand:MVE_2 1 "s_register_operand" "w")
+ (match_operand:MVE_2 2 "s_register_operand" "w")))
]
"TARGET_HAVE_MVE"
- "vmin.<supf>%#<V_sz_elem>\t%q0, %q1, %q2"
+ "vmin.%#<V_s_elem>\t%q0, %q1, %q2"
+ [(set_attr "type" "mve_move")
+])
+
+(define_insn "mve_vminq_u<mode>"
+ [
+ (set (match_operand:MVE_2 0 "s_register_operand" "=w")
+ (umin:MVE_2 (match_operand:MVE_2 1 "s_register_operand" "w")
+ (match_operand:MVE_2 2 "s_register_operand" "w")))
+ ]
+ "TARGET_HAVE_MVE"
+ "vmin.%#<V_u_elem>\t%q0, %q1, %q2"
[(set_attr "type" "mve_move")
])
@@ -2393,9 +2413,8 @@
(define_insn "mve_vmaxnmq_f<mode>"
[
(set (match_operand:MVE_0 0 "s_register_operand" "=w")
- (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "w")
- (match_operand:MVE_0 2 "s_register_operand" "w")]
- VMAXNMQ_F))
+ (smax:MVE_0 (match_operand:MVE_0 1 "s_register_operand" "w")
+ (match_operand:MVE_0 2 "s_register_operand" "w")))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
"vmaxnm.f%#<V_sz_elem> %q0, %q1, %q2"
@@ -2453,9 +2472,8 @@
(define_insn "mve_vminnmq_f<mode>"
[
(set (match_operand:MVE_0 0 "s_register_operand" "=w")
- (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "w")
- (match_operand:MVE_0 2 "s_register_operand" "w")]
- VMINNMQ_F))
+ (smin:MVE_0 (match_operand:MVE_0 1 "s_register_operand" "w")
+ (match_operand:MVE_0 2 "s_register_operand" "w")))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
"vminnm.f%#<V_sz_elem> %q0, %q1, %q2"
diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md
index 45db60e..0f117d6 100644
--- a/gcc/config/arm/vec-common.md
+++ b/gcc/config/arm/vec-common.md
@@ -111,39 +111,29 @@
[(set (match_operand:VALLW 0 "s_register_operand")
(smin:VALLW (match_operand:VALLW 1 "s_register_operand")
(match_operand:VALLW 2 "s_register_operand")))]
- "(TARGET_NEON && ((<MODE>mode != V2SFmode && <MODE>mode != V4SFmode)
- || flag_unsafe_math_optimizations))
- || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))"
-{
-})
+ "ARM_HAVE_<MODE>_ARITH"
+)
(define_expand "umin<mode>3"
[(set (match_operand:VINTW 0 "s_register_operand")
(umin:VINTW (match_operand:VINTW 1 "s_register_operand")
(match_operand:VINTW 2 "s_register_operand")))]
- "TARGET_NEON
- || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))"
-{
-})
+ "ARM_HAVE_<MODE>_ARITH"
+)
(define_expand "smax<mode>3"
[(set (match_operand:VALLW 0 "s_register_operand")
(smax:VALLW (match_operand:VALLW 1 "s_register_operand")
(match_operand:VALLW 2 "s_register_operand")))]
- "(TARGET_NEON && ((<MODE>mode != V2SFmode && <MODE>mode != V4SFmode)
- || flag_unsafe_math_optimizations))
- || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))"
-{
-})
+ "ARM_HAVE_<MODE>_ARITH"
+)
(define_expand "umax<mode>3"
[(set (match_operand:VINTW 0 "s_register_operand")
(umax:VINTW (match_operand:VINTW 1 "s_register_operand")
(match_operand:VINTW 2 "s_register_operand")))]
- "TARGET_NEON
- || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))"
-{
-})
+ "ARM_HAVE_<MODE>_ARITH"
+)
(define_expand "vec_perm<mode>"
[(match_operand:VE 0 "s_register_operand")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index eb55a64..304d44c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2020-10-22 Dennis Zhang <dennis.zhang@arm.com>
+ * gcc.target/arm/simd/mve-vminmax_1.c: New test.
+
+2020-10-22 Dennis Zhang <dennis.zhang@arm.com>
+
* gcc.target/arm/simd/mve-vmul_1.c: New test.
2020-10-20 Jeff Law <law@redhat.com>
diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vminmax_1.c b/gcc/testsuite/gcc.target/arm/simd/mve-vminmax_1.c
new file mode 100644
index 0000000..6c8e7d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/mve-vminmax_1.c
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-options "-O3" } */
+/* { dg-add-options arm_v8_1m_mve } */
+
+#include <stdint.h>
+
+#define MAX(a, b) ((a) > (b)) ? (a) : (b)
+#define MIN(a, b) ((a) < (b)) ? (a) : (b)
+
+
+#define TEST_BINOP(OP, TY, N) \
+ TY test_##OP##_##TY (TY * dest, TY * a, TY * b) \
+ { \
+ int i; \
+ for (i=0; i<N; i++) \
+ { \
+ dest[i] = OP (a[i], b[i]); \
+ } \
+ }
+
+/* Test vmax. */
+
+TEST_BINOP (MAX, int32_t, 4)
+/* { dg-final { scan-assembler-times {vmax\.s32\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MAX, uint32_t, 4)
+/* { dg-final { scan-assembler-times {vmax\.u32\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MAX, int16_t, 8)
+/* { dg-final { scan-assembler-times {vmax\.s16\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MAX, uint16_t, 8)
+/* { dg-final { scan-assembler-times {vmax\.u16\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MAX, int8_t, 16)
+/* { dg-final { scan-assembler-times {vmax\.s8\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MAX, uint8_t, 16)
+/* { dg-final { scan-assembler-times {vmax\.u8\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+/* Test vmin. */
+
+TEST_BINOP (MIN, int32_t, 4)
+/* { dg-final { scan-assembler-times {vmin\.s32\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MIN, uint32_t, 4)
+/* { dg-final { scan-assembler-times {vmin\.u32\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MIN, int16_t, 8)
+/* { dg-final { scan-assembler-times {vmin\.s16\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MIN, uint16_t, 8)
+/* { dg-final { scan-assembler-times {vmin\.u16\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MIN, int8_t, 16)
+/* { dg-final { scan-assembler-times {vmin\.s8\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+
+TEST_BINOP (MIN, uint8_t, 16)
+/* { dg-final { scan-assembler-times {vmin\.u8\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+