Dependence analysis in the vectorizer assumes that all references take part in vectorization - which is of course the case for loop-based vectorization. For BB vectorization unrelated DRs can be inbetween vectorized stmts though. The original fix properly verified that when accounting DDRs that involve such stmts we don't make decisions based on the assumption the references would take part in vectorization. Now the issue is that after dependence analysis we may end up deciding that some more stmts do not take part in vectorization ...
The following patch fixes that by moving dependence analysis even later for BB vectorization. Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. This doesn't make the fixes easier backportable though :/ Richard. 2014-01-10 Richard Biener <rguent...@suse.de> PR tree-optimization/59374 * tree-vect-slp.c (vect_slp_analyze_bb_1): Move dependence checking after SLP discovery. Mark stmts not participating in any SLP instance properly. * gcc.dg/torture/pr59374-3.c: New testcase. Index: gcc/tree-vect-slp.c =================================================================== *** gcc/tree-vect-slp.c (revision 206460) --- gcc/tree-vect-slp.c (working copy) *************** vect_slp_analyze_bb_1 (basic_block bb) *** 2110,2126 **** vect_pattern_recog (NULL, bb_vinfo); - if (!vect_slp_analyze_data_ref_dependences (bb_vinfo)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: unhandled data dependence " - "in basic block.\n"); - - destroy_bb_vec_info (bb_vinfo); - return NULL; - } - if (!vect_analyze_data_refs_alignment (NULL, bb_vinfo)) { if (dump_enabled_p ()) --- 2110,2115 ---- *************** vect_slp_analyze_bb_1 (basic_block bb) *** 2155,2160 **** --- 2144,2172 ---- vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance)); } + /* Mark all the statements that we do not want to vectorize. */ + for (gimple_stmt_iterator gsi = gsi_start_bb (BB_VINFO_BB (bb_vinfo)); + !gsi_end_p (gsi); gsi_next (&gsi)) + { + stmt_vec_info vinfo = vinfo_for_stmt (gsi_stmt (gsi)); + if (STMT_SLP_TYPE (vinfo) != pure_slp) + STMT_VINFO_VECTORIZABLE (vinfo) = false; + } + + /* Analyze dependences. At this point all stmts not participating in + vectorization have to be marked. Dependence analysis assumes + that we either vectorize all SLP instances or none at all. */ + if (!vect_slp_analyze_data_ref_dependences (bb_vinfo)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: unhandled data dependence " + "in basic block.\n"); + + destroy_bb_vec_info (bb_vinfo); + return NULL; + } + if (!vect_verify_datarefs_alignment (NULL, bb_vinfo)) { if (dump_enabled_p ()) Index: gcc/testsuite/gcc.dg/torture/pr59374-3.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr59374-3.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr59374-3.c (working copy) *************** *** 0 **** --- 1,21 ---- + extern void abort (void); + + static struct X { void *a; void *b; } a, b; + + void __attribute__((noinline)) foo (void) + { + void *tem = a.b; + a.b = (void *)0; + b.b = tem; + b.a = a.a; + a.a = tem; + } + + int main() + { + a.b = &a; + foo (); + if (b.b != &a) + abort (); + return 0; + }