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.

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.
---

Bootstrapped and regtested on loongarch64-linux-gnu.  Ok for trunk?

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

diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index 66359949a42..0d561cc665e 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -1598,7 +1598,7 @@ (define_insn "lsx_vshuf4i_<lsxfmt_f>"
   [(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 9e686846514..ced79fe6f50 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -684,7 +684,7 @@ (define_predicate "const_vector_neg_fp_operand"
                                                       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 00000000000..a76748ae0cb
--- /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);
+}
-- 
2.55.0

Reply via email to