This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR56933


This fixes the wrong-code caused by the use-before-compute
of GROUP_READ_WRITE_DEPENDENCE after I moved data dependence
checking after group analysis in the vectorizer.  The fix
is to move the dependence checking completely to the
dependence checking - now possible as we have computed groups
already.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2013-04-15  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/56933
	* tree-vectorizer.h (struct _stmt_vec_info): Remove read_write_dep
	member.
	(GROUP_READ_WRITE_DEPENDENCE): Remove.
	(STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE): Likewise.
	* tree-vect-data-refs.c (vect_analyze_group_access): Move
	dependence check ...
	vect_analyze_data_ref_dependence (vect_analyze_data_ref_dependence):
	... here.
	* tree-vect-stmts.c (new_stmt_vec_info): Do not initialize
	GROUP_READ_WRITE_DEPENDENCE.

	* gcc.dg/vect/pr56933.c: New testcase.

Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c	(revision 197957)
--- gcc/tree-vect-data-refs.c	(working copy)
*************** vect_analyze_data_ref_dependence (struct
*** 341,354 ****
  	      dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
  	    }
  
!           /* For interleaving, mark that there is a read-write dependency if
!              necessary.  We check before that one of the data-refs is store.  */
!           if (DR_IS_READ (dra))
!             GROUP_READ_WRITE_DEPENDENCE (stmtinfo_a) = true;
! 	  else
!             {
!               if (DR_IS_READ (drb))
!                 GROUP_READ_WRITE_DEPENDENCE (stmtinfo_b) = true;
  	    }
  
  	  continue;
--- 341,374 ----
  	      dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
  	    }
  
! 	  /* When we perform grouped accesses and perform implicit CSE
! 	     by detecting equal accesses and doing disambiguation with
! 	     runtime alias tests like for
! 	        .. = a[i];
! 		.. = a[i+1];
! 		a[i] = ..;
! 		a[i+1] = ..;
! 		*p = ..;
! 		.. = a[i];
! 		.. = a[i+1];
! 	     where we will end up loading { a[i], a[i+1] } once, make
! 	     sure that inserting group loads before the first load and
! 	     stores after the last store will do the right thing.  */
! 	  if ((STMT_VINFO_GROUPED_ACCESS (stmtinfo_a)
! 	       && GROUP_SAME_DR_STMT (stmtinfo_a))
! 	      || (STMT_VINFO_GROUPED_ACCESS (stmtinfo_b)
! 		  && GROUP_SAME_DR_STMT (stmtinfo_b)))
! 	    {
! 	      gimple earlier_stmt;
! 	      earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
! 	      if (DR_IS_WRITE
! 		    (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
! 		{
! 		  if (dump_enabled_p ())
! 		    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
! 				     "READ_WRITE dependence in interleaving.");
! 		  return true;
! 		}
  	    }
  
  	  continue;
*************** vect_analyze_group_access (struct data_r
*** 2097,2113 ****
                    return false;
                  }
  
-               /* Check that there is no load-store dependencies for this loads
-                  to prevent a case of load-store-load to the same location.  */
-               if (GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (next))
-                   || GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (prev)))
-                 {
-                   if (dump_enabled_p ())
-                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 
-                                      "READ_WRITE dependence in interleaving.");
-                   return false;
-                 }
- 
                /* For load use the same data-ref load.  */
                GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev;
  
--- 2117,2122 ----
Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c	(revision 197957)
--- gcc/tree-vect-stmts.c	(working copy)
*************** new_stmt_vec_info (gimple stmt, loop_vec
*** 5962,5968 ****
    GROUP_STORE_COUNT (res) = 0;
    GROUP_GAP (res) = 0;
    GROUP_SAME_DR_STMT (res) = NULL;
-   GROUP_READ_WRITE_DEPENDENCE (res) = false;
  
    return res;
  }
--- 5962,5967 ----
Index: gcc/tree-vectorizer.h
===================================================================
*** gcc/tree-vectorizer.h	(revision 197957)
--- gcc/tree-vectorizer.h	(working copy)
*************** typedef struct _stmt_vec_info {
*** 460,469 ****
    /* Stmt is part of some pattern (computation idiom)  */
    bool in_pattern_p;
  
-   /* For loads only, if there is a store with the same location, this field is
-      TRUE.  */
-   bool read_write_dep;
- 
    /* The stmt to which this info struct refers to.  */
    gimple stmt;
  
--- 460,465 ----
*************** typedef struct _stmt_vec_info {
*** 589,595 ****
  #define STMT_VINFO_GROUP_STORE_COUNT(S)    (S)->store_count
  #define STMT_VINFO_GROUP_GAP(S)            (S)->gap
  #define STMT_VINFO_GROUP_SAME_DR_STMT(S)   (S)->same_dr_stmt
- #define STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE(S)  (S)->read_write_dep
  #define STMT_VINFO_GROUPED_ACCESS(S)      ((S)->first_element != NULL && (S)->data_ref_info)
  #define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
  
--- 585,590 ----
*************** typedef struct _stmt_vec_info {
*** 599,605 ****
  #define GROUP_STORE_COUNT(S)            (S)->store_count
  #define GROUP_GAP(S)                    (S)->gap
  #define GROUP_SAME_DR_STMT(S)           (S)->same_dr_stmt
- #define GROUP_READ_WRITE_DEPENDENCE(S)  (S)->read_write_dep
  
  #define STMT_VINFO_RELEVANT_P(S)          ((S)->relevant != vect_unused_in_scope)
  
--- 594,599 ----
Index: gcc/testsuite/gcc.dg/vect/pr56933.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/pr56933.c	(revision 0)
--- gcc/testsuite/gcc.dg/vect/pr56933.c	(working copy)
***************
*** 0 ****
--- 1,40 ----
+ /* { dg-do run } */
+ 
+ extern void abort (void);
+ void __attribute__((noinline,noclone))
+ foo (double *b, double *d, double *f)
+ {
+   int i;
+   for (i = 0; i < 1024; i++)
+     {
+       d[2*i] = 2. * d[2*i];
+       d[2*i+1] = 4. * d[2*i+1];
+       b[i] = d[2*i] - 1.;
+       f[i] = d[2*i+1] + 2.;
+     }
+ }
+ int main()
+ {
+   double b[1024], d[2*1024], f[1024];
+   int i;
+   for (i = 0; i < 2*1024; i++)
+     d[i] = 1.;
+   foo (b, d, f);
+   for (i = 0; i < 1024; i+= 2)
+     {
+       if (d[2*i] != 2.)
+ 	abort ();
+       if (d[2*i+1] != 4.)
+ 	abort ();
+     }
+   for (i = 0; i < 1024; i++)
+     {
+       if (b[i] != 1.)
+ 	abort ();
+       if (f[i] != 6.)
+ 	abort ();
+     }
+   return 0;
+ }
+ 
+ /* { dg-final { cleanup-tree-dump "vect" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]