aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2023-05-15 09:55:44 +0100
committerKyrylo Tkachov <kyrylo.tkachov@arm.com>2023-05-15 09:55:44 +0100
commite90791e5a02b021d22ffb4c36673b9af623e2063 (patch)
treeb5f51ed43487cd5687023fd889b7c6de8de4634f
parent676d33f95eede2dfa629c9b0174c15cc55c4a45a (diff)
downloadgcc-e90791e5a02b021d22ffb4c36673b9af623e2063.zip
gcc-e90791e5a02b021d22ffb4c36673b9af623e2063.tar.gz
gcc-e90791e5a02b021d22ffb4c36673b9af623e2063.tar.bz2
aarch64: PR target/99195 annotate vector compare patterns for vec-concat-zero
This instalment of the series goes through the vector comparison patterns in the backend. One wart are the int64x1_t comparisons that this patch doesn't touch. Those are a bit trickier because they have define_insn_and_split mechanisms for falling back to GP reg comparisons after reload and I don't think a simple annotation will catch those cases correctly. Those will need more custom thinking. As said, this patch doesn't touch those and is a decent straightforward improvement on its own. Bootstrapped and tested on aarch64-none-linux-gnu and aarch64_be-none-elf. gcc/ChangeLog: PR target/99195 * config/aarch64/aarch64-simd.md (aarch64_cm<optab><mode>): Rename to... (aarch64_cm<optab><mode><vczle><vczbe>): ... This. (aarch64_cmtst<mode>): Rename to... (aarch64_cmtst<mode><vczle><vczbe>): ... This. (*aarch64_cmtst_same_<mode>): Rename to... (*aarch64_cmtst_same_<mode><vczle><vczbe>): ... This. (*aarch64_cmtstdi): Rename to... (*aarch64_cmtstdi<vczle><vczbe>): ... This. (aarch64_fac<optab><mode>): Rename to... (aarch64_fac<optab><mode><vczle><vczbe>): ... This. gcc/testsuite/ChangeLog: PR target/99195 * gcc.target/aarch64/simd/pr99195_7.c: New test.
-rw-r--r--gcc/config/aarch64/aarch64-simd.md14
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/pr99195_7.c96
2 files changed, 103 insertions, 7 deletions
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 26320f2..61c815b 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -6615,7 +6615,7 @@
;; Note, we have constraints for Dz and Z as different expanders
;; have different ideas of what should be passed to this pattern.
-(define_insn "aarch64_cm<optab><mode>"
+(define_insn "aarch64_cm<optab><mode><vczle><vczbe>"
[(set (match_operand:<V_INT_EQUIV> 0 "register_operand" "=w,w")
(neg:<V_INT_EQUIV>
(COMPARISONS:<V_INT_EQUIV>
@@ -6680,7 +6680,7 @@
;; cm(hs|hi)
-(define_insn "aarch64_cm<optab><mode>"
+(define_insn "aarch64_cm<optab><mode><vczle><vczbe>"
[(set (match_operand:<V_INT_EQUIV> 0 "register_operand" "=w")
(neg:<V_INT_EQUIV>
(UCOMPARISONS:<V_INT_EQUIV>
@@ -6747,7 +6747,7 @@
;; which is rewritten by simplify_rtx as
;; plus (eq (and x y) 0) -1.
-(define_insn "aarch64_cmtst<mode>"
+(define_insn "aarch64_cmtst<mode><vczle><vczbe>"
[(set (match_operand:<V_INT_EQUIV> 0 "register_operand" "=w")
(plus:<V_INT_EQUIV>
(eq:<V_INT_EQUIV>
@@ -6766,7 +6766,7 @@
;; not (neq (eq x 0)) in which case you rewrite it to
;; a comparison against itself
-(define_insn "*aarch64_cmtst_same_<mode>"
+(define_insn "*aarch64_cmtst_same_<mode><vczle><vczbe>"
[(set (match_operand:<V_INT_EQUIV> 0 "register_operand" "=w")
(plus:<V_INT_EQUIV>
(eq:<V_INT_EQUIV>
@@ -6817,7 +6817,7 @@
[(set_attr "type" "neon_tst,multiple")]
)
-(define_insn "*aarch64_cmtstdi"
+(define_insn "*aarch64_cmtstdi<vczle><vczbe>"
[(set (match_operand:DI 0 "register_operand" "=w")
(neg:DI
(ne:DI
@@ -6832,7 +6832,7 @@
;; fcm(eq|ge|gt|le|lt)
-(define_insn "aarch64_cm<optab><mode>"
+(define_insn "aarch64_cm<optab><mode><vczle><vczbe>"
[(set (match_operand:<V_INT_EQUIV> 0 "register_operand" "=w,w")
(neg:<V_INT_EQUIV>
(COMPARISONS:<V_INT_EQUIV>
@@ -6850,7 +6850,7 @@
;; Note we can also handle what would be fac(le|lt) by
;; generating fac(ge|gt).
-(define_insn "aarch64_fac<optab><mode>"
+(define_insn "aarch64_fac<optab><mode><vczle><vczbe>"
[(set (match_operand:<V_INT_EQUIV> 0 "register_operand" "=w")
(neg:<V_INT_EQUIV>
(FAC_COMPARISONS:<V_INT_EQUIV>
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/pr99195_7.c b/gcc/testsuite/gcc.target/aarch64/simd/pr99195_7.c
new file mode 100644
index 0000000..86bd729
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/pr99195_7.c
@@ -0,0 +1,96 @@
+/* PR target/99195. */
+/* Check that we take advantage of 64-bit Advanced SIMD operations clearing
+ the top half of the vector register and no explicit zeroing instructions
+ are emitted. */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+#include <arm_neon.h>
+
+#define MYOP(OT,IT,IMT,OP,IS,OS) \
+OT \
+foo_##OP##_##OS##_##IT##_##IS (IT a, IT b) \
+{ \
+ IMT zeros = vcreate_##OS (0); \
+ return vcombine_##OS (v##OP##_##IS (a, b), zeros); \
+}
+
+#define FUNC(OT,IT,IMT,IS,OS) \
+MYOP (OT, IT, IMT, ceq, IS, OS) \
+MYOP (OT, IT, IMT, clt, IS, OS) \
+MYOP (OT, IT, IMT, cge, IS, OS) \
+MYOP (OT, IT, IMT, cle, IS, OS) \
+MYOP (OT, IT, IMT, cgt, IS, OS) \
+MYOP (OT, IT, IMT, tst, IS, OS)
+
+#define MYFUNC(PFX, T, S, N, DN) \
+FUNC (uint##S##x##DN##_t, T##S##x##N##_t, uint##S##x##N##_t, PFX##S, u##S)
+
+MYFUNC (s, int, 8, 8, 16)
+MYFUNC (s, int, 16, 4, 8)
+MYFUNC (s, int, 32, 2, 4)
+MYFUNC (u, uint, 8, 8, 16)
+MYFUNC (u, uint, 16, 4, 8)
+MYFUNC (u, uint, 32, 2, 4)
+
+#undef FUNC
+#define FUNC(OT,IT,IMT,IS,OS) \
+MYOP (OT, IT, IMT, ceq, IS, OS) \
+MYOP (OT, IT, IMT, clt, IS, OS) \
+MYOP (OT, IT, IMT, cge, IS, OS) \
+MYOP (OT, IT, IMT, cle, IS, OS) \
+MYOP (OT, IT, IMT, cgt, IS, OS)
+
+
+#pragma GCC push_options
+#pragma GCC target ("arch=armv8.2-a+fp16")
+MYFUNC (f, float, 16, 4, 8)
+#pragma GCC pop_options
+MYFUNC (f, float, 32, 2, 4)
+MYFUNC (f, float, 64, 1, 2)
+
+#undef FUNC
+#define FUNC(OT,IT,IMT,IS,OS) \
+MYOP (OT, IT, IMT, cale, IS, OS) \
+MYOP (OT, IT, IMT, cagt, IS, OS) \
+MYOP (OT, IT, IMT, calt, IS, OS) \
+MYOP (OT, IT, IMT, cage, IS, OS) \
+
+#pragma GCC push_options
+#pragma GCC target ("arch=armv8.2-a+fp16")
+MYFUNC (f, float, 16, 4, 8)
+#pragma GCC pop_options
+MYFUNC (f, float, 32, 2, 4)
+MYFUNC (f, float, 64, 1, 2)
+
+#undef MYOP
+#define MYOP(OT,IT,IMT,OP,IS,OS) \
+OT \
+foo_##OP##_##OS##_##IT##_z (IT a) \
+{ \
+ IMT zeros = vcreate_##OS (0); \
+ return vcombine_##OS (v##OP##_##IS (a), zeros); \
+}
+
+#undef FUNC
+#define FUNC(OT,IT,IMT,IS,OS) \
+MYOP (OT, IT, IMT, cltz, IS, OS) \
+MYOP (OT, IT, IMT, ceqz, IS, OS) \
+MYOP (OT, IT, IMT, cgez, IS, OS) \
+MYOP (OT, IT, IMT, cgtz, IS, OS) \
+MYOP (OT, IT, IMT, clez, IS, OS) \
+
+MYFUNC (s, int, 8, 8, 16)
+MYFUNC (s, int, 16, 4, 8)
+MYFUNC (s, int, 32, 2, 4)
+
+#pragma GCC push_options
+#pragma GCC target ("arch=armv8.2-a+fp16")
+MYFUNC (f, float, 16, 4, 8)
+#pragma GCC pop_options
+MYFUNC (f, float, 32, 2, 4)
+MYFUNC (f, float, 64, 1, 2)
+
+/* { dg-final { scan-assembler-not {\tfmov\t} } } */
+/* { dg-final { scan-assembler-not {\tmov\t} } } */
+