Hi all,
This patch enables MVE vmin/vmax instructions for auto-vectorization.
MVE target is included in expander smin3, umin3, smax3
and umax3 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.
Regression tested on arm-none-eabi and bootstraped on
arm-none-linux-gnueabihf.
Is it OK for trunk please?
Thanks
Dennis
gcc/ChangeLog:
2020-10-02 Dennis Zhang
* config/arm/mve.md (mve_vmaxq_): Replace with ...
(mve_vmaxq_s, mve_vmaxq_u): ... these new insns to
use smax/umax instead of VMAXQ.
(mve_vminq_): Replace with ...
(mve_vminq_s, mve_vminq_u): ... these new insns to
use smin/umin instead of VMINQ.
(mve_vmaxnmq_f): Use smax instead of VMAXNMQ_F.
(mve_vminnmq_f): Use smin instead of VMINNMQ_F.
* config/arm/vec-common.md (smin3): Use the new mode macros
ARM_HAVE__ARITH.
(umin3, smax3, umax3): Likewise.
gcc/testsuite/ChangeLog:
2020-10-02 Dennis Zhang
* gcc.target/arm/simd/mve-vminmax_1.c: New test.
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 3a57901bd5b..0d9f932e983 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -1977,15 +1977,25 @@
;;
;; [vmaxq_u, vmaxq_s])
;;
-(define_insn "mve_vmaxq_"
+(define_insn "mve_vmaxq_s"
[
(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.%#\t%q0, %q1, %q2"
+ [(set_attr "type" "mve_move")
+])
+
+(define_insn "mve_vmaxq_u"
+ [
+ (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.%#\t%q0, %q1, %q2"
+ "vmax.%#\t%q0, %q1, %q2"
[(set_attr "type" "mve_move")
])
@@ -2037,15 +2047,25 @@
;;
;; [vminq_s, vminq_u])
;;
-(define_insn "mve_vminq_"
+(define_insn "mve_vminq_s"
[
(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.%#\t%q0, %q1, %q2"
+ "vmin.%#\t%q0, %q1, %q2"
+ [(set_attr "type" "mve_move")
+])
+
+(define_insn "mve_vminq_u"
+ [
+ (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.%#\t%q0, %q1, %q2"
[(set_attr "type" "mve_move")
])
@@ -3030,9 +3050,8 @@
(define_insn "mve_vmaxnmq_f"
[
(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%# %q0, %q1, %q2"
@@ -3090,9 +3109,8 @@
(define_insn "mve_vminnmq_f"
[
(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%# %q0, %q1, %q2"
diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md
index c3c86c46355..6a330cc82f6 100644
--- a/gcc/config/arm/vec-common.md
+++ b/gcc/config/arm/vec-common.md
@@ -114,39 +114,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 != V2SFmode && mode != V4SFmode)
- || flag_unsafe_math_optimizations))
- || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))"
-{
-})
+ "ARM_HAVE__ARITH"
+)
(define_expand "umin3"
[(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))"
-{
-})
+ "ARM_HAVE__ARITH"
+)
(define_expand "smax3"
[(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