if (vr1->operands == vr2->operands)
return true;
- if (COMPLETE_TYPE_P (vr1->type) != COMPLETE_TYPE_P (vr2->type)
- || (COMPLETE_TYPE_P (vr1->type)
- && !expressions_equal_p (TYPE_SIZE (vr1->type),
- TYPE_SIZE (vr2->type))))
+ if (!vr1->type || !vr2->type)
+ {
+ if (vr1->type != vr2->type)
+ return false;
+ }
+ else if (COMPLETE_TYPE_P (vr1->type) != COMPLETE_TYPE_P (vr2->type)
+ || (COMPLETE_TYPE_P (vr1->type)
+ && !expressions_equal_p (TYPE_SIZE (vr1->type),
+ TYPE_SIZE (vr2->type))))
return false;
-
- if (INTEGRAL_TYPE_P (vr1->type)
- && INTEGRAL_TYPE_P (vr2->type))
+ else if (INTEGRAL_TYPE_P (vr1->type)
+ && INTEGRAL_TYPE_P (vr2->type))
{
if (TYPE_PRECISION (vr1->type) != TYPE_PRECISION (vr2->type))
return false;
poly_offset_int size = -1;
tree size_tree = NULL_TREE;
+ /* We don't handle calls. */
+ if (!type)
+ return false;
+
machine_mode mode = TYPE_MODE (type);
if (mode == BLKmode)
size_tree = TYPE_SIZE (type);
/* Simplify reads from constants or constant initializers. */
else if (BITS_PER_UNIT == 8
+ && ref->type
&& COMPLETE_TYPE_P (ref->type)
&& is_gimple_reg_type (ref->type))
{
vr->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
vr->operands = valueize_shared_reference_ops_from_call (call);
- vr->type = gimple_expr_type (call);
+ tree lhs = gimple_call_lhs (call);
+ /* For non-SSA return values the referece ops contain the LHS. */
+ vr->type = ((lhs && TREE_CODE (lhs) == SSA_NAME)
+ ? TREE_TYPE (lhs) : NULL_TREE);
vr->punned = false;
vr->set = 0;
vr->base_set = 0;
expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f,
tree type, tree inner_type,
tree a, tree b, enum tree_code code,
- tree ret_type = NULL_TREE)
+ bool parallel_p, tree ret_type = NULL_TREE)
{
vec<constructor_elt, va_gc> *v;
tree part_width = TYPE_SIZE (inner_type);
int i;
location_t loc = gimple_location (gsi_stmt (*gsi));
- if (ret_type
- || types_compatible_p (gimple_expr_type (gsi_stmt (*gsi)), type))
+ if (ret_type || !parallel_p)
warning_at (loc, OPT_Wvector_operation_performance,
"vector operation will be expanded piecewise");
else
if (TYPE_MODE (TREE_TYPE (type)) == word_mode)
return expand_vector_piecewise (gsi, f,
type, TREE_TYPE (type),
- a, b, code);
+ a, b, code, true);
else if (n_words > 1)
{
tree word_type = build_word_mode_vector_type (n_words);
result = expand_vector_piecewise (gsi, f,
word_type, TREE_TYPE (word_type),
- a, b, code);
+ a, b, code, true);
result = force_gimple_operand_gsi (gsi, result, true, NULL, true,
GSI_SAME_STMT);
}
else
return expand_vector_piecewise (gsi, f,
type, TREE_TYPE (type),
- a, b, code);
+ a, b, code, false);
}
static bool
else
t = expand_vector_piecewise (gsi, do_compare, type,
TREE_TYPE (TREE_TYPE (op0)), op0, op1,
- code);
+ code, false);
}
else
t = NULL_TREE;
if (TREE_CODE_CLASS (code) == tcc_unary)
return expand_vector_piecewise (gsi, do_unop, type, compute_type,
gimple_assign_rhs1 (assign),
- NULL_TREE, code);
+ NULL_TREE, code, false);
else
return expand_vector_piecewise (gsi, do_binop, type, compute_type,
gimple_assign_rhs1 (assign),
- gimple_assign_rhs2 (assign), code);
+ gimple_assign_rhs2 (assign), code, false);
}
/* Try to optimize
COND_EXPR);
else
new_rhs = expand_vector_piecewise (gsi, do_cond, type, compute_type,
- rhs2, rhs3, COND_EXPR);
+ rhs2, rhs3, COND_EXPR, false);
if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_rhs)))
new_rhs = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
new_rhs);
{
new_rhs = expand_vector_piecewise (gsi, do_vec_conversion,
ret_type, arg1_type, arg,
- NULL_TREE, code1);
+ NULL_TREE, code1, false);
g = gimple_build_assign (lhs, new_rhs);
gsi_replace (gsi, g, false);
return;
do_vec_narrow_conversion,
arg_type, dcompute_type,
arg, NULL_TREE, code1,
- ret_type);
+ false, ret_type);
g = gimple_build_assign (lhs, new_rhs);
gsi_replace (gsi, g, false);
return;
new_rhs = expand_vector_piecewise (gsi, do_vec_conversion, arg_type,
TREE_TYPE (arg_type), arg,
- NULL_TREE, code, ret_type);
+ NULL_TREE, code, false, ret_type);
g = gimple_build_assign (lhs, new_rhs);
gsi_replace (gsi, g, false);
}