Richard Guenther wrote:

> In this testcase the alignment of arr[i] should be irrelevant - it is
> not part of
> the stmts that are going to be vectorized.  But of course this may be
> simply an odering issue in how we analyze data-references / statements
> in basic-block vectorization (thus we possibly did not yet declare the
> arr[i] = i statement as not taking part in the vectorization).

The following patch changes tree-vect-data-refs.c:vect_verify_datarefs_alignment
to only take into account statements marked as "relevant".

This should have no impact for loop-based vectorization, since the only caller
(vect_enhance_data_refs_alignment) already skips irrelevant statements.
[ As an aside, that routine should probably use STMT_VINFO_RELEVANT_P instead
of just checking STMT_VINFO_RELEVANT as a boolean. ]

However, for SLP this change in itself doesn't work, since vect_slp_analyze_bb_1
calls vect_verify_datarefs_alignment *before* statements have actually been
marked as relevant or irrelevant.  Therefore, the patch also rearranges the
sequence in vect_slp_analyze_bb_1.

This in turn caused ICEs in vect_get_store_cost/vect_get_load_cost, since those
now can get called with statements with unsupported alignment.  There is already
one caller (vect_get_data_access_cost) that checks for this case and simply
returns "infinite" cost instead of aborting.  The patch moves this behaviour
into vect_get_store_cost/vect_get_load_cost themselves.  (The particular cost
shouldn't matter since vectorization will still be rejected in the end, it's
just that the test now runs a bit later.)

Overall, I've tested the patch with no regresions on powerpc64-linux and
arm-linux-gnueabi.   On PowerPC, it fixed the gcc.dg/vect/bb-slp-16.c test.

Mikael, would you mind verifying that it fixes the problem on sparc64?

OK for mainline?

Bye,
Ulrich


ChangeLog:

        PR tree-optimization/53729
        PR tree-optimization/53636
        * tree-vect-slp.c (vect_slp_analyze_bb_1): Delay call to
        vect_verify_datarefs_alignment until after statements have
        been marked as relevant/irrelevant.
        * tree-vect-data-refs.c (vect_verify_datarefs_alignment):
        Skip irrelevant statements.
        (vect_enhance_data_refs_alignment): Use STMT_VINFO_RELEVANT_P
        instead of STMT_VINFO_RELEVANT.
        (vect_get_data_access_cost): Do not check for supportable
        alignment before calling vect_get_load_cost/vect_get_store_cost.
        * tree-vect-stmts.c (vect_get_store_cost): Do not abort when
        handling unsupported alignment.
        (vect_get_load_cost): Likewise.


Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c   (revision 188850)
--- gcc/tree-vect-data-refs.c   (working copy)
*************** vect_verify_datarefs_alignment (loop_vec
*** 1094,1099 ****
--- 1094,1102 ----
        gimple stmt = DR_STMT (dr);
        stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
  
+       if (!STMT_VINFO_RELEVANT_P (stmt_info))
+       continue;
+ 
        /* For interleaving, only the alignment of the first access matters. 
           Skip statements marked as not vectorizable.  */
        if ((STMT_VINFO_GROUPED_ACCESS (stmt_info)
*************** vect_get_data_access_cost (struct data_r
*** 1213,1229 ****
    loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
    int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
    int ncopies = vf / nunits;
-   bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
  
!   if (!supportable_dr_alignment)
!     *inside_cost = VECT_MAX_COST;
    else
!     {
!       if (DR_IS_READ (dr))
!         vect_get_load_cost (dr, ncopies, true, inside_cost, outside_cost);
!       else
!         vect_get_store_cost (dr, ncopies, inside_cost);
!     }
  
    if (vect_print_dump_info (REPORT_COST))
      fprintf (vect_dump, "vect_get_data_access_cost: inside_cost = %d, "
--- 1216,1226 ----
    loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
    int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
    int ncopies = vf / nunits;
  
!   if (DR_IS_READ (dr))
!     vect_get_load_cost (dr, ncopies, true, inside_cost, outside_cost);
    else
!     vect_get_store_cost (dr, ncopies, inside_cost);
  
    if (vect_print_dump_info (REPORT_COST))
      fprintf (vect_dump, "vect_get_data_access_cost: inside_cost = %d, "
*************** vect_enhance_data_refs_alignment (loop_v
*** 1537,1543 ****
        stmt = DR_STMT (dr);
        stmt_info = vinfo_for_stmt (stmt);
  
!       if (!STMT_VINFO_RELEVANT (stmt_info))
        continue;
  
        /* For interleaving, only the alignment of the first access
--- 1534,1540 ----
        stmt = DR_STMT (dr);
        stmt_info = vinfo_for_stmt (stmt);
  
!       if (!STMT_VINFO_RELEVANT_P (stmt_info))
        continue;
  
        /* For interleaving, only the alignment of the first access
Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c       (revision 188850)
--- gcc/tree-vect-stmts.c       (working copy)
*************** vect_get_store_cost (struct data_referen
*** 931,936 ****
--- 931,946 ----
          break;
        }
  
+     case dr_unaligned_unsupported:
+       {
+         *inside_cost = VECT_MAX_COST;
+ 
+         if (vect_print_dump_info (REPORT_COST))
+           fprintf (vect_dump, "vect_model_store_cost: unsupported access.");
+ 
+         break;
+       }
+ 
      default:
        gcc_unreachable ();
      }
*************** vect_get_load_cost (struct data_referenc
*** 1094,1099 ****
--- 1104,1119 ----
          break;
        }
  
+     case dr_unaligned_unsupported:
+       {
+         *inside_cost = VECT_MAX_COST;
+ 
+         if (vect_print_dump_info (REPORT_COST))
+           fprintf (vect_dump, "vect_model_load_cost: unsupported access.");
+ 
+         break;
+       }
+ 
      default:
        gcc_unreachable ();
      }
Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c (revision 188850)
--- gcc/tree-vect-slp.c (working copy)
*************** vect_slp_analyze_bb_1 (basic_block bb)
*** 2050,2065 ****
        return NULL;
      }
  
-    if (!vect_verify_datarefs_alignment (NULL, bb_vinfo))
-     {
-       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
-         fprintf (vect_dump, "not vectorized: unsupported alignment in basic "
-                             "block.\n");
- 
-       destroy_bb_vec_info (bb_vinfo);
-       return NULL;
-     }
- 
    /* Check the SLP opportunities in the basic block, analyze and build SLP
       trees.  */
    if (!vect_analyze_slp (NULL, bb_vinfo))
--- 2050,2055 ----
*************** vect_slp_analyze_bb_1 (basic_block bb)
*** 2082,2087 ****
--- 2072,2087 ----
        vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance));
      }
  
+    if (!vect_verify_datarefs_alignment (NULL, bb_vinfo))
+     {
+       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+         fprintf (vect_dump, "not vectorized: unsupported alignment in basic "
+                             "block.\n");
+ 
+       destroy_bb_vec_info (bb_vinfo);
+       return NULL;
+     }
+ 
    if (!vect_slp_analyze_operations (bb_vinfo))
      {
        if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  ulrich.weig...@de.ibm.com

Reply via email to