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;
+ }

Reply via email to