Three new tests verify that GCC generates still code that uses
the 'rev' instruction instead of using predicated vector tails
to vectorise 32-bit byte-order-reversal code.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/sve/slp_rev_32_1.c: New test.
* gcc.target/aarch64/sve/slp_rev_32_2.c: New test.
* gcc.target/aarch64/sve/slp_rev_32_3.c: New test.
---
.../gcc.target/aarch64/sve/slp_rev_32_1.c | 25 ++++++++++++++++
.../gcc.target/aarch64/sve/slp_rev_32_2.c | 29 +++++++++++++++++++
.../gcc.target/aarch64/sve/slp_rev_32_3.c | 26 +++++++++++++++++
3 files changed, 80 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_1.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_2.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_3.c
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_1.c
b/gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_1.c
new file mode 100644
index 00000000000..fb07c2b86c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_1.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -march=armv8.2-a+sve" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* If the compiler mistakenly vectorizes byte order reversal
+ * then the resultant code is inevitably less efficient than a
+ * rev instruction. Guard against such regressions.
+ */
+typedef unsigned int __u32;
+typedef unsigned char __u8;
+
+/*
+** rev:
+** rev w1, w1
+** str w1, \[x0\]
+** ret
+*/
+void
+rev (__u8 (*dst)[4], __u32 src)
+{
+ (*dst)[0] = src >> 24;
+ (*dst)[1] = src >> 16;
+ (*dst)[2] = src >> 8;
+ (*dst)[3] = src >> 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_2.c
b/gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_2.c
new file mode 100644
index 00000000000..358017b6587
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_2.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -march=armv8.2-a+sve" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* If the compiler mistakenly vectorizes byte order reversal
+ * then the resultant code is inevitably less efficient than a
+ * rev instruction. Guard against such regressions.
+ */
+typedef unsigned int __u32;
+typedef unsigned char __u8;
+
+/*
+** rev2:
+** ldr w0, \[x0\]
+** rev w0, w0
+** ret
+*/
+__u32
+rev2 (const __u8 (*src)[4])
+{
+ __u32 dst = 0;
+
+ dst |= (__u32) (*src)[3] << 0;
+ dst |= (__u32) (*src)[2] << 8;
+ dst |= (__u32) (*src)[1] << 16;
+ dst |= (__u32) (*src)[0] << 24;
+
+ return dst;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_3.c
b/gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_3.c
new file mode 100644
index 00000000000..dbddaebf1e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_rev_32_3.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -march=armv8.2-a+sve" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* If the compiler mistakenly vectorizes byte order reversal
+ * then the resultant code is inevitably less efficient than a
+ * rev instruction. Guard against such regressions.
+ */
+typedef unsigned char __u8;
+
+/*
+** rev3:
+** ldr w1, \[x1\]
+** rev w1, w1
+** str w1, \[x0\]
+** ret
+*/
+void
+rev3 (unsigned char (*__restrict dst)[4],
+ const unsigned char (*__restrict src)[4])
+{
+ (*dst)[0] = (*src)[3];
+ (*dst)[1] = (*src)[2];
+ (*dst)[2] = (*src)[1];
+ (*dst)[3] = (*src)[0];
+}
--
2.43.0