aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-if-conv.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-if-conv.c')
-rw-r--r--gcc/tree-if-conv.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index fe446d9..e63dc66 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -117,7 +117,8 @@ static void add_to_predicate_list (basic_block, tree);
static tree add_to_dst_predicate_list (struct loop * loop, basic_block, tree, tree,
block_stmt_iterator *);
static void clean_predicate_lists (struct loop *loop);
-static basic_block find_phi_replacement_condition (basic_block, tree *,
+static basic_block find_phi_replacement_condition (struct loop *loop,
+ basic_block, tree *,
block_stmt_iterator *);
static void replace_phi_with_cond_modify_expr (tree, tree, basic_block,
block_stmt_iterator *);
@@ -677,7 +678,8 @@ clean_predicate_lists (struct loop *loop)
whose phi arguments are selected when cond is true. */
static basic_block
-find_phi_replacement_condition (basic_block bb, tree *cond,
+find_phi_replacement_condition (struct loop *loop,
+ basic_block bb, tree *cond,
block_stmt_iterator *bsi)
{
edge e;
@@ -702,12 +704,22 @@ find_phi_replacement_condition (basic_block bb, tree *cond,
tmp_cond = p1->aux;
if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
{
- *cond = p2->aux;
+ /* If p2 is loop->header than its aux field does not have useful
+ info. Instead use !(cond) where cond is p1's aux field. */
+ if (p2 == loop->header)
+ *cond = invert_truthvalue (unshare_expr (p1->aux));
+ else
+ *cond = p2->aux;
true_bb = p2;
}
else
{
- *cond = p1->aux;
+ /* If p1 is loop->header than its aux field does not have useful
+ info. Instead use !(cond) where cond is p2's aux field. */
+ if (p1 == loop->header)
+ *cond = invert_truthvalue (unshare_expr (p2->aux));
+ else
+ *cond = p1->aux;
true_bb = p1;
}
@@ -828,7 +840,7 @@ process_phi_nodes (struct loop *loop)
/* BB has two predecessors. Using predecessor's aux field, set
appropriate condition for the PHI node replacement. */
if (phi)
- true_bb = find_phi_replacement_condition (bb, &cond, &bsi);
+ true_bb = find_phi_replacement_condition (loop, bb, &cond, &bsi);
while (phi)
{
@@ -1113,20 +1125,17 @@ gate_tree_if_conversion (void)
struct tree_opt_pass pass_if_conversion =
{
- "ifcvt", /* name */
- gate_tree_if_conversion, /* gate */
- main_tree_if_conversion, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- 0, /* tv_id */
- PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- TODO_dump_func, /* todo_flags_start */
- TODO_dump_func
- | TODO_verify_ssa
- | TODO_verify_stmts
- | TODO_verify_flow, /* todo_flags_finish */
- 0 /* letter */
+ "ifcvt", /* name */
+ gate_tree_if_conversion, /* gate */
+ main_tree_if_conversion, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_loops, /* todo_flags_finish */
+ 0 /* letter */
};