Commit 29f85237 by Jakub Jelinek Committed by Ira Rosen

re PR tree-optimization/49352 (-fcompare-debug failure with -O2 -ftree-vectorize)


        PR tree-optimization/49352
        * tree-vect-loop.c (vect_is_slp_reduction): Don't count debug
        uses at all, make sure loop_use_stmt after the loop is a def
        stmt of a used SSA_NAME that is the only one defined inside
        of the loop.  Don't check for COND_EXPR and GIMPLE_BINARY_RHS.
        (vect_is_simple_reduction_1): Call vect_is_slp_reduction only
        if check_reduction is true.


Co-Authored-By: Ira Rosen <ira.rosen@linaro.org>

From-SVN: r174982
parent fd74d101
2011-06-13 Jakub Jelinek <jakub@redhat.com>
Ira Rosen <ira.rosen@linaro.org>
PR tree-optimization/49352
* tree-vect-loop.c (vect_is_slp_reduction): Don't count debug uses at
all, make sure loop_use_stmt after the loop is a def stmt of a used
SSA_NAME that is the only one defined inside of the loop. Don't
check for COND_EXPR and GIMPLE_BINARY_RHS.
(vect_is_simple_reduction_1): Call vect_is_slp_reduction only if
check_reduction is true.
2011-06-11 Jan Hubicka <jh@suse.cz> 2011-06-11 Jan Hubicka <jh@suse.cz>
PR middle-end/49373 PR middle-end/49373
......
2011-06-13 Jakub Jelinek <jakub@redhat.com>
Ira Rosen <ira.rosen@linaro.org>
PR tree-optimization/49352
* gcc.dg/vect/pr49352.c: New test.
2011-06-12 Tobias Burnus 2011-06-12 Tobias Burnus
PR fortran/49324 PR fortran/49324
......
/* PR tree-optimization/49352 */
/* { dg-do compile } */
/* { dg-options "-O2 -ftree-vectorize -fcompare-debug" } */
int
foo (int *x, int *y, int n)
{
int i, j;
int dot = 0;
for (i = 0; i < n; i++)
for (j = 0; j < 2; j++)
dot += *(x++) * *(y++);
return dot;
}
...@@ -1710,12 +1710,12 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) ...@@ -1710,12 +1710,12 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
struct loop *loop = (gimple_bb (phi))->loop_father; struct loop *loop = (gimple_bb (phi))->loop_father;
struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info); struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
enum tree_code code; enum tree_code code;
gimple current_stmt = NULL, use_stmt = NULL, first, next_stmt; gimple current_stmt = NULL, loop_use_stmt = NULL, first, next_stmt;
stmt_vec_info use_stmt_info, current_stmt_info; stmt_vec_info use_stmt_info, current_stmt_info;
tree lhs; tree lhs;
imm_use_iterator imm_iter; imm_use_iterator imm_iter;
use_operand_p use_p; use_operand_p use_p;
int nloop_uses, size = 0, nuses; int nloop_uses, size = 0;
bool found = false; bool found = false;
if (loop != vect_loop) if (loop != vect_loop)
...@@ -1726,66 +1726,68 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) ...@@ -1726,66 +1726,68 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
while (1) while (1)
{ {
nloop_uses = 0; nloop_uses = 0;
nuses = 0;
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
{ {
use_stmt = USE_STMT (use_p); gimple use_stmt = USE_STMT (use_p);
nuses++;
if (is_gimple_debug (use_stmt)) if (is_gimple_debug (use_stmt))
continue; continue;
use_stmt = USE_STMT (use_p);
/* Check if we got back to the reduction phi. */ /* Check if we got back to the reduction phi. */
if (gimple_code (use_stmt) == GIMPLE_PHI if (use_stmt == phi)
&& use_stmt == phi)
{ {
loop_use_stmt = use_stmt;
found = true; found = true;
break; break;
} }
if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)) if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
&& vinfo_for_stmt (use_stmt) && vinfo_for_stmt (use_stmt)
&& !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)) && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt)))
&& use_stmt != first_stmt) {
nloop_uses++; loop_use_stmt = use_stmt;
nloop_uses++;
}
if (nloop_uses > 1) if (nloop_uses > 1)
return false; return false;
} }
/* We reached a statement with no uses. */
if (nuses == 0)
return false;
if (found) if (found)
break; break;
/* We reached a statement with no loop uses. */
if (nloop_uses == 0)
return false;
/* This is a loop exit phi, and we haven't reached the reduction phi. */ /* This is a loop exit phi, and we haven't reached the reduction phi. */
if (gimple_code (use_stmt) == GIMPLE_PHI) if (gimple_code (loop_use_stmt) == GIMPLE_PHI)
return false; return false;
if (!is_gimple_assign (use_stmt) if (!is_gimple_assign (loop_use_stmt)
|| code != gimple_assign_rhs_code (use_stmt) || code != gimple_assign_rhs_code (loop_use_stmt)
|| !flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) || !flow_bb_inside_loop_p (loop, gimple_bb (loop_use_stmt)))
return false; return false;
/* Insert USE_STMT into reduction chain. */ /* Insert USE_STMT into reduction chain. */
use_stmt_info = vinfo_for_stmt (use_stmt); use_stmt_info = vinfo_for_stmt (loop_use_stmt);
if (current_stmt) if (current_stmt)
{ {
current_stmt_info = vinfo_for_stmt (current_stmt); current_stmt_info = vinfo_for_stmt (current_stmt);
GROUP_NEXT_ELEMENT (current_stmt_info) = use_stmt; GROUP_NEXT_ELEMENT (current_stmt_info) = loop_use_stmt;
GROUP_FIRST_ELEMENT (use_stmt_info) GROUP_FIRST_ELEMENT (use_stmt_info)
= GROUP_FIRST_ELEMENT (current_stmt_info); = GROUP_FIRST_ELEMENT (current_stmt_info);
} }
else else
GROUP_FIRST_ELEMENT (use_stmt_info) = use_stmt; GROUP_FIRST_ELEMENT (use_stmt_info) = loop_use_stmt;
lhs = gimple_assign_lhs (use_stmt); lhs = gimple_assign_lhs (loop_use_stmt);
current_stmt = use_stmt; current_stmt = loop_use_stmt;
size++; size++;
} }
if (!found || use_stmt != phi || size < 2) if (!found || loop_use_stmt != phi || size < 2)
return false; return false;
/* Swap the operands, if needed, to make the reduction operand be the second /* Swap the operands, if needed, to make the reduction operand be the second
...@@ -1794,75 +1796,70 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) ...@@ -1794,75 +1796,70 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
next_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt)); next_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt));
while (next_stmt) while (next_stmt)
{ {
if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS) if (gimple_assign_rhs2 (next_stmt) == lhs)
{ {
if (gimple_assign_rhs2 (next_stmt) == lhs) tree op = gimple_assign_rhs1 (next_stmt);
gimple def_stmt = NULL;
if (TREE_CODE (op) == SSA_NAME)
def_stmt = SSA_NAME_DEF_STMT (op);
/* Check that the other def is either defined in the loop
("vect_internal_def"), or it's an induction (defined by a
loop-header phi-node). */
if (def_stmt
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
&& (is_gimple_assign (def_stmt)
|| is_gimple_call (def_stmt)
|| STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
== vect_induction_def
|| (gimple_code (def_stmt) == GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
== vect_internal_def
&& !is_loop_header_bb_p (gimple_bb (def_stmt)))))
{ {
tree op = gimple_assign_rhs1 (next_stmt); lhs = gimple_assign_lhs (next_stmt);
gimple def_stmt = NULL; next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
continue;
if (TREE_CODE (op) == SSA_NAME) }
def_stmt = SSA_NAME_DEF_STMT (op);
return false;
/* Check that the other def is either defined in the loop }
("vect_internal_def"), or it's an induction (defined by a else
loop-header phi-node). */ {
if (code == COND_EXPR tree op = gimple_assign_rhs2 (next_stmt);
|| (def_stmt gimple def_stmt = NULL;
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
&& (is_gimple_assign (def_stmt) if (TREE_CODE (op) == SSA_NAME)
|| is_gimple_call (def_stmt) def_stmt = SSA_NAME_DEF_STMT (op);
|| STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
/* Check that the other def is either defined in the loop
("vect_internal_def"), or it's an induction (defined by a
loop-header phi-node). */
if (def_stmt
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
&& (is_gimple_assign (def_stmt)
|| is_gimple_call (def_stmt)
|| STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
== vect_induction_def == vect_induction_def
|| (gimple_code (def_stmt) == GIMPLE_PHI || (gimple_code (def_stmt) == GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
== vect_internal_def == vect_internal_def
&& !is_loop_header_bb_p (gimple_bb (def_stmt)))))) && !is_loop_header_bb_p (gimple_bb (def_stmt)))))
{
if (vect_print_dump_info (REPORT_DETAILS))
{ {
lhs = gimple_assign_lhs (next_stmt); fprintf (vect_dump, "swapping oprnds: ");
next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM);
continue;
} }
return false; swap_tree_operands (next_stmt,
gimple_assign_rhs1_ptr (next_stmt),
gimple_assign_rhs2_ptr (next_stmt));
mark_symbols_for_renaming (next_stmt);
} }
else else
{ return false;
tree op = gimple_assign_rhs2 (next_stmt);
gimple def_stmt = NULL;
if (TREE_CODE (op) == SSA_NAME)
def_stmt = SSA_NAME_DEF_STMT (op);
/* Check that the other def is either defined in the loop
("vect_internal_def"), or it's an induction (defined by a
loop-header phi-node). */
if (code == COND_EXPR
|| (def_stmt
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
&& (is_gimple_assign (def_stmt)
|| is_gimple_call (def_stmt)
|| STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
== vect_induction_def
|| (gimple_code (def_stmt) == GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
== vect_internal_def
&& !is_loop_header_bb_p (gimple_bb (def_stmt))))))
{
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "swapping oprnds: ");
print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM);
}
swap_tree_operands (next_stmt,
gimple_assign_rhs1_ptr (next_stmt),
gimple_assign_rhs2_ptr (next_stmt));
mark_symbols_for_renaming (next_stmt);
}
else
return false;
}
} }
lhs = gimple_assign_lhs (next_stmt); lhs = gimple_assign_lhs (next_stmt);
...@@ -2273,7 +2270,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, ...@@ -2273,7 +2270,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
} }
/* Try to find SLP reduction chain. */ /* Try to find SLP reduction chain. */
if (vect_is_slp_reduction (loop_info, phi, def_stmt)) if (check_reduction && vect_is_slp_reduction (loop_info, phi, def_stmt))
{ {
if (vect_print_dump_info (REPORT_DETAILS)) if (vect_print_dump_info (REPORT_DETAILS))
report_vect_op (def_stmt, "reduction: detected reduction chain: "); report_vect_op (def_stmt, "reduction: detected reduction chain: ");
......
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