[PATCH v2] RISC-V: Reject non-monotonic shuffle masks in slide patterns [PR126411]

Souradipto Das <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
shuffle_slide_patterns did not verify that the endpoints of a combined
slideup+slidedown sequence actually correspond to OP0's and OP1's
expected positions, allowing a non-monotonic shuffle mask to be
accepted as a valid slide pattern. This produced wrong code at -O0
for masks such as { 7, 0, 7, 0 } on a 4-element vector, as reported
in PR target/126411.

This patch checks that d->perm[0] and d->perm[vlen - 1] correspond
to the expected OP0/OP1 boundary positions (vlen - slideup_cnt and
2 * vlen - 1 - slideup_cnt respectively), and rejects the pattern
otherwise. need_slideup_p is also added to the existing second-pivot
rejection check.

gcc/ChangeLog:

	PR target/126411
	* config/riscv/riscv-v.cc (shuffle_slide_patterns): Check that
	the sequence endpoints correspond to OP0's and OP1's expected
	positions and also reject a second pivot when need_slideup_p is set.

gcc/testsuite/ChangeLog:

	PR target/126411
	* gcc.target/riscv/rvv/base/bug126411.c: New test.

Suggested-by: Raphael M Zinsly <[email protected]>
Signed-off-by: Souradipto Das <[email protected]>
---
**No llm generated code was used to arrive at this patch.
Changes in V2
	*Added the comment on need_slideup_p referring to riscv specifications.
	*Improved the run test by adding effective-target check and riscv_v_ok.

 gcc/config/riscv/riscv-v.cc                      | 10 ++++++++--
 .../gcc.target/riscv/rvv/base/bug126411.c        | 16 ++++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug126411.c

diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index d8d20925dd5..3614d310cbd 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3829,6 +3829,11 @@ shuffle_slide_patterns (struct expand_vec_perm_d *d)
 	}
       else
 	return false;
+
+      /* Check if the beginning and end of the sequence corresponds to OP0 and OP1 respectively */
+      if (!(known_eq (d->perm[0], vlen - slideup_cnt) && known_eq (d->perm[vlen - 1], 2 * vlen - 1 - slideup_cnt)))
+	return false;
+
     }
 
   /* Check for a monotonic sequence with one or two pivots.  */
@@ -3841,8 +3846,9 @@ shuffle_slide_patterns (struct expand_vec_perm_d *d)
       if (i > 0 && i != pivot
 	  && maybe_ne (d->perm[i], d->perm[i - 1] + 1))
 	{
-	  /* A second pivot would indicate the vector length and is in OP0.  */
-	  if (known_ge (d->perm[i], vec_len) || pivot == -1 || len != 0)
+	  /* A second pivot would indicate the vector length and is in OP0. Also a second pivot would indicate
+             three or more monotonic sequences in the given permuatation which cannot be handled by slideup function. */
+	  if (known_ge (d->perm[i], vec_len) || pivot == -1 || len != 0 || need_slideup_p)
 	    return false;
 	  len = i;
 	}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug126411.c b/gcc/testsuite/gcc.target/riscv/rvv/base/bug126411.c
new file mode 100644
index 00000000000..3d42835174b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug126411.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-require-effective-target riscv_v_ok } */
+/* { dg-additional-options " -O0 " } */
+
+#include <stdint.h>
+
+typedef int8_t v4i8 __attribute__((vector_size(4)));
+v4i8 g2 = { 7, 0, 8, 70 }, g12;
+
+int main()
+{
+    g12 = __builtin_shufflevector(g2, g2, 7, 0, 7, 0);
+    if (g12[2] != 70)
+      __builtin_abort();
+    return 0;
+}
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.