https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118795
--- Comment #14 from Richard Biener <rguenth at gcc dot gnu.org> --- And /* Merge c = VEC_PERM_EXPR <a, b, VCST0>; d = VEC_PERM_EXPR <c, c, VCST1>; to d = VEC_PERM_EXPR <a, b, NEW_VCST>; */ is a bit confused about constraints, but matching modes instead of TYPE_SIZE to make sure can_vec_perm_const_p are applicable doesn't fix it either. I'll note this pattern specifically uses vec_perm_indices sel1 (builder1, 1, nelts); thus single-arg - using , 2, there _does_ fix the testcase. I'm a bit confused here - we don't seem to record whether we use 1 or 2 in the IL but what we use decides on whether the target can expand or not. Richard? diff --git a/gcc/match.pd b/gcc/match.pd index ad966766376..1e78d0795fd 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -11123,8 +11122,8 @@ and, } (if (tree_to_vec_perm_builder (&builder0, @4) && tree_to_vec_perm_builder (&builder1, @5) - && TYPE_SIZE (TREE_TYPE (TREE_TYPE (@0))) - == TYPE_SIZE (TREE_TYPE (TREE_TYPE (@1)))) + && result_mode == TYPE_MODE (TREE_TYPE (@1)) + && op_mode == TYPE_MODE (TREE_TYPE (@0))) (with { vec_perm_indices sel0 (builder0, 2, nelts);