expr.c (expand_expr_real_2): Move COND_EXPR and VEC_COND_EXPR handling here, from ...

2011-08-31  Richard Guenther  <rguenther@suse.de>

	* expr.c (expand_expr_real_2): Move COND_EXPR and VEC_COND_EXPR
	handling here, from ...
	(expand_expr_real_1): ... here.
	* gimple-pretty-print.c (dump_ternary_rhs): Handle COND_EXPR
	and VEC_COND_EXPR.
	* gimple.c (gimple_rhs_class_table): Make COND_EXPR and VEC_COND_EXPR
	a GIMPLE_TERNARY_RHS.
	* tree-cfg.c (verify_gimple_assign_ternary): Handle COND_EXPR
	and VEC_COND_EXPR here ...
	(verify_gimple_assign_single): ... not here.
	* gimple-fold.c (fold_gimple_assign): Move COND_EXPR folding.
	* tree-object-size.c (cond_expr_object_size): Adjust.
	(collect_object_sizes_for): Likewise.
	* tree-scalar-evolution.c (interpret_expr): Don't handle
	ternary RHSs.
	* tree-ssa-forwprop.c (forward_propagate_into_cond): Fix and
	simplify.
	(ssa_forward_propagate_and_combine): Adjust.
	* tree-ssa-loop-im.c (move_computations_stmt): Build the COND_EXPR
	as ternary.
	* tree-ssa-threadedge.c (fold_assignment_stmt): Adjust.
	* tree-vect-loop.c (vect_is_simple_reduction_1): Likewise.
	* tree-vect-stmt.c (vectorizable_condition): Likewise.
	* tree-vrp.c (extract_range_from_cond_expr): Likewise.
	(extract_range_from_assignment): Likewise.

From-SVN: r178408
This commit is contained in:
Richard Guenther 2011-09-01 11:46:08 +00:00 committed by Richard Biener
parent dbe36d674a
commit 4e71066d7e
14 changed files with 220 additions and 187 deletions

View File

@ -1,3 +1,31 @@
2011-08-31 Richard Guenther <rguenther@suse.de>
* expr.c (expand_expr_real_2): Move COND_EXPR and VEC_COND_EXPR
handling here, from ...
(expand_expr_real_1): ... here.
* gimple-pretty-print.c (dump_ternary_rhs): Handle COND_EXPR
and VEC_COND_EXPR.
* gimple.c (gimple_rhs_class_table): Make COND_EXPR and VEC_COND_EXPR
a GIMPLE_TERNARY_RHS.
* tree-cfg.c (verify_gimple_assign_ternary): Handle COND_EXPR
and VEC_COND_EXPR here ...
(verify_gimple_assign_single): ... not here.
* gimple-fold.c (fold_gimple_assign): Move COND_EXPR folding.
* tree-object-size.c (cond_expr_object_size): Adjust.
(collect_object_sizes_for): Likewise.
* tree-scalar-evolution.c (interpret_expr): Don't handle
ternary RHSs.
* tree-ssa-forwprop.c (forward_propagate_into_cond): Fix and
simplify.
(ssa_forward_propagate_and_combine): Adjust.
* tree-ssa-loop-im.c (move_computations_stmt): Build the COND_EXPR
as ternary.
* tree-ssa-threadedge.c (fold_assignment_stmt): Adjust.
* tree-vect-loop.c (vect_is_simple_reduction_1): Likewise.
* tree-vect-stmt.c (vectorizable_condition): Likewise.
* tree-vrp.c (extract_range_from_cond_expr): Likewise.
(extract_range_from_assignment): Likewise.
2011-08-31 Richard Sandiford <rdsandiford@googlemail.com>
* config/i386/i386.md: Use (match_test ...) for attribute tests.

View File

@ -8636,6 +8636,64 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
return temp;
}
case COND_EXPR:
/* A COND_EXPR with its type being VOID_TYPE represents a
conditional jump and is handled in
expand_gimple_cond_expr. */
gcc_assert (!VOID_TYPE_P (type));
/* Note that COND_EXPRs whose type is a structure or union
are required to be constructed to contain assignments of
a temporary variable, so that we can evaluate them here
for side effect only. If type is void, we must do likewise. */
gcc_assert (!TREE_ADDRESSABLE (type)
&& !ignore
&& TREE_TYPE (treeop1) != void_type_node
&& TREE_TYPE (treeop2) != void_type_node);
/* If we are not to produce a result, we have no target. Otherwise,
if a target was specified use it; it will not be used as an
intermediate target unless it is safe. If no target, use a
temporary. */
if (modifier != EXPAND_STACK_PARM
&& original_target
&& safe_from_p (original_target, treeop0, 1)
&& GET_MODE (original_target) == mode
#ifdef HAVE_conditional_move
&& (! can_conditionally_move_p (mode)
|| REG_P (original_target))
#endif
&& !MEM_P (original_target))
temp = original_target;
else
temp = assign_temp (type, 0, 0, 1);
do_pending_stack_adjust ();
NO_DEFER_POP;
op0 = gen_label_rtx ();
op1 = gen_label_rtx ();
jumpifnot (treeop0, op0, -1);
store_expr (treeop1, temp,
modifier == EXPAND_STACK_PARM,
false);
emit_jump_insn (gen_jump (op1));
emit_barrier ();
emit_label (op0);
store_expr (treeop2, temp,
modifier == EXPAND_STACK_PARM,
false);
emit_label (op1);
OK_DEFER_POP;
return temp;
case VEC_COND_EXPR:
target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target);
return target;
default:
gcc_unreachable ();
}
@ -9878,64 +9936,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return op0;
case COND_EXPR:
/* A COND_EXPR with its type being VOID_TYPE represents a
conditional jump and is handled in
expand_gimple_cond_expr. */
gcc_assert (!VOID_TYPE_P (type));
/* Note that COND_EXPRs whose type is a structure or union
are required to be constructed to contain assignments of
a temporary variable, so that we can evaluate them here
for side effect only. If type is void, we must do likewise. */
gcc_assert (!TREE_ADDRESSABLE (type)
&& !ignore
&& TREE_TYPE (treeop1) != void_type_node
&& TREE_TYPE (treeop2) != void_type_node);
/* If we are not to produce a result, we have no target. Otherwise,
if a target was specified use it; it will not be used as an
intermediate target unless it is safe. If no target, use a
temporary. */
if (modifier != EXPAND_STACK_PARM
&& original_target
&& safe_from_p (original_target, treeop0, 1)
&& GET_MODE (original_target) == mode
#ifdef HAVE_conditional_move
&& (! can_conditionally_move_p (mode)
|| REG_P (original_target))
#endif
&& !MEM_P (original_target))
temp = original_target;
else
temp = assign_temp (type, 0, 0, 1);
do_pending_stack_adjust ();
NO_DEFER_POP;
op0 = gen_label_rtx ();
op1 = gen_label_rtx ();
jumpifnot (treeop0, op0, -1);
store_expr (treeop1, temp,
modifier == EXPAND_STACK_PARM,
false);
emit_jump_insn (gen_jump (op1));
emit_barrier ();
emit_label (op0);
store_expr (treeop2, temp,
modifier == EXPAND_STACK_PARM,
false);
emit_label (op1);
OK_DEFER_POP;
return temp;
case VEC_COND_EXPR:
target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target);
return target;
case MODIFY_EXPR:
{
tree lhs = treeop0;

View File

@ -294,42 +294,7 @@ fold_gimple_assign (gimple_stmt_iterator *si)
{
tree rhs = gimple_assign_rhs1 (stmt);
/* Try to fold a conditional expression. */
if (TREE_CODE (rhs) == COND_EXPR)
{
tree op0 = COND_EXPR_COND (rhs);
tree tem;
bool set = false;
location_t cond_loc = EXPR_LOCATION (rhs);
if (COMPARISON_CLASS_P (op0))
{
fold_defer_overflow_warnings ();
tem = fold_binary_loc (cond_loc,
TREE_CODE (op0), TREE_TYPE (op0),
TREE_OPERAND (op0, 0),
TREE_OPERAND (op0, 1));
/* This is actually a conditional expression, not a GIMPLE
conditional statement, however, the valid_gimple_rhs_p
test still applies. */
set = (tem && is_gimple_condexpr (tem)
&& valid_gimple_rhs_p (tem));
fold_undefer_overflow_warnings (set, stmt, 0);
}
else if (is_gimple_min_invariant (op0))
{
tem = op0;
set = true;
}
else
return NULL_TREE;
if (set)
result = fold_build3_loc (cond_loc, COND_EXPR, TREE_TYPE (rhs), tem,
COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
}
else if (REFERENCE_CLASS_P (rhs))
if (REFERENCE_CLASS_P (rhs))
return maybe_fold_reference (rhs, false);
else if (TREE_CODE (rhs) == ADDR_EXPR)
@ -469,11 +434,49 @@ fold_gimple_assign (gimple_stmt_iterator *si)
break;
case GIMPLE_TERNARY_RHS:
result = fold_ternary_loc (loc, subcode,
TREE_TYPE (gimple_assign_lhs (stmt)),
gimple_assign_rhs1 (stmt),
gimple_assign_rhs2 (stmt),
gimple_assign_rhs3 (stmt));
/* Try to fold a conditional expression. */
if (gimple_assign_rhs_code (stmt) == COND_EXPR)
{
tree op0 = gimple_assign_rhs1 (stmt);
tree tem;
bool set = false;
location_t cond_loc = gimple_location (stmt);
if (COMPARISON_CLASS_P (op0))
{
fold_defer_overflow_warnings ();
tem = fold_binary_loc (cond_loc,
TREE_CODE (op0), TREE_TYPE (op0),
TREE_OPERAND (op0, 0),
TREE_OPERAND (op0, 1));
/* This is actually a conditional expression, not a GIMPLE
conditional statement, however, the valid_gimple_rhs_p
test still applies. */
set = (tem && is_gimple_condexpr (tem)
&& valid_gimple_rhs_p (tem));
fold_undefer_overflow_warnings (set, stmt, 0);
}
else if (is_gimple_min_invariant (op0))
{
tem = op0;
set = true;
}
else
return NULL_TREE;
if (set)
result = fold_build3_loc (cond_loc, COND_EXPR,
TREE_TYPE (gimple_assign_lhs (stmt)), tem,
gimple_assign_rhs2 (stmt),
gimple_assign_rhs3 (stmt));
}
if (!result)
result = fold_ternary_loc (loc, subcode,
TREE_TYPE (gimple_assign_lhs (stmt)),
gimple_assign_rhs1 (stmt),
gimple_assign_rhs2 (stmt),
gimple_assign_rhs3 (stmt));
if (result)
{

View File

@ -428,6 +428,24 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
pp_string (buffer, ">");
break;
case COND_EXPR:
dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
pp_string (buffer, " ? ");
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
pp_string (buffer, " : ");
dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
break;
case VEC_COND_EXPR:
pp_string (buffer, "VEC_COND_EXPR <");
dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
pp_string (buffer, ">");
break;
default:
gcc_unreachable ();
}

View File

@ -2611,19 +2611,19 @@ get_gimple_rhs_num_ops (enum tree_code code)
|| (SYM) == TRUTH_OR_EXPR \
|| (SYM) == TRUTH_XOR_EXPR) ? GIMPLE_BINARY_RHS \
: (SYM) == TRUTH_NOT_EXPR ? GIMPLE_UNARY_RHS \
: ((SYM) == WIDEN_MULT_PLUS_EXPR \
: ((SYM) == COND_EXPR \
|| (SYM) == WIDEN_MULT_PLUS_EXPR \
|| (SYM) == WIDEN_MULT_MINUS_EXPR \
|| (SYM) == DOT_PROD_EXPR \
|| (SYM) == REALIGN_LOAD_EXPR \
|| (SYM) == VEC_COND_EXPR \
|| (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS \
: ((SYM) == COND_EXPR \
|| (SYM) == CONSTRUCTOR \
: ((SYM) == CONSTRUCTOR \
|| (SYM) == OBJ_TYPE_REF \
|| (SYM) == ASSERT_EXPR \
|| (SYM) == ADDR_EXPR \
|| (SYM) == WITH_SIZE_EXPR \
|| (SYM) == SSA_NAME \
|| (SYM) == VEC_COND_EXPR) ? GIMPLE_SINGLE_RHS \
|| (SYM) == SSA_NAME) ? GIMPLE_SINGLE_RHS \
: GIMPLE_INVALID_RHS),
#define END_OF_BASE_TREE_CODES (unsigned char) GIMPLE_INVALID_RHS,

View File

@ -3668,7 +3668,8 @@ verify_gimple_assign_ternary (gimple stmt)
return true;
}
if (!is_gimple_val (rhs1)
if (((rhs_code == VEC_COND_EXPR || rhs_code == COND_EXPR)
? !is_gimple_condexpr (rhs1) : !is_gimple_val (rhs1))
|| !is_gimple_val (rhs2)
|| !is_gimple_val (rhs3))
{
@ -3711,6 +3712,19 @@ verify_gimple_assign_ternary (gimple stmt)
}
break;
case COND_EXPR:
case VEC_COND_EXPR:
if (!useless_type_conversion_p (lhs_type, rhs2_type)
|| !useless_type_conversion_p (lhs_type, rhs3_type))
{
error ("type mismatch in conditional expression");
debug_generic_expr (lhs_type);
debug_generic_expr (rhs2_type);
debug_generic_expr (rhs3_type);
return true;
}
break;
case DOT_PROD_EXPR:
case REALIGN_LOAD_EXPR:
/* FIXME. */
@ -3827,26 +3841,10 @@ verify_gimple_assign_single (gimple stmt)
}
return res;
case COND_EXPR:
if (!is_gimple_reg (lhs)
|| (!is_gimple_reg (TREE_OPERAND (rhs1, 0))
&& !COMPARISON_CLASS_P (TREE_OPERAND (rhs1, 0)))
|| (!is_gimple_reg (TREE_OPERAND (rhs1, 1))
&& !is_gimple_min_invariant (TREE_OPERAND (rhs1, 1)))
|| (!is_gimple_reg (TREE_OPERAND (rhs1, 2))
&& !is_gimple_min_invariant (TREE_OPERAND (rhs1, 2))))
{
error ("invalid COND_EXPR in gimple assignment");
debug_generic_stmt (rhs1);
return true;
}
return res;
case CONSTRUCTOR:
case OBJ_TYPE_REF:
case ASSERT_EXPR:
case WITH_SIZE_EXPR:
case VEC_COND_EXPR:
/* FIXME. */
return res;

View File

@ -53,7 +53,7 @@ static void expr_object_size (struct object_size_info *, tree, tree);
static bool merge_object_sizes (struct object_size_info *, tree, tree,
unsigned HOST_WIDE_INT);
static bool plus_stmt_object_size (struct object_size_info *, tree, gimple);
static bool cond_expr_object_size (struct object_size_info *, tree, tree);
static bool cond_expr_object_size (struct object_size_info *, tree, gimple);
static unsigned int compute_object_sizes (void);
static void init_offset_limit (void);
static void check_for_plus_in_loops (struct object_size_info *, tree);
@ -827,25 +827,25 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple stmt)
}
/* Compute object_sizes for VAR, defined to VALUE, which is
/* Compute object_sizes for VAR, defined at STMT, which is
a COND_EXPR. Return true if the object size might need reexamination
later. */
static bool
cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
cond_expr_object_size (struct object_size_info *osi, tree var, gimple stmt)
{
tree then_, else_;
int object_size_type = osi->object_size_type;
unsigned int varno = SSA_NAME_VERSION (var);
bool reexamine = false;
gcc_assert (TREE_CODE (value) == COND_EXPR);
gcc_assert (gimple_assign_rhs_code (stmt) == COND_EXPR);
if (object_sizes[object_size_type][varno] == unknown[object_size_type])
return false;
then_ = COND_EXPR_THEN (value);
else_ = COND_EXPR_ELSE (value);
then_ = gimple_assign_rhs2 (stmt);
else_ = gimple_assign_rhs3 (stmt);
if (TREE_CODE (then_) == SSA_NAME)
reexamine |= merge_object_sizes (osi, var, then_, 0);
@ -932,14 +932,14 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
|| (gimple_assign_rhs_code (stmt) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF))
reexamine = plus_stmt_object_size (osi, var, stmt);
else if (gimple_assign_rhs_code (stmt) == COND_EXPR)
reexamine = cond_expr_object_size (osi, var, stmt);
else if (gimple_assign_single_p (stmt)
|| gimple_assign_unary_nop_p (stmt))
{
if (TREE_CODE (rhs) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (rhs)))
reexamine = merge_object_sizes (osi, var, rhs, 0);
else if (TREE_CODE (rhs) == COND_EXPR)
reexamine = cond_expr_object_size (osi, var, rhs);
else
expr_object_size (osi, var, rhs);
}
@ -956,8 +956,6 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
if (TREE_CODE (arg) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (arg)))
reexamine = merge_object_sizes (osi, var, arg, 0);
else if (TREE_CODE (arg) == COND_EXPR)
reexamine = cond_expr_object_size (osi, var, arg);
else
expr_object_size (osi, var, arg);
}

View File

@ -1796,7 +1796,8 @@ interpret_expr (struct loop *loop, gimple at_stmt, tree expr)
if (automatically_generated_chrec_p (expr))
return expr;
if (TREE_CODE (expr) == POLYNOMIAL_CHREC)
if (TREE_CODE (expr) == POLYNOMIAL_CHREC
|| get_gimple_rhs_class (TREE_CODE (expr)) == GIMPLE_TERNARY_RHS)
return chrec_dont_know;
extract_ops_from_tree (expr, &code, &op0, &op1);

View File

@ -540,12 +540,9 @@ forward_propagate_into_gimple_cond (gimple stmt)
/* Propagate from the ssa name definition statements of COND_EXPR
in the rhs of statement STMT into the conditional if that simplifies it.
Returns zero if no statement was changed, one if there were
changes and two if cfg_cleanup needs to run.
Returns true zero if the stmt was changed. */
This must be kept in sync with forward_propagate_into_gimple_cond. */
static int
static bool
forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
{
gimple stmt = gsi_stmt (*gsi_p);
@ -560,15 +557,17 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
TREE_OPERAND (cond, 1));
else if (TREE_CODE (cond) == SSA_NAME)
{
tree name = cond, rhs0;
tree name = cond;
gimple def_stmt = get_prop_source_stmt (name, true, NULL);
if (!def_stmt || !can_propagate_from (def_stmt))
return 0;
rhs0 = gimple_assign_rhs1 (def_stmt);
tmp = combine_cond_expr_cond (stmt, NE_EXPR, boolean_type_node, rhs0,
build_int_cst (TREE_TYPE (rhs0), 0),
false);
if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_comparison)
tmp = fold_build2_loc (gimple_location (def_stmt),
gimple_assign_rhs_code (def_stmt),
boolean_type_node,
gimple_assign_rhs1 (def_stmt),
gimple_assign_rhs2 (def_stmt));
}
if (tmp)
@ -582,11 +581,16 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
fprintf (dump_file, "'\n");
}
gimple_assign_set_rhs_from_tree (gsi_p, unshare_expr (tmp));
if (integer_onep (tmp))
gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs2 (stmt));
else if (integer_zerop (tmp))
gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
else
gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
stmt = gsi_stmt (*gsi_p);
update_stmt (stmt);
return is_gimple_min_invariant (tmp) ? 2 : 1;
return true;
}
return 0;
@ -2436,12 +2440,8 @@ ssa_forward_propagate_and_combine (void)
else if (code == COND_EXPR)
{
/* In this case the entire COND_EXPR is in rhs1. */
int did_something;
did_something = forward_propagate_into_cond (&gsi);
changed |= forward_propagate_into_cond (&gsi);
stmt = gsi_stmt (gsi);
if (did_something == 2)
cfg_changed = true;
changed = did_something != 0;
}
else if (TREE_CODE_CLASS (code) == tcc_comparison)
{

View File

@ -1251,11 +1251,9 @@ move_computations_stmt (struct dom_walk_data *dw_data,
gcc_assert (arg0 && arg1);
t = build2 (gimple_cond_code (cond), boolean_type_node,
gimple_cond_lhs (cond), gimple_cond_rhs (cond));
t = build3 (COND_EXPR, TREE_TYPE (gimple_phi_result (stmt)),
t, arg0, arg1);
new_stmt = gimple_build_assign_with_ops (COND_EXPR,
gimple_phi_result (stmt),
t, NULL_TREE);
new_stmt = gimple_build_assign_with_ops3 (COND_EXPR,
gimple_phi_result (stmt),
t, arg0, arg1);
SSA_NAME_DEF_STMT (gimple_phi_result (stmt)) = new_stmt;
*((unsigned int *)(dw_data->global_data)) |= TODO_cleanup_cfg;
}

View File

@ -225,24 +225,7 @@ fold_assignment_stmt (gimple stmt)
switch (get_gimple_rhs_class (subcode))
{
case GIMPLE_SINGLE_RHS:
{
tree rhs = gimple_assign_rhs1 (stmt);
if (TREE_CODE (rhs) == COND_EXPR)
{
/* Sadly, we have to handle conditional assignments specially
here, because fold expects all the operands of an expression
to be folded before the expression itself is folded, but we
can't just substitute the folded condition here. */
tree cond = fold (COND_EXPR_COND (rhs));
if (cond == boolean_true_node)
rhs = COND_EXPR_THEN (rhs);
else if (cond == boolean_false_node)
rhs = COND_EXPR_ELSE (rhs);
}
return fold (rhs);
}
return fold (gimple_assign_rhs1 (stmt));
case GIMPLE_UNARY_RHS:
{
@ -265,6 +248,14 @@ fold_assignment_stmt (gimple stmt)
tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt);
tree op2 = gimple_assign_rhs3 (stmt);
/* Sadly, we have to handle conditional assignments specially
here, because fold expects all the operands of an expression
to be folded before the expression itself is folded, but we
can't just substitute the folded condition here. */
if (gimple_assign_rhs_code (stmt) == COND_EXPR)
op0 = fold (op0);
return fold_ternary (subcode, TREE_TYPE (lhs), op0, op1, op2);
}

View File

@ -2126,15 +2126,15 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
return NULL;
}
op3 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
op3 = gimple_assign_rhs1 (def_stmt);
if (COMPARISON_CLASS_P (op3))
{
op4 = TREE_OPERAND (op3, 1);
op3 = TREE_OPERAND (op3, 0);
}
op1 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 1);
op2 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 2);
op1 = gimple_assign_rhs2 (def_stmt);
op2 = gimple_assign_rhs3 (def_stmt);
if (TREE_CODE (op1) != SSA_NAME && TREE_CODE (op2) != SSA_NAME)
{

View File

@ -4740,7 +4740,6 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
{
tree scalar_dest = NULL_TREE;
tree vec_dest = NULL_TREE;
tree op = NULL_TREE;
tree cond_expr, then_clause, else_clause;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
@ -4794,11 +4793,9 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
if (code != COND_EXPR)
return false;
gcc_assert (gimple_assign_single_p (stmt));
op = gimple_assign_rhs1 (stmt);
cond_expr = TREE_OPERAND (op, 0);
then_clause = TREE_OPERAND (op, 1);
else_clause = TREE_OPERAND (op, 2);
cond_expr = gimple_assign_rhs1 (stmt);
then_clause = gimple_assign_rhs2 (stmt);
else_clause = gimple_assign_rhs3 (stmt);
if (!vect_is_simple_cond (cond_expr, loop_vinfo))
return false;
@ -4839,7 +4836,8 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
if (!vec_stmt)
{
STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
return expand_vec_cond_expr_p (TREE_TYPE (op), vec_mode);
return expand_vec_cond_expr_p (TREE_TYPE (gimple_assign_lhs (stmt)),
vec_mode);
}
/* Transform */

View File

@ -3190,11 +3190,11 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
}
/* Extract range information from a conditional expression EXPR based on
/* Extract range information from a conditional expression STMT based on
the ranges of each of its operands and the expression code. */
static void
extract_range_from_cond_expr (value_range_t *vr, tree expr)
extract_range_from_cond_expr (value_range_t *vr, gimple stmt)
{
tree op0, op1;
value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
@ -3202,7 +3202,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr)
/* Get value ranges for each operand. For constant operands, create
a new value range with the operand to simplify processing. */
op0 = COND_EXPR_THEN (expr);
op0 = gimple_assign_rhs2 (stmt);
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0))
@ -3210,7 +3210,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr)
else
set_value_range_to_varying (&vr0);
op1 = COND_EXPR_ELSE (expr);
op1 = gimple_assign_rhs3 (stmt);
if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1));
else if (is_gimple_min_invariant (op1))
@ -3302,7 +3302,7 @@ extract_range_from_assignment (value_range_t *vr, gimple stmt)
gimple_expr_type (stmt),
gimple_assign_rhs1 (stmt));
else if (code == COND_EXPR)
extract_range_from_cond_expr (vr, gimple_assign_rhs1 (stmt));
extract_range_from_cond_expr (vr, stmt);
else if (TREE_CODE_CLASS (code) == tcc_comparison)
extract_range_from_comparison (vr, gimple_assign_rhs_code (stmt),
gimple_expr_type (stmt),