[gcc r17-2510] LoongArch: fix par_const_vector_shf_set_operand for vshuf4i [PR 126200]

Xi Ruoyao via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:6abaf53d84db86bd917d18cac5aac3c3bf37929c

commit r17-2510-g6abaf53d84db86bd917d18cac5aac3c3bf37929c
Author: Xi Ruoyao <[email protected]>
Date:   Tue Jul 14 15:03:19 2026 +0800

    LoongArch: fix par_const_vector_shf_set_operand for vshuf4i [PR 126200]
    
    The logic of par_const_vector_shf_set_operand (actually,
    loongarch_const_vector_shuffle_set_p) expect mode to have the same
    element count as the shuffled vector.  But the lsx_vshuf4i_<lsxfmt_f>
    definition have VOIDmode for the mode of the selector, thus the
    predicate actually accepts anything.  The issue was somehow latent until
    recently fwprop1 seems improved on folding two vec_select into one.
    
    Change par_const_vector_shf_set_operand to a special predicate so we can
    specify a mode different from the actual mode of the selector parallel
    (in VOIDmode) to the predicate.  Then specify VIMODE to satisfy the
    expectation of loongarch_const_vector_shuffle_set_p.
    
            PR target/126200
    
    gcc/
    
            * config/loongarch/predicates.md
            (par_const_vector_shf_set_operand): Define as special predicate.
            * config/loongarch/lsx.md (lsx_vshuf4i_<lsxfmt_f>): Pass VIMODE
            to the predicate of selector.
    
    gcc/testsuite/
    
            * gcc.target/loongarch/vector/lsx/pr126200.c: New test.

Diff:
---
 gcc/config/loongarch/lsx.md                              |  2 +-
 gcc/config/loongarch/predicates.md                       |  2 +-
 gcc/testsuite/gcc.target/loongarch/vector/lsx/pr126200.c | 11 +++++++++++
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index 66359949a42b..0d561cc665e7 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -1598,7 +1598,7 @@
   [(set (match_operand:LSX_WHB_W 0 "register_operand" "=f")
 	(vec_select:LSX_WHB_W
 	  (match_operand:LSX_WHB_W 1 "register_operand" "f")
-	  (match_operand 2 "par_const_vector_shf_set_operand" "")))]
+	  (match_operand:<VIMODE>  2 "par_const_vector_shf_set_operand" "")))]
   "ISA_HAS_LSX"
 {
   HOST_WIDE_INT val = 0;
diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md
index 9e6868465147..ced79fe6f502 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -684,7 +684,7 @@
 						       op));
 })
 
-(define_predicate "par_const_vector_shf_set_operand"
+(define_special_predicate "par_const_vector_shf_set_operand"
   (match_code "parallel")
 {
   return loongarch_const_vector_shuffle_set_p (op, mode);
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr126200.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr126200.c
new file mode 100644
index 000000000000..a76748ae0cbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr126200.c
@@ -0,0 +1,11 @@
+/* { dg-do assemble } */
+/* { dg-options "-O2 -mlsx" } */
+
+typedef signed char v16i8 __attribute__ ((vector_size (16), aligned (16)));
+
+v16i8
+lsx_convert_utf16_to_utf8 (v16i8 in)
+{
+  v16i8 x = __builtin_lsx_vshuf4i_b (in, 0b10110001);
+  return __builtin_lsx_vpickev_b (x, x);
+}
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.