Hi, This patch fixes the vectorizer part of PR tree-optmization/48290 by checking that if we have a phi in outer loop in the basic block after the inner loop, then this phi is really inner loop's exit phi, i.e., its operand is defined in the inner loop.
Bootstrapped with vectorization enabled on powerpc64-suse-linux and tested on x86_64-suse-linux. Committed. Ira ChangeLog: PR tree-optimization/48290 * tree-vect-loop.c (vect_analyze_loop_operations): In outer loop vectorization, check that relevant phis in the basic block after the inner loop are really inner loop's exit phis. Index: tree-vect-loop.c =================================================================== --- tree-vect-loop.c (revision 171654) +++ tree-vect-loop.c (working copy) @@ -1184,11 +1184,11 @@ vect_analyze_loop_operations (loop_vec_info loop_v print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM); } + /* Inner-loop loop-closed exit phi in outer-loop vectorization + (i.e., a phi in the tail of the outer-loop). */ if (! is_loop_header_bb_p (bb)) { - /* inner-loop loop-closed exit phi in outer-loop vectorization - (i.e. a phi in the tail of the outer-loop). - FORNOW: we currently don't support the case that these phis + /* FORNOW: we currently don't support the case that these phis are not used in the outerloop (unless it is double reduction, i.e., this phi is vect_reduction_def), cause this case requires to actually do something here. */ @@ -1202,6 +1202,32 @@ vect_analyze_loop_operations (loop_vec_info loop_v "Unsupported loop-closed phi in outer-loop."); return false; } + + /* If PHI is used in the outer loop, we check that its operand + is defined in the inner loop. */ + if (STMT_VINFO_RELEVANT_P (stmt_info)) + { + tree phi_op; + gimple op_def_stmt; + + if (gimple_phi_num_args (phi) != 1) + return false; + + phi_op = PHI_ARG_DEF (phi, 0); + if (TREE_CODE (phi_op) != SSA_NAME) + return false; + + op_def_stmt = SSA_NAME_DEF_STMT (phi_op); + if (!op_def_stmt || !vinfo_for_stmt (op_def_stmt)) + return false; + + if (STMT_VINFO_RELEVANT (vinfo_for_stmt (op_def_stmt)) + != vect_used_in_outer + && STMT_VINFO_RELEVANT (vinfo_for_stmt (op_def_stmt)) + != vect_used_in_outer_by_reduction) + return false; + } + continue; }