From 69940d4d9e914bfda0650a0771e916754dceb573 Mon Sep 17 00:00:00 2001 From: Ira Rosen Date: Mon, 30 May 2011 07:15:31 +0000 Subject: [PATCH] re PR tree-optimization/49199 (ICE: in vect_create_epilog_for_reduction at tree-vect-loop.c:3445 with -O -fno-tree-scev-cprop -ftree-vectorize -funswitch-loops) PR tree-optimization/49199 * tree-vect-loop.c (vect_is_slp_reduction): Check that the non-reduction operands are either defined in the loop or by induction. From-SVN: r174425 --- gcc/ChangeLog | 7 ++ gcc/testsuite/ChangeLog | 7 ++ .../gcc.dg/vect/no-scevccp-pr49199.c | 18 ++++ gcc/testsuite/gcc.dg/vect/vect.exp | 6 ++ gcc/tree-vect-loop.c | 100 ++++++++++++++---- 5 files changed, 116 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/no-scevccp-pr49199.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad6be6da202..c771214e672 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-05-30 Ira Rosen + + PR tree-optimization/49199 + * tree-vect-loop.c (vect_is_slp_reduction): Check that the + non-reduction operands are either defined in the loop or + by induction. + 2011-05-29 Xinliang David Li * opts-global.c (handle_common_deferred_options): Handle new options. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c9b6fb470e..60230d8623b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-05-30 Ira Rosen + + PR tree-optimization/49199 + * gcc.dg/vect/no-scevccp-pr49199.c: New test. + * gcc.dg/vect/vect.exp: Run no-scevccp-pr* tests with + -fno-tree-scev-cprop. + 2011-05-29 Janus Weil PR fortran/47601 diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-pr49199.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-pr49199.c new file mode 100644 index 00000000000..0f11142eb75 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-pr49199.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +int const_bar (void) __attribute__ ((__const__)); +int pure_bar (void) __attribute__ ((__pure__)); + +int foo (void) +{ + int i = 0, x = 0; + for (; i < 100; i++) + { + x += const_bar (); + x += pure_bar (); + } + return x; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp index b783ec39ba8..e0821d0f514 100644 --- a/gcc/testsuite/gcc.dg/vect/vect.exp +++ b/gcc/testsuite/gcc.dg/vect/vect.exp @@ -173,6 +173,12 @@ lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-scevccp-vect-*.\[cS\]]] \ "" $DEFAULT_VECTCFLAGS +# -fno-tree-scev-cprop +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-scevccp-pr*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + # -fno-tree-scev-cprop set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 666bd9b0fa7..c9d0c460b62 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -1700,7 +1700,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) struct loop *loop = (gimple_bb (phi))->loop_father; struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info); enum tree_code code; - gimple current_stmt = NULL, use_stmt = NULL, first; + gimple current_stmt = NULL, use_stmt = NULL, first, next_stmt; stmt_vec_info use_stmt_info, current_stmt_info; tree lhs; imm_use_iterator imm_iter; @@ -1778,36 +1778,92 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) if (!found || use_stmt != phi || size < 2) return false; - /* Save the chain for further analysis in SLP detection. */ - first = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt)); - VEC_safe_push (gimple, heap, LOOP_VINFO_REDUCTION_CHAINS (loop_info), first); - GROUP_SIZE (vinfo_for_stmt (first)) = size; - /* Swap the operands, if needed, to make the reduction operand be the second operand. */ lhs = PHI_RESULT (phi); - current_stmt = first; - while (current_stmt) + next_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt)); + while (next_stmt) { - if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS - && gimple_assign_rhs2 (current_stmt) != lhs) - { - if (vect_print_dump_info (REPORT_DETAILS)) - { - fprintf (vect_dump, "swapping oprnds: "); - print_gimple_stmt (vect_dump, current_stmt, 0, TDF_SLIM); - } + if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS) + { + 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 (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)))))) + { + lhs = gimple_assign_lhs (next_stmt); + next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); + continue; + } + + return false; + } + else + { + 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 (current_stmt, - gimple_assign_rhs1_ptr (current_stmt), - gimple_assign_rhs2_ptr (current_stmt)); - mark_symbols_for_renaming (current_stmt); + 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 (current_stmt); - current_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (current_stmt)); + lhs = gimple_assign_lhs (next_stmt); + next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); } + /* Save the chain for further analysis in SLP detection. */ + first = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt)); + VEC_safe_push (gimple, heap, LOOP_VINFO_REDUCTION_CHAINS (loop_info), first); + GROUP_SIZE (vinfo_for_stmt (first)) = size; + return true; } -- 2.30.2