https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126200
--- Comment #3 from WANG Xuerui <xen0n at gentoo dot org> ---
Dumped pr126200.c.280r.fwprop1:
(insn 7 3 11 2 (set (reg:V16QI 81 [ <retval> ])
(vec_select:V16QI (reg/v:V16QI 82 [ in ])
(parallel [
(const_int 1 [0x1])
(const_int 3 [0x3])
(const_int 5 [0x5])
(const_int 7 [0x7])
(const_int 9 [0x9])
(const_int 11 [0xb])
(const_int 13 [0xd])
(const_int 15 [0xf])
(const_int 1 [0x1])
(const_int 3 [0x3])
(const_int 5 [0x5])
(const_int 7 [0x7])
(const_int 9 [0x9])
(const_int 11 [0xb])
(const_int 13 [0xd])
(const_int 15 [0xf])
])))
"../../gcc/testsuite/gcc.target/loongarch/vector/lsx/pr126200.c":10:10 1322
{lsx_vshuf4i_b}
(nil))
This is wrong -- this shuffle pattern cannot be realized by a single vshuf4i.b
insn. Looking at loongarch_const_vector_shuffle_set_p in loongarch.cc:
/* Check if we have the same 4-element sets. */
for (j = 0; j < nsets; j++, set = 4 * j)
for (i = 0; i < 4; i++)
if ((INTVAL (XVECEXP (op, 0, i))
!= (INTVAL (XVECEXP (op, 0, set + i)) - set))
|| !IN_RANGE (INTVAL (XVECEXP (op, 0, set + i)), 0, set + 3))
return false;
The code was copied from mips/mips.cc and the IN_RANGE check is buggy: should
check if the value falls between *set* and (set + 3). Weird thing is I tried
this change but the bug didn't disappear; I had to rewrite the function to
derive the expected vshuf4i control word from the first group of 4, and then
compare the remaining groups with it.