Commit 1c280337 by Devang Patel Committed by Devang Patel

tree-if-conv.c (find_phi_replacement_condition): Avoid generating x = !(a == b) : p : q;.

  * tree-if-conv.c (find_phi_replacement_condition): Avoid
  generating x = !(a == b) : p : q;.
  (pass_if_conversion): Verify stmts and flow.

  * gcc.dg/tree-ssa/ifc-3.c: New test.

From-SVN: r98514
parent de3eb46f
2005-04-21 Devang Patel <dpatel@apple.com>
PR optimization/20994
* tree-if-conv.c (find_phi_replacement_condition): Avoid generating
x = !(a == b) : p , q;.
(pass_if_conversion): Verify stmts and flow.
2005-04-21 Nathan Sidwell <nathan@codesourcery.com> 2005-04-21 Nathan Sidwell <nathan@codesourcery.com>
* optabs.c (gen_conditional_trap): Restore #define. * optabs.c (gen_conditional_trap): Restore #define.
......
2005-04-21 Devang Patel <dpatel@apple.com>
PR optimization/20994
* gcc.dg/tree-ssa/ifc-3.c: New test.
2005-04-20 Joseph S. Myers <joseph@codesourcery.com> 2005-04-20 Joseph S. Myers <joseph@codesourcery.com>
PR c/12913 PR c/12913
......
/* PR 20994 */
/* { dg-do compile } */
int foo(double* p, double* q)
{
int i=0;
for (; q!=p; ++q)
if (*q)
++i;
return i;
}
...@@ -665,46 +665,64 @@ find_phi_replacement_condition (struct loop *loop, ...@@ -665,46 +665,64 @@ find_phi_replacement_condition (struct loop *loop,
basic_block bb, tree *cond, basic_block bb, tree *cond,
block_stmt_iterator *bsi) block_stmt_iterator *bsi)
{ {
edge e; basic_block first_bb = NULL;
basic_block p1 = NULL; basic_block second_bb = NULL;
basic_block p2 = NULL;
basic_block true_bb = NULL;
tree tmp_cond; tree tmp_cond;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->preds) gcc_assert (EDGE_COUNT (bb->preds) == 2);
{ first_bb = (EDGE_PRED (bb, 0))->src;
if (p1 == NULL) second_bb = (EDGE_PRED (bb, 1))->src;
p1 = e->src;
else
{
gcc_assert (!p2);
p2 = e->src;
}
}
/* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */ /* Use condition based on following criteria:
tmp_cond = p1->aux; 1)
S1: x = !c ? a : b;
S2: x = c ? b : a;
S2 is preferred over S1. Make 'b' first_bb and use its condition.
2) Do not make loop header first_bb.
3)
S1: x = !(c == d)? a : b;
S21: t1 = c == d;
S22: x = t1 ? b : a;
S3: x = (c == d) ? b : a;
S3 is preferred over S1 and S2*, Make 'b' first_bb and use
its condition. */
/* Select condition that is not TRUTH_NOT_EXPR. */
tmp_cond = first_bb->aux;
if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR) if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
{ {
/* If p2 is loop->header than its aux field does not have useful basic_block tmp_bb;
info. Instead use !(cond) where cond is p1's aux field. */ tmp_bb = first_bb;
if (p2 == loop->header) first_bb = second_bb;
*cond = invert_truthvalue (unshare_expr (p1->aux)); second_bb = first_bb;
else
*cond = p2->aux;
true_bb = p2;
} }
else
/* Check if FIRST_BB is loop header or not. */
if (first_bb == loop->header)
{ {
/* If p1 is loop->header than its aux field does not have useful tmp_cond = second_bb->aux;
info. Instead use !(cond) where cond is p2's aux field. */ if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
if (p1 == loop->header) {
*cond = invert_truthvalue (unshare_expr (p2->aux)); /* Select non loop header condition but do not switch basic blocks. */
*cond = invert_truthvalue (unshare_expr (tmp_cond));
}
else else
*cond = p1->aux; {
true_bb = p1; /* Select non loop header condition. */
first_bb = second_bb;
*cond = first_bb->aux;
}
} }
else
/* FIRST_BB is not loop header */
*cond = first_bb->aux;
/* Create temp. for the condition. Vectorizer prefers to have gimple /* Create temp. for the condition. Vectorizer prefers to have gimple
value as condition. Various targets use different means to communicate value as condition. Various targets use different means to communicate
...@@ -722,7 +740,7 @@ find_phi_replacement_condition (struct loop *loop, ...@@ -722,7 +740,7 @@ find_phi_replacement_condition (struct loop *loop,
gcc_assert (*cond); gcc_assert (*cond);
return true_bb; return first_bb;
} }
...@@ -1119,6 +1137,7 @@ struct tree_opt_pass pass_if_conversion = ...@@ -1119,6 +1137,7 @@ struct tree_opt_pass pass_if_conversion =
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
TODO_dump_func | TODO_verify_loops, /* todo_flags_finish */ TODO_dump_func | TODO_verify_loops | TODO_verify_stmts | TODO_verify_flow,
/* todo_flags_finish */
0 /* letter */ 0 /* letter */
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment