diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 99021a82df4..6912de9b43c 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -10541,15 +10541,33 @@ fold_vec_perm (tree type, tree arg0, tree arg1, const vec_perm_indices &sel) unsigned HOST_WIDE_INT nelts; bool need_ctor = false; - if (!sel.length ().is_constant (&nelts)) - return NULL_TREE; - gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (type), nelts) - && known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)), nelts) - && known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)), nelts)); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (type), + sel.length ())); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)), + TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)))); + if (TREE_TYPE (TREE_TYPE (arg0)) != TREE_TYPE (type) || TREE_TYPE (TREE_TYPE (arg1)) != TREE_TYPE (type)) return NULL_TREE; + /* If result vector has greater length than input vector, + then allow permuting two vectors as long as: + a) sel.nelts_per_pattern == 1 + b) sel.npatterns == len of input vector. + The intent is to permute input vectors, and + dup the elements in resulting vector to target vector length. */ + + if (maybe_gt (TYPE_VECTOR_SUBPARTS (type), + TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)))) + { + nelts = sel.encoding ().npatterns (); + if (sel.encoding ().nelts_per_pattern () != 1 + || (!known_eq (nelts, TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0))))) + return NULL_TREE; + } + else if (!sel.length ().is_constant (&nelts)) + return NULL_TREE; + tree *in_elts = XALLOCAVEC (tree, nelts * 2); if (!vec_cst_ctor_to_array (arg0, nelts, in_elts) || !vec_cst_ctor_to_array (arg1, nelts, in_elts + nelts)) diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc index 47371d8bcbe..7e706857f43 100644 --- a/gcc/tree-pretty-print.cc +++ b/gcc/tree-pretty-print.cc @@ -2602,6 +2602,9 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags, pp_space (pp); } } + if (VECTOR_TYPE_P (TREE_TYPE (node)) + && !TYPE_VECTOR_SUBPARTS (TREE_TYPE (node)).is_constant ()) + pp_string (pp, ", ... "); pp_right_brace (pp); } break;