https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118795
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rsandifo at gcc dot gnu.org --- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> --- With (simplify (vec_perm @0 @1 VECTOR_CST@2) ... we have /* Generate a canonical form of the selector. */ if (!ins && sel.encoding () != builder) { /* Some targets are deficient and fail to expand a single argument permutation while still allowing an equivalent 2-argument version. */ tree oldop2 = op2; if (sel.ninputs () == 2 || can_vec_perm_const_p (result_mode, op_mode, sel, false)) op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel); else { vec_perm_indices sel2 (builder, 2, nelts); if (can_vec_perm_const_p (result_mode, op_mode, sel2, false)) op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel2); else /* Not directly supported with either encoding, so use the preferred form. */ op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel); where the last case can generate a not supported permute and the ninputs == 2 guard is botched. I think sth like the following was intended, but it doesn't fix the testcase. diff --git a/gcc/match.pd b/gcc/match.pd index ad966766376..f5caa472411 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -11043,15 +11043,14 @@ and, argument permutation while still allowing an equivalent 2-argument version. */ tree oldop2 = op2; - if (sel.ninputs () == 2 - || can_vec_perm_const_p (result_mode, op_mode, sel, false)) + if (can_vec_perm_const_p (result_mode, op_mode, sel, false)) op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel); - else + else if (sel.ninputs () == 1) { vec_perm_indices sel2 (builder, 2, nelts); if (can_vec_perm_const_p (result_mode, op_mode, sel2, false)) op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel2); - else + else if (optimize_vectors_before_lowering_p ()) /* Not directly supported with either encoding, so use the preferred form. */ op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel); I'll note that RTL expansion does /* Always specify two input vectors here and leave the target to handle cases in which the inputs are equal. Not all backends can cope with the single-input representation when testing for a double-input target instruction. */ vec_perm_indices indices (sel, 2, GET_MODE_NUNITS (mode)); so the above target support checks might be "wrong" in this sense if it matters at all which the above suggests.