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

Jeff Law via Gcc-cvs <[email protected]> Mon, 3 Aug 2026 03:58:38 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:779eed50ec701e84137a007f1afcafa9936fb9b7

commit r17-2890-g779eed50ec701e84137a007f1afcafa9936fb9b7
Author: Souradipto Das <[email protected]>
Date:   Sun Aug 2 21:58:01 2026 -0600

    [PATCH v2] RISC-V: Reject non-monotonic shuffle masks in slide patterns [PR126411]
    
    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.
    
            PR target/126411
    gcc/ChangeLog:
    
            * 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:
    
            * gcc.target/riscv/rvv/base/bug126411.c: New test.
    
    Suggested-by: Raphael M Zinsly <[email protected]>
    Signed-off-by: Souradipto Das <[email protected]>

Diff:
---
 gcc/config/riscv/riscv-v.cc                         | 17 +++++++++++++++--
 gcc/testsuite/gcc.target/riscv/rvv/base/bug126411.c | 16 ++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index d8d20925dd5c..5644ac270c6c 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3829,6 +3829,13 @@ 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 +3848,14 @@ 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 permutation 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 000000000000..3d42835174b2
--- /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;
+}