https://gcc.gnu.org/g:a45e7022288dfd1f42b55216fd3995b4fded83f6
commit r17-5413-ga45e7022288dfd1f42b55216fd3995b4fded83f6 Author: Christopher Bazley <[email protected]> Date: Thu Jul 30 14:56:41 2026 +0000 AArch64/SVE: Regression tests for use of 'rev' instead of BB SLP Three new tests verify that GCC still generates 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. Diff: --- .../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(+) 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 000000000000..fb07c2b86c57 --- /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 000000000000..358017b65872 --- /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 000000000000..dbddaebf1e93 --- /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]; +}
