Index: ChangeLog =================================================================== --- ChangeLog (revision 183901) +++ ChangeLog (working copy) @@ -1,3 +1,31 @@ +2012-02-05 Ira Rosen + + PR tree-optimization/52091 + * tree-vectorizer.h (vect_is_simple_use): Add an argument. + (vect_is_simple_use_1): Likewise. + * tree-vect-loop.c (vectorizable_reduction): Update calls + to vect_is_simple_use_1 and vect_is_simple_use. + (vectorizable_live_operation): Likewise. + * tree-vect-patterns.c (widened_name_p, + vect_recog_vector_vector_shift_pattern, check_bool_pattern): + Likewise. + * tree-vect-stmts.c (process_use, vect_get_vec_def_for_operand, + vectorizable_call, vectorizable_conversion, + vectorizable_assignment, vectorizable_shift, + vectorizable_operation, vectorizable_store, vectorizable_load): + Likewise. + (vect_is_simple_cond): Add an argument, pass it to + vect_is_simple_use_1. + (vectorizable_condition): Update calls to vect_is_simple_cond, + vect_is_simple_use. + (vect_is_simple_use): Add an argument, the statement in which + OPERAND is used. Check that if OPERAND's def stmt is a double + reduction phi node, the use is a phi node too. + (vect_is_simple_use_1): Add an argument, pass it to + vect_is_simple_use. + * tree-vect-slp.c (vect_get_and_check_slp_defs): Update a call + to vect_is_simple_use. + 2012-02-04 Jakub Jelinek PR rtl-optimization/52095 Index: testsuite/gcc.dg/vect/pr52091.c =================================================================== --- testsuite/gcc.dg/vect/pr52091.c (revision 0) +++ testsuite/gcc.dg/vect/pr52091.c (revision 0) @@ -0,0 +1,31 @@ +/* { dg-require-effective-target vect_int } */ + +/* PR tree-optimization/52091 */ + +int b, c, d, f; +unsigned h; +extern void abort (void); + +int +main () +{ + d = -1; + h = 65; + asm volatile ("" : : : "memory"); + for (f = 0; f < 4; f++) + { + h &= (unsigned short) d; + for (b = 0; b <= 1; b++) + { + c = 0; + d &= 1; + } + } + asm volatile ("" : : : "memory"); + if (b != 2 || c != 0 || d != 1 || f != 4 || h != 1) + abort (); + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 183901) +++ testsuite/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2012-02-05 Ira Rosen + + PR tree-optimization/52091 + * gcc.dg/vect/pr52091.c: New test. + 2012-02-04 Jakub Jelinek PR rtl-optimization/52113 Index: tree-vectorizer.h =================================================================== --- tree-vectorizer.h (revision 183901) +++ tree-vectorizer.h (working copy) @@ -1,5 +1,5 @@ /* Vectorizer - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Contributed by Dorit Naishlos @@ -808,9 +808,11 @@ extern bool vect_can_advance_ivs_p (loop_vec_info) extern unsigned int current_vector_size; extern tree get_vectype_for_scalar_type (tree); extern tree get_same_sized_vectype (tree, tree); -extern bool vect_is_simple_use (tree, loop_vec_info, bb_vec_info, gimple *, +extern bool vect_is_simple_use (tree, gimple, loop_vec_info, + bb_vec_info, gimple *, tree *, enum vect_def_type *); -extern bool vect_is_simple_use_1 (tree, loop_vec_info, bb_vec_info, gimple *, +extern bool vect_is_simple_use_1 (tree, gimple, loop_vec_info, + bb_vec_info, gimple *, tree *, enum vect_def_type *, tree *); extern bool supportable_widening_operation (enum tree_code, gimple, tree, tree, tree *, tree *, enum tree_code *, Index: tree-vect-loop.c =================================================================== --- tree-vect-loop.c (revision 183901) +++ tree-vect-loop.c (working copy) @@ -1,5 +1,5 @@ /* Loop Vectorization - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Contributed by Dorit Naishlos and Ira Rosen @@ -4486,7 +4486,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_i if (i == 0 && code == COND_EXPR) continue; - is_simple_use = vect_is_simple_use_1 (ops[i], loop_vinfo, NULL, + is_simple_use = vect_is_simple_use_1 (ops[i], stmt, loop_vinfo, NULL, &def_stmt, &def, &dt, &tem); if (!vectype_in) vectype_in = tem; @@ -4507,8 +4507,8 @@ vectorizable_reduction (gimple stmt, gimple_stmt_i } } - is_simple_use = vect_is_simple_use_1 (ops[i], loop_vinfo, NULL, &def_stmt, - &def, &dt, &tem); + is_simple_use = vect_is_simple_use_1 (ops[i], stmt, loop_vinfo, NULL, + &def_stmt, &def, &dt, &tem); if (!vectype_in) vectype_in = tem; gcc_assert (is_simple_use); @@ -4864,14 +4864,14 @@ vectorizable_reduction (gimple stmt, gimple_stmt_i gimple dummy_stmt; tree dummy; - vect_is_simple_use (ops[!reduc_index], loop_vinfo, NULL, + vect_is_simple_use (ops[!reduc_index], stmt, loop_vinfo, NULL, &dummy_stmt, &dummy, &dt); loop_vec_def0 = vect_get_vec_def_for_stmt_copy (dt, loop_vec_def0); VEC_replace (tree, vec_oprnds0, 0, loop_vec_def0); if (op_type == ternary_op) { - vect_is_simple_use (op1, loop_vinfo, NULL, &dummy_stmt, + vect_is_simple_use (op1, stmt, loop_vinfo, NULL, &dummy_stmt, &dummy, &dt); loop_vec_def1 = vect_get_vec_def_for_stmt_copy (dt, loop_vec_def1); @@ -5103,7 +5103,8 @@ vectorizable_live_operation (gimple stmt, else op = gimple_op (stmt, i + 1); if (op - && !vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def, &dt)) + && !vect_is_simple_use (op, stmt, loop_vinfo, NULL, &def_stmt, &def, + &dt)) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "use not simple."); Index: tree-vect-patterns.c =================================================================== --- tree-vect-patterns.c (revision 183901) +++ tree-vect-patterns.c (working copy) @@ -109,7 +109,8 @@ widened_name_p (tree name, gimple use_stmt, tree * stmt_vinfo = vinfo_for_stmt (use_stmt); loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); - if (!vect_is_simple_use (name, loop_vinfo, NULL, def_stmt, &def, &dt)) + if (!vect_is_simple_use (name, use_stmt, loop_vinfo, NULL, def_stmt, &def, + &dt)) return false; if (dt != vect_internal_def @@ -133,8 +134,8 @@ widened_name_p (tree name, gimple use_stmt, tree * || (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 2))) return false; - if (!vect_is_simple_use (oprnd0, loop_vinfo, NULL, &dummy_gimple, &dummy, - &dt)) + if (!vect_is_simple_use (oprnd0, *def_stmt, loop_vinfo, + NULL, &dummy_gimple, &dummy, &dt)) return false; return true; @@ -1550,7 +1551,8 @@ vect_recog_vector_vector_shift_pattern (VEC (gimpl != TYPE_PRECISION (TREE_TYPE (oprnd0))) return NULL; - if (!vect_is_simple_use (oprnd1, loop_vinfo, NULL, &def_stmt, &def, &dt)) + if (!vect_is_simple_use (oprnd1, last_stmt, loop_vinfo, NULL, &def_stmt, + &def, &dt)) return NULL; if (dt != vect_internal_def) @@ -1926,7 +1928,7 @@ check_bool_pattern (tree var, loop_vec_info loop_v tree def, rhs1; enum tree_code rhs_code; - if (!vect_is_simple_use (var, loop_vinfo, NULL, &def_stmt, &def, &dt)) + if (!vect_is_simple_use (var, NULL, loop_vinfo, NULL, &def_stmt, &def, &dt)) return false; if (dt != vect_internal_def) Index: tree-vect-stmts.c =================================================================== --- tree-vect-stmts.c (revision 183901) +++ tree-vect-stmts.c (working copy) @@ -374,7 +374,7 @@ process_use (gimple stmt, tree use, loop_vec_info if (!force && !exist_non_indexing_operands_for_use_p (use, stmt)) return true; - if (!vect_is_simple_use (use, loop_vinfo, NULL, &def_stmt, &def, &dt)) + if (!vect_is_simple_use (use, stmt, loop_vinfo, NULL, &def_stmt, &def, &dt)) { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) fprintf (vect_dump, "not vectorized: unsupported use in stmt."); @@ -1193,8 +1193,8 @@ vect_get_vec_def_for_operand (tree op, gimple stmt print_generic_expr (vect_dump, op, TDF_SLIM); } - is_simple_use = vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def, - &dt); + is_simple_use = vect_is_simple_use (op, stmt, loop_vinfo, NULL, + &def_stmt, &def, &dt); gcc_assert (is_simple_use); if (vect_print_dump_info (REPORT_DETAILS)) { @@ -1596,7 +1596,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterat if (!rhs_type) rhs_type = TREE_TYPE (op); - if (!vect_is_simple_use_1 (op, loop_vinfo, bb_vinfo, + if (!vect_is_simple_use_1 (op, stmt, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt[i], &opvectype)) { if (vect_print_dump_info (REPORT_DETAILS)) @@ -2208,7 +2208,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_ } /* Check the operands of the operation. */ - if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo, + if (!vect_is_simple_use_1 (op0, stmt, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt[0], &vectype_in)) { if (vect_print_dump_info (REPORT_DETAILS)) @@ -2224,11 +2224,11 @@ vectorizable_conversion (gimple stmt, gimple_stmt_ /* For WIDEN_MULT_EXPR, if OP0 is a constant, use the type of OP1. */ if (CONSTANT_CLASS_P (op0)) - ok = vect_is_simple_use_1 (op1, loop_vinfo, NULL, + ok = vect_is_simple_use_1 (op1, stmt, loop_vinfo, NULL, &def_stmt, &def, &dt[1], &vectype_in); else - ok = vect_is_simple_use (op1, loop_vinfo, NULL, &def_stmt, &def, - &dt[1]); + ok = vect_is_simple_use (op1, stmt, loop_vinfo, NULL, &def_stmt, + &def, &dt[1]); if (!ok) { @@ -2757,7 +2757,7 @@ vectorizable_assignment (gimple stmt, gimple_stmt_ if (code == VIEW_CONVERT_EXPR) op = TREE_OPERAND (op, 0); - if (!vect_is_simple_use_1 (op, loop_vinfo, bb_vinfo, + if (!vect_is_simple_use_1 (op, stmt, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt[0], &vectype_in)) { if (vect_print_dump_info (REPORT_DETAILS)) @@ -2957,7 +2957,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_itera } op0 = gimple_assign_rhs1 (stmt); - if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo, + if (!vect_is_simple_use_1 (op0, stmt, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt[0], &vectype)) { if (vect_print_dump_info (REPORT_DETAILS)) @@ -2987,8 +2987,8 @@ vectorizable_shift (gimple stmt, gimple_stmt_itera return false; op1 = gimple_assign_rhs2 (stmt); - if (!vect_is_simple_use_1 (op1, loop_vinfo, bb_vinfo, &def_stmt, &def, - &dt[1], &op1_vectype)) + if (!vect_is_simple_use_1 (op1, stmt, loop_vinfo, bb_vinfo, &def_stmt, + &def, &dt[1], &op1_vectype)) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "use not simple."); @@ -3334,7 +3334,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_i } op0 = gimple_assign_rhs1 (stmt); - if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo, + if (!vect_is_simple_use_1 (op0, stmt, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt[0], &vectype)) { if (vect_print_dump_info (REPORT_DETAILS)) @@ -3366,8 +3366,8 @@ vectorizable_operation (gimple stmt, gimple_stmt_i if (op_type == binary_op || op_type == ternary_op) { op1 = gimple_assign_rhs2 (stmt); - if (!vect_is_simple_use (op1, loop_vinfo, bb_vinfo, &def_stmt, &def, - &dt[1])) + if (!vect_is_simple_use (op1, stmt, loop_vinfo, bb_vinfo, &def_stmt, + &def, &dt[1])) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "use not simple."); @@ -3377,8 +3377,8 @@ vectorizable_operation (gimple stmt, gimple_stmt_i if (op_type == ternary_op) { op2 = gimple_assign_rhs3 (stmt); - if (!vect_is_simple_use (op2, loop_vinfo, bb_vinfo, &def_stmt, &def, - &dt[2])) + if (!vect_is_simple_use (op2, stmt, loop_vinfo, bb_vinfo, &def_stmt, + &def, &dt[2])) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "use not simple."); @@ -3684,7 +3684,8 @@ vectorizable_store (gimple stmt, gimple_stmt_itera gcc_assert (gimple_assign_single_p (stmt)); op = gimple_assign_rhs1 (stmt); - if (!vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt)) + if (!vect_is_simple_use (op, stmt, loop_vinfo, bb_vinfo, &def_stmt, + &def, &dt)) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "use not simple."); @@ -3731,8 +3732,8 @@ vectorizable_store (gimple stmt, gimple_stmt_itera { gcc_assert (gimple_assign_single_p (next_stmt)); op = gimple_assign_rhs1 (next_stmt); - if (!vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, - &def, &dt)) + if (!vect_is_simple_use (op, next_stmt, loop_vinfo, bb_vinfo, + &def_stmt, &def, &dt)) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "use not simple."); @@ -3917,8 +3918,8 @@ vectorizable_store (gimple stmt, gimple_stmt_itera for (i = 0; i < group_size; i++) { op = VEC_index (tree, oprnds, i); - vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, &def, - &dt); + vect_is_simple_use (op, NULL, loop_vinfo, bb_vinfo, &def_stmt, + &def, &dt); vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, op); VEC_replace(tree, dr_chain, i, vec_oprnd); VEC_replace(tree, oprnds, i, vec_oprnd); @@ -4279,7 +4280,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterat gather_decl = vect_check_gather (stmt, loop_vinfo, &gather_base, &gather_off, &gather_scale); gcc_assert (gather_decl); - if (!vect_is_simple_use_1 (gather_off, loop_vinfo, bb_vinfo, + if (!vect_is_simple_use_1 (gather_off, NULL, loop_vinfo, bb_vinfo, &def_stmt, &def, &gather_dt, &gather_off_vectype)) { @@ -4914,8 +4915,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterat condition operands are supportable using vec_is_simple_use. */ static bool -vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, - tree *comp_vectype) +vect_is_simple_cond (tree cond, gimple stmt, loop_vec_info loop_vinfo, + bb_vec_info bb_vinfo, tree *comp_vectype) { tree lhs, rhs; tree def; @@ -4931,8 +4932,8 @@ static bool if (TREE_CODE (lhs) == SSA_NAME) { gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs); - if (!vect_is_simple_use_1 (lhs, loop_vinfo, bb_vinfo, &lhs_def_stmt, &def, - &dt, &vectype1)) + if (!vect_is_simple_use_1 (lhs, stmt, loop_vinfo, bb_vinfo, + &lhs_def_stmt, &def, &dt, &vectype1)) return false; } else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST @@ -4942,8 +4943,8 @@ static bool if (TREE_CODE (rhs) == SSA_NAME) { gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs); - if (!vect_is_simple_use_1 (rhs, loop_vinfo, bb_vinfo, &rhs_def_stmt, &def, - &dt, &vectype2)) + if (!vect_is_simple_use_1 (rhs, stmt, loop_vinfo, bb_vinfo, + &rhs_def_stmt, &def, &dt, &vectype2)) return false; } else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST @@ -5035,14 +5036,15 @@ vectorizable_condition (gimple stmt, gimple_stmt_i then_clause = gimple_assign_rhs2 (stmt); else_clause = gimple_assign_rhs3 (stmt); - if (!vect_is_simple_cond (cond_expr, loop_vinfo, bb_vinfo, &comp_vectype) + if (!vect_is_simple_cond (cond_expr, stmt, loop_vinfo, bb_vinfo, + &comp_vectype) || !comp_vectype) return false; if (TREE_CODE (then_clause) == SSA_NAME) { gimple then_def_stmt = SSA_NAME_DEF_STMT (then_clause); - if (!vect_is_simple_use (then_clause, loop_vinfo, bb_vinfo, + if (!vect_is_simple_use (then_clause, stmt, loop_vinfo, bb_vinfo, &then_def_stmt, &def, &dt)) return false; } @@ -5054,7 +5056,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_i if (TREE_CODE (else_clause) == SSA_NAME) { gimple else_def_stmt = SSA_NAME_DEF_STMT (else_clause); - if (!vect_is_simple_use (else_clause, loop_vinfo, bb_vinfo, + if (!vect_is_simple_use (else_clause, stmt, loop_vinfo, bb_vinfo, &else_def_stmt, &def, &dt)) return false; } @@ -5114,21 +5116,21 @@ vectorizable_condition (gimple stmt, gimple_stmt_i vec_cond_lhs = vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt, NULL); - vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo, - NULL, >emp, &def, &dts[0]); + vect_is_simple_use (TREE_OPERAND (cond_expr, 0), stmt, + loop_vinfo, NULL, >emp, &def, &dts[0]); vec_cond_rhs = vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt, NULL); - vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo, - NULL, >emp, &def, &dts[1]); + vect_is_simple_use (TREE_OPERAND (cond_expr, 1), stmt, + loop_vinfo, NULL, >emp, &def, &dts[1]); if (reduc_index == 1) vec_then_clause = reduc_def; else { vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt, NULL); - vect_is_simple_use (then_clause, loop_vinfo, + vect_is_simple_use (then_clause, stmt, loop_vinfo, NULL, >emp, &def, &dts[2]); } if (reduc_index == 2) @@ -5137,7 +5139,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_i { vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL); - vect_is_simple_use (else_clause, loop_vinfo, + vect_is_simple_use (else_clause, stmt, loop_vinfo, NULL, >emp, &def, &dts[3]); } } @@ -5831,7 +5833,7 @@ get_same_sized_vectype (tree scalar_type, tree vec Input: LOOP_VINFO - the vect info of the loop that is being vectorized. BB_VINFO - the vect info of the basic block that is being vectorized. - OPERAND - operand of a stmt in the loop or bb. + OPERAND - operand of STMT in the loop or bb. DEF - the defining stmt in case OPERAND is an SSA_NAME. Returns whether a stmt with OPERAND can be vectorized. @@ -5843,7 +5845,7 @@ get_same_sized_vectype (tree scalar_type, tree vec For now, operands defined outside the basic block are not supported. */ bool -vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, +vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, gimple *def_stmt, tree *def, enum vect_def_type *dt) { @@ -5925,7 +5927,10 @@ bool *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo); } - if (*dt == vect_unknown_def_type) + if (*dt == vect_unknown_def_type + || (stmt + && *dt == vect_double_reduction_def + && gimple_code (stmt) != GIMPLE_PHI)) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "Unsupported pattern."); @@ -5969,11 +5974,12 @@ bool scalar operand. */ bool -vect_is_simple_use_1 (tree operand, loop_vec_info loop_vinfo, +vect_is_simple_use_1 (tree operand, gimple stmt, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, gimple *def_stmt, tree *def, enum vect_def_type *dt, tree *vectype) { - if (!vect_is_simple_use (operand, loop_vinfo, bb_vinfo, def_stmt, def, dt)) + if (!vect_is_simple_use (operand, stmt, loop_vinfo, bb_vinfo, def_stmt, + def, dt)) return false; /* Now get a vector type if the def is internal, otherwise supply Index: tree-vect-slp.c =================================================================== --- tree-vect-slp.c (revision 183901) +++ tree-vect-slp.c (working copy) @@ -233,8 +233,8 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vi oprnd = TREE_OPERAND (oprnd, 0); } - if (!vect_is_simple_use (oprnd, loop_vinfo, bb_vinfo, &def_stmt, &def, - &dt) + if (!vect_is_simple_use (oprnd, NULL, loop_vinfo, bb_vinfo, &def_stmt, + &def, &dt) || (!def_stmt && dt != vect_constant_def)) { if (vect_print_dump_info (REPORT_SLP))