https://gcc.gnu.org/g:a17e06fa2ab5776de129d35418e05039bd9a51b1
commit r16-5117-ga17e06fa2ab5776de129d35418e05039bd9a51b1 Author: Robin Dapp <[email protected]> Date: Fri Nov 7 10:21:36 2025 +0100 optabs: Do not pun modes smaller than QImode. In can_vec_perm_const_p if we cannot directly permute a vector mode we try to pun it with a byte mode. qimode_for_vec_perm checks gets the mode size and uses that as number of elements for the new QImode vector. This doesn't work for RVV mask vectors, though. First, their precision might be smaller than a byte and second, there is no way to easily pun them. The most common way would be a vector select from {0, 0, ...} and {1, 1, ...} vectors. Therefore this patch checks if the perm's innermode precision is a multiple of QImode's precision. Bootstrapped and regtested on x86 and power10. Regtested on aarch64 and riscv64. gcc/ChangeLog: * optabs-query.cc (qimode_for_vec_perm): Check if QImode's precision divides the inner mode's precision. Diff: --- gcc/optabs-query.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc index 5335d0d8401a..484d7c2e205f 100644 --- a/gcc/optabs-query.cc +++ b/gcc/optabs-query.cc @@ -358,7 +358,9 @@ can_conditionally_move_p (machine_mode mode) opt_machine_mode qimode_for_vec_perm (machine_mode mode) { - if (GET_MODE_INNER (mode) != QImode) + if (GET_MODE_INNER (mode) != QImode + && multiple_p (GET_MODE_PRECISION (GET_MODE_INNER (mode)), + GET_MODE_PRECISION (QImode))) return related_vector_mode (mode, QImode, GET_MODE_SIZE (mode)); return opt_machine_mode (); }
