This fixes PR52298, we need to use the proper DR step for outer
loop vectorization.

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

Richard.

2012-02-20  Richard Guenther  <rguent...@suse.de>

        PR tree-optimization/52298
        * tree-vect-stmts.c (vectorizable_store): Properly use
        STMT_VINFO_DR_STEP instead of DR_STEP when vectorizing
        outer loops.
        (vectorizable_load): Likewise.
        * tree-vect-data-refs.c (vect_analyze_data_ref_access):
        Access DR_STEP after ensuring it is not NULL.

        * gcc.dg/torture/pr52298.c: New testcase.
        * gcc.dg/vect/pr52298.c: Likewise.

Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c       (revision 184390)
--- gcc/tree-vect-stmts.c       (working copy)
*************** vectorizable_store (gimple stmt, gimple_
*** 3753,3759 ****
    if (!STMT_VINFO_DATA_REF (stmt_info))
      return false;
  
!   if (tree_int_cst_compare (DR_STEP (dr), size_zero_node) < 0)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
          fprintf (vect_dump, "negative step for store.");
--- 3753,3761 ----
    if (!STMT_VINFO_DATA_REF (stmt_info))
      return false;
  
!   if (tree_int_cst_compare (loop && nested_in_vect_loop_p (loop, stmt)
!                           ? STMT_VINFO_DR_STEP (stmt_info) : DR_STEP (dr),
!                           size_zero_node) < 0)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
          fprintf (vect_dump, "negative step for store.");
*************** vectorizable_load (gimple stmt, gimple_s
*** 4266,4272 ****
    if (!STMT_VINFO_DATA_REF (stmt_info))
      return false;
  
!   negative = tree_int_cst_compare (DR_STEP (dr), size_zero_node) < 0;
    if (negative && ncopies > 1)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
--- 4268,4277 ----
    if (!STMT_VINFO_DATA_REF (stmt_info))
      return false;
  
!   negative = tree_int_cst_compare (loop && nested_in_vect_loop_p (loop, stmt)
!                                  ? STMT_VINFO_DR_STEP (stmt_info)
!                                  : DR_STEP (dr),
!                                  size_zero_node) < 0;
    if (negative && ncopies > 1)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
*************** vectorizable_load (gimple stmt, gimple_s
*** 4654,4660 ****
       nested within an outer-loop that is being vectorized.  */
  
    if (loop && nested_in_vect_loop_p (loop, stmt)
!       && (TREE_INT_CST_LOW (DR_STEP (dr))
          % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0))
      {
        gcc_assert (alignment_support_scheme != dr_explicit_realign_optimized);
--- 4659,4665 ----
       nested within an outer-loop that is being vectorized.  */
  
    if (loop && nested_in_vect_loop_p (loop, stmt)
!       && (TREE_INT_CST_LOW (STMT_VINFO_DR_STEP (stmt_info))
          % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0))
      {
        gcc_assert (alignment_support_scheme != dr_explicit_realign_optimized);
Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c   (revision 184390)
--- gcc/tree-vect-data-refs.c   (working copy)
*************** vect_analyze_data_ref_access (struct dat
*** 2319,2325 ****
    stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
    loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
    struct loop *loop = NULL;
!   HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
  
    if (loop_vinfo)
      loop = LOOP_VINFO_LOOP (loop_vinfo);
--- 2319,2325 ----
    stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
    loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
    struct loop *loop = NULL;
!   HOST_WIDE_INT dr_step;
  
    if (loop_vinfo)
      loop = LOOP_VINFO_LOOP (loop_vinfo);
*************** vect_analyze_data_ref_access (struct dat
*** 2332,2337 ****
--- 2332,2338 ----
      }
  
    /* Allow invariant loads in loops.  */
+   dr_step = TREE_INT_CST_LOW (step);
    if (loop_vinfo && dr_step == 0)
      {
        GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) = NULL;
Index: gcc/testsuite/gcc.dg/torture/pr52298.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr52298.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr52298.c      (revision 0)
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do compile } */
+ 
+ int a, b, c, h;
+ 
+ int i[5][5];
+ 
+ void
+ fn1 ()
+ {
+   int l = 0;
+ 
+   for (a = 0; a <= 3; a++)
+     for (b = 1; b >= 0; b -= 1)
+       l |= i[0][b];
+   c = l;
+ }
Index: gcc/testsuite/gcc.dg/vect/pr52298.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/pr52298.c (revision 0)
--- gcc/testsuite/gcc.dg/vect/pr52298.c (revision 0)
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-do run } */
+ /* { dg-options "-O1 -ftree-vectorize -fno-tree-pre -fno-tree-loop-im" } */
+ 
+ extern void abort (void);
+ int c[80];
+ 
+ __attribute__((noinline)) int
+ foo (void)
+ {
+   int l = 0;
+   int a, b;
+ 
+   for (a = 3; a >= 0; a--)
+     for (b = 7; b >= 0; b--)
+       l |= c[a+60];
+   return l;
+ }
+ 
+ int
+ main ()
+ {
+   int i;
+   for (i = 0; i < 60; i++)
+     c[i] = 1;
+   for (; i < 64; i++)
+     c[i] = 1 << (i - 59);
+   if (foo () != 30)
+     abort ();
+   return 0;
+ }
+ 

Reply via email to