aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r--gcc/gimple-fold.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 66aced6..99f265e 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6079,13 +6079,13 @@ gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
}
else if (TREE_CODE (rhs) == CONSTRUCTOR
&& TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
- && (CONSTRUCTOR_NELTS (rhs)
- == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
+ && known_eq (CONSTRUCTOR_NELTS (rhs),
+ TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
{
unsigned i, nelts;
tree val;
- nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs));
+ nelts = CONSTRUCTOR_NELTS (rhs);
tree_vector_builder vec (TREE_TYPE (rhs), nelts, 1);
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
{
@@ -6930,8 +6930,8 @@ gimple_fold_indirect_ref (tree t)
= tree_to_shwi (part_width) / BITS_PER_UNIT;
unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
tree index = bitsize_int (indexi);
- if (offset / part_widthi
- < TYPE_VECTOR_SUBPARTS (TREE_TYPE (addrtype)))
+ if (known_lt (offset / part_widthi,
+ TYPE_VECTOR_SUBPARTS (TREE_TYPE (addrtype))))
return fold_build3 (BIT_FIELD_REF, type, TREE_OPERAND (addr, 0),
part_width, index);
}
@@ -7233,6 +7233,10 @@ tree
gimple_build_vector_from_val (gimple_seq *seq, location_t loc, tree type,
tree op)
{
+ if (!TYPE_VECTOR_SUBPARTS (type).is_constant ()
+ && !CONSTANT_CLASS_P (op))
+ return gimple_build (seq, loc, VEC_DUPLICATE_EXPR, type, op);
+
tree res, vec = build_vector_from_val (type, op);
if (is_gimple_val (vec))
return vec;
@@ -7265,7 +7269,7 @@ gimple_build_vector (gimple_seq *seq, location_t loc,
if (!TREE_CONSTANT ((*builder)[i]))
{
tree type = builder->type ();
- unsigned int nelts = TYPE_VECTOR_SUBPARTS (type);
+ unsigned int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
vec<constructor_elt, va_gc> *v;
vec_alloc (v, nelts);
for (i = 0; i < nelts; ++i)