Call maybe_fold_or_comparisons to fold OR-ed predicates.
2010-07-08 Sebastian Pop <sebastian.pop@amd.com> PR tree-optimization/44710 * tree-if-conv.c (parse_predicate): New. (add_to_predicate_list): Call it, call maybe_fold_or_comparisons. Make sure that the predicates are either SSA_NAMEs or gimple_condexpr. * gcc.dg/tree-ssa/ifc-6.c: New. * gcc.dg/tree-ssa/ifc-pr44710.c: New. From-SVN: r161964
This commit is contained in:
parent
384a5197cb
commit
d89e5e20b6
5 changed files with 155 additions and 7 deletions
|
@ -1,3 +1,10 @@
|
|||
2010-07-08 Sebastian Pop <sebastian.pop@amd.com>
|
||||
|
||||
PR tree-optimization/44710
|
||||
* tree-if-conv.c (parse_predicate): New.
|
||||
(add_to_predicate_list): Call it, call maybe_fold_or_comparisons.
|
||||
Make sure that the predicates are either SSA_NAMEs or gimple_condexpr.
|
||||
|
||||
2010-07-08 Sebastian Pop <sebastian.pop@amd.com>
|
||||
|
||||
* common.opt (ftree-loop-if-convert): New flag.
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2010-07-08 Sebastian Pop <sebastian.pop@amd.com>
|
||||
|
||||
PR tree-optimization/44710
|
||||
* gcc.dg/tree-ssa/ifc-6.c: New.
|
||||
* gcc.dg/tree-ssa/ifc-pr44710.c: New.
|
||||
|
||||
2010-07-08 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
PR fortran/18918
|
||||
|
|
15
gcc/testsuite/gcc.dg/tree-ssa/ifc-6.c
Normal file
15
gcc/testsuite/gcc.dg/tree-ssa/ifc-6.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-c -O2 -ftree-vectorize" { target *-*-* } } */
|
||||
|
||||
static int x;
|
||||
foo (int n, int *A)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (A[i])
|
||||
x = 2;
|
||||
if (A[i + 1])
|
||||
x = 1;
|
||||
}
|
||||
}
|
44
gcc/testsuite/gcc.dg/tree-ssa/ifc-pr44710.c
Normal file
44
gcc/testsuite/gcc.dg/tree-ssa/ifc-pr44710.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-c -O2 -ftree-vectorize" { target *-*-* } } */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define N 64
|
||||
float arr[N];
|
||||
|
||||
__attribute__ ((noinline))
|
||||
int foo (unsigned int n, float *min)
|
||||
{
|
||||
unsigned int pos = 1;
|
||||
unsigned int i;
|
||||
float limit = N+N;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
if (arr[i] < limit)
|
||||
{
|
||||
pos = i + 1;
|
||||
limit = arr[i];
|
||||
}
|
||||
|
||||
*min = limit;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int i, pos;
|
||||
float min;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
arr[i] = (float)(i);
|
||||
|
||||
arr[2] = -5.8;
|
||||
|
||||
pos = foo (N, &min);
|
||||
if (pos != 3 || min != arr[2])
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -259,17 +259,93 @@ is_predicated (basic_block bb)
|
|||
return !is_true_predicate (bb_predicate (bb));
|
||||
}
|
||||
|
||||
/* Add condition NEW_COND to the predicate list of basic block BB. */
|
||||
/* Parses the predicate COND and returns its comparison code and
|
||||
operands OP0 and OP1. */
|
||||
|
||||
static enum tree_code
|
||||
parse_predicate (tree cond, tree *op0, tree *op1)
|
||||
{
|
||||
gimple s;
|
||||
|
||||
if (TREE_CODE (cond) == SSA_NAME
|
||||
&& is_gimple_assign (s = SSA_NAME_DEF_STMT (cond)))
|
||||
{
|
||||
if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
|
||||
{
|
||||
*op0 = gimple_assign_rhs1 (s);
|
||||
*op1 = gimple_assign_rhs2 (s);
|
||||
return gimple_assign_rhs_code (s);
|
||||
}
|
||||
|
||||
else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR)
|
||||
{
|
||||
tree op = gimple_assign_rhs1 (s);
|
||||
tree type = TREE_TYPE (op);
|
||||
enum tree_code code = parse_predicate (op, op0, op1);
|
||||
|
||||
return code == ERROR_MARK ? ERROR_MARK
|
||||
: invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (type)));
|
||||
}
|
||||
|
||||
return ERROR_MARK;
|
||||
}
|
||||
|
||||
if (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison)
|
||||
{
|
||||
*op0 = TREE_OPERAND (cond, 0);
|
||||
*op1 = TREE_OPERAND (cond, 1);
|
||||
return TREE_CODE (cond);
|
||||
}
|
||||
|
||||
return ERROR_MARK;
|
||||
}
|
||||
|
||||
/* Add condition NC to the predicate list of basic block BB. */
|
||||
|
||||
static inline void
|
||||
add_to_predicate_list (basic_block bb, tree new_cond)
|
||||
add_to_predicate_list (basic_block bb, tree nc)
|
||||
{
|
||||
tree cond = bb_predicate (bb);
|
||||
tree bc;
|
||||
|
||||
set_bb_predicate (bb, is_true_predicate (cond) ? new_cond :
|
||||
fold_build2_loc (EXPR_LOCATION (cond),
|
||||
TRUTH_OR_EXPR, boolean_type_node,
|
||||
cond, new_cond));
|
||||
if (is_true_predicate (nc))
|
||||
return;
|
||||
|
||||
if (!is_predicated (bb))
|
||||
bc = nc;
|
||||
else
|
||||
{
|
||||
enum tree_code code1, code2;
|
||||
tree op1a, op1b, op2a, op2b;
|
||||
|
||||
bc = bb_predicate (bb);
|
||||
code1 = parse_predicate (bc, &op1a, &op1b);
|
||||
code2 = parse_predicate (nc, &op2a, &op2b);
|
||||
|
||||
if (code1 != ERROR_MARK && code2 != ERROR_MARK)
|
||||
{
|
||||
tree t = maybe_fold_or_comparisons (code1, op1a, op1b,
|
||||
code2, op2a, op2b);
|
||||
if (!t)
|
||||
t = fold_build2_loc (EXPR_LOCATION (bc), TRUTH_OR_EXPR,
|
||||
boolean_type_node, bc, nc);
|
||||
bc = t;
|
||||
}
|
||||
else
|
||||
bc = fold_build2_loc (EXPR_LOCATION (bc), TRUTH_OR_EXPR,
|
||||
boolean_type_node, bc, nc);
|
||||
}
|
||||
|
||||
if (!is_gimple_condexpr (bc))
|
||||
{
|
||||
gimple_seq stmts;
|
||||
bc = force_gimple_operand (bc, &stmts, true, NULL_TREE);
|
||||
add_bb_predicate_gimplified_stmts (bb, stmts);
|
||||
}
|
||||
|
||||
if (is_true_predicate (bc))
|
||||
reset_bb_predicate (bb);
|
||||
else
|
||||
set_bb_predicate (bb, bc);
|
||||
}
|
||||
|
||||
/* Add the condition COND to the previous condition PREV_COND, and add
|
||||
|
|
Loading…
Add table
Reference in a new issue