diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 99021a82df4..bc8ba4607a5 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -10541,15 +10541,24 @@ 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; + /* TODO: Handle VEC_PERM_EXPR with differing lengths. */ + if (!known_eq (TYPE_VECTOR_SUBPARTS (type), + TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)))) + return NULL_TREE; + + /* TODO: Handle VLA vectors. */ + 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/match.pd b/gcc/match.pd index 330c1db0c8e..aa20cc713c5 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -7845,6 +7845,12 @@ and, (with { tree op0 = @0, op1 = @1, op2 = @2; + + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (type), + TYPE_VECTOR_SUBPARTS (TREE_TYPE (op2)))); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op0)), + TYPE_VECTOR_SUBPARTS (TREE_TYPE (op1)))); + machine_mode result_mode = TYPE_MODE (type); machine_mode op_mode = TYPE_MODE (TREE_TYPE (op0)); diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index fdc4bc8909d..4b693ef095c 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -2661,7 +2661,9 @@ simplify_permutation (gimple_stmt_iterator *gsi) /* Shuffle of a constructor. */ bool ret = false; - tree res_type = TREE_TYPE (arg0); + tree res_type + = build_vector_type (TREE_TYPE (TREE_TYPE (arg0)), + TYPE_VECTOR_SUBPARTS (TREE_TYPE (op2))); tree opt = fold_ternary (VEC_PERM_EXPR, res_type, arg0, arg1, op2); if (!opt || (TREE_CODE (opt) != CONSTRUCTOR && TREE_CODE (opt) != VECTOR_CST))