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