Index: gcc/tree-data-ref.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.c,v
retrieving revision 2.7
diff -Idpatel.pbxuser -c -3 -p -r2.7 tree-data-ref.c
*** gcc/tree-data-ref.c	10 Sep 2004 15:09:38 -0000	2.7
--- gcc/tree-data-ref.c	15 Sep 2004 20:57:33 -0000
*************** init_data_ref (tree stmt, 
*** 598,604 ****
  /* When there exists a dependence relation, determine its distance
     vector.  */
  
! static void
  compute_distance_vector (struct data_dependence_relation *ddr)
  {
    if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
--- 598,604 ----
  /* When there exists a dependence relation, determine its distance
     vector.  */
  
! void
  compute_distance_vector (struct data_dependence_relation *ddr)
  {
    if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
Index: gcc/tree-data-ref.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.h,v
retrieving revision 2.4
diff -Idpatel.pbxuser -c -3 -p -r2.4 tree-data-ref.h
*** gcc/tree-data-ref.h	10 Sep 2004 15:09:38 -0000	2.4
--- gcc/tree-data-ref.h	15 Sep 2004 20:57:33 -0000
*************** struct data_dependence_relation
*** 147,152 ****
--- 147,153 ----
  struct data_dependence_relation *initialize_data_dependence_relation 
  (struct data_reference *, struct data_reference *);
  void compute_affine_dependence (struct data_dependence_relation *);
+ void compute_distance_vector (struct data_dependence_relation *ddr);
  extern void analyze_all_data_dependences (struct loops *);
  extern void compute_data_dependences_for_loop (unsigned, struct loop *, 
  					       varray_type *, varray_type *);
Index: gcc/tree-vectorizer.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.c,v
retrieving revision 2.8
diff -Idpatel.pbxuser -c -3 -p -r2.8 tree-vectorizer.c
*** gcc/tree-vectorizer.c	10 Sep 2004 10:44:47 -0000	2.8
--- gcc/tree-vectorizer.c	15 Sep 2004 20:57:34 -0000
*************** vect_analyze_scalar_cycles (loop_vec_inf
*** 1973,1982 ****
  static bool
  vect_analyze_data_ref_dependence (struct data_reference *dra,
  				  struct data_reference *drb, 
! 				  struct loop *loop)
  {
    bool differ_p;
    struct data_dependence_relation *ddr;
  
    if (!array_base_name_differ_p (dra, drb, &differ_p))
      {
--- 2116,2130 ----
  static bool
  vect_analyze_data_ref_dependence (struct data_reference *dra,
  				  struct data_reference *drb, 
! 				  struct loop *loop,
! 				  loop_vec_info loop_info)
  {
    bool differ_p;
    struct data_dependence_relation *ddr;
+   unsigned int i;
+   bool dep_exists = true;
+   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_info);
+   tree vf = NULL_TREE;
  
    if (!array_base_name_differ_p (dra, drb, &differ_p))
      {
*************** vect_analyze_data_ref_dependence (struct
*** 2000,2005 ****
--- 2148,2178 ----
    if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
      return false;
    
+   /* Check distance vector.  */
+   compute_distance_vector (ddr);
+   vf = build_int_cst (unsigned_type_node, vectorization_factor);
+ 
+   for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
+     {
+       struct subscript *subscript;
+  	  
+       subscript = DDR_SUBSCRIPT (ddr, i);
+ 
+       if (SUB_DISTANCE (subscript) == integer_zero_node)
+ 	dep_exists = false;
+       else if (INT_CST_LT (vf, SUB_DISTANCE (subscript)))
+ 	{
+ 	  dep_exists = false;
+ 
+ 	  if (TREE_INT_CST_LOW (vf) == TREE_INT_CST_LOW (SUB_DISTANCE (subscript))
+ 	      && TREE_INT_CST_HIGH (vf) == TREE_INT_CST_HIGH (SUB_DISTANCE (subscript)))
+ 	    dep_exists = true;
+ 	  }
+     }
+ 
+   if (!dep_exists)
+     return false;
+ 
    if (vect_debug_stats (loop) || vect_debug_details (loop))
      {
        fprintf (dump_file,
*************** vect_analyze_data_ref_dependences (loop_
*** 2045,2051 ****
  	    VARRAY_GENERIC_PTR (loop_write_refs, i);
  	  struct data_reference *drb =
  	    VARRAY_GENERIC_PTR (loop_write_refs, j);
! 	  if (vect_analyze_data_ref_dependence (dra, drb, loop))
  	    return false;
  	}
      }
--- 2218,2224 ----
  	    VARRAY_GENERIC_PTR (loop_write_refs, i);
  	  struct data_reference *drb =
  	    VARRAY_GENERIC_PTR (loop_write_refs, j);
! 	  if (vect_analyze_data_ref_dependence (dra, drb, loop, loop_vinfo))
  	    return false;
  	}
      }
*************** vect_analyze_data_ref_dependences (loop_
*** 2062,2068 ****
  	  struct data_reference *dra = VARRAY_GENERIC_PTR (loop_read_refs, i);
  	  struct data_reference *drb =
  	    VARRAY_GENERIC_PTR (loop_write_refs, j);
! 	  if (vect_analyze_data_ref_dependence (dra, drb, loop))
  	    return false;
  	}
      }
--- 2235,2241 ----
  	  struct data_reference *dra = VARRAY_GENERIC_PTR (loop_read_refs, i);
  	  struct data_reference *drb =
  	    VARRAY_GENERIC_PTR (loop_write_refs, j);
! 	  if (vect_analyze_data_ref_dependence (dra, drb, loop, loop_vinfo))
  	    return false;
  	}
      }
*************** vect_analyze_loop (struct loop *loop)
*** 3275,3327 ****
      }
  
  
!   /* Analyze data dependences between the data-refs in the loop. 
!      FORNOW: fail at the first data dependence that we encounter.  */
  
!   ok = vect_analyze_data_ref_dependences (loop_vinfo);
    if (!ok)
      {
        if (vect_debug_details (loop))
! 	fprintf (dump_file, "bad data dependence.");
        destroy_loop_vec_info (loop_vinfo);
        return NULL;
      }
  
  
!   /* Analyze the access patterns of the data-refs in the loop (consecutive,
!      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
  
!   ok = vect_analyze_data_ref_accesses (loop_vinfo);
    if (!ok)
      {
        if (vect_debug_details (loop))
! 	fprintf (dump_file, "bad data access.");
        destroy_loop_vec_info (loop_vinfo);
        return NULL;
      }
  
  
!   /* Analyze the alignment of the data-refs in the loop.
!      FORNOW: Only aligned accesses are handled.  */
! 
!   ok = vect_analyze_data_refs_alignment (loop_vinfo);
    if (!ok)
      {
        if (vect_debug_details (loop))
! 	fprintf (dump_file, "bad data alignment.");
        destroy_loop_vec_info (loop_vinfo);
        return NULL;
      }
  
  
!   /* Scan all the operations in the loop and make sure they are
!      vectorizable.  */
! 
!   ok = vect_analyze_operations (loop_vinfo);
    if (!ok)
      {
        if (vect_debug_details (loop))
! 	fprintf (dump_file, "bad operation or unsupported loop bound.");
        destroy_loop_vec_info (loop_vinfo);
        return NULL;
      }
--- 3450,3500 ----
      }
  
  
!   /* Analyze the alignment of the data-refs in the loop.
!      FORNOW: Only aligned accesses are handled.  */
  
!   ok = vect_analyze_data_refs_alignment (loop_vinfo);
    if (!ok)
      {
        if (vect_debug_details (loop))
! 	fprintf (dump_file, "bad data alignment.");
        destroy_loop_vec_info (loop_vinfo);
        return NULL;
      }
  
  
!   /* Scan all the operations in the loop and make sure they are
!      vectorizable.  */
  
!   ok = vect_analyze_operations (loop_vinfo);
    if (!ok)
      {
        if (vect_debug_details (loop))
! 	fprintf (dump_file, "bad operation or unsupported loop bound.");
        destroy_loop_vec_info (loop_vinfo);
        return NULL;
      }
  
+   /* Analyze data dependences between the data-refs in the loop. 
+      FORNOW: fail at the first data dependence that we encounter.  */
  
!   ok = vect_analyze_data_ref_dependences (loop_vinfo);
    if (!ok)
      {
        if (vect_debug_details (loop))
! 	fprintf (dump_file, "bad data dependence.");
        destroy_loop_vec_info (loop_vinfo);
        return NULL;
      }
  
+   /* Analyze the access patterns of the data-refs in the loop (consecutive,
+      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
  
!   ok = vect_analyze_data_ref_accesses (loop_vinfo);
    if (!ok)
      {
        if (vect_debug_details (loop))
! 	fprintf (dump_file, "bad data access.");
        destroy_loop_vec_info (loop_vinfo);
        return NULL;
      }
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */

#include <stdarg.h>
#include <signal.h>

#define N 64
#define MAX 42

extern void abort(void); 

int main ()
{  
  int A[N];
  int B[N];
  int C[N];

  int i, j;

  for (i = 0; i < N; i++)
    {
      A[i] = i;
      B[i] = i;
      C[i] = i;
    }
  /* Vectorizable */
  for (i = 0; i < 16; i++)
    {
      A[i] = A[i+20];
    }

  /* check results:  */
  for (i = 0; i < 16; i++)
    {
      if (A[i] != A[i+20])
	abort ();
    }

  /* Vectorizable */
  for (i = 0; i < 16; i++)
    {
      B[i] = B[i] + 5;
    }

  /* check results:  */
  for (i = 0; i < 16; i++)
    {
      if (B[i] != C[i] + 5)
	abort ();
    }

  /* Not vectorizable */
  for (i = 0; i < 4; i++)
    {
      C[i] = C[i+4];
    }

  /* check results:  */
  for (i = 0; i < 4; i++)
    {
      if (C[i] != C[i+4])
	abort ();
    }


  return 0;
}



/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
