Hi, This patch STMT_VINFO_FIRST_COPY_P field to statement vec info. This is used to find the first vector store generated for a scalar one. For other statements I use original scalar statement to find the first and following vector statement. For stores original scalar statement is removed and this new fiels is used to mark a chain start. Also original data reference and vector type are preserved in the first vector statement for masking purposes.
Thanks, Ilya -- gcc/ 2016-05-19 Ilya Enkovich <ilya.enkov...@intel.com> * tree-vect-stmts.c (vectorizable_mask_load_store): Mark the first copy of generated vector stores. (vectorizable_store): Mark the first copy of generated vector stores and provide it with vectype and the original data reference. * tree-vectorizer.h (struct _stmt_vec_info): Add first_copy_p field. (STMT_VINFO_FIRST_COPY_P): New. diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 91ebe5a..84f4dc81 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -2131,7 +2131,10 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, ptr, vec_mask, vec_rhs); vect_finish_stmt_generation (stmt, new_stmt, gsi); if (i == 0) - STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; + { + STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; + STMT_VINFO_FIRST_COPY_P (vinfo_for_stmt (new_stmt)) = true; + } else STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt; prev_stmt_info = vinfo_for_stmt (new_stmt); @@ -6203,7 +6206,16 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, if (!slp) { if (j == 0) - STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; + { + STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; + STMT_VINFO_FIRST_COPY_P (vinfo_for_stmt (new_stmt)) = true; + /* Original statement is replaced with the first vector one. + Keep data reference and original vectype in the first + vector copy for masking purposes. */ + STMT_VINFO_DATA_REF (vinfo_for_stmt (new_stmt)) + = STMT_VINFO_DATA_REF (stmt_info); + STMT_VINFO_VECTYPE (vinfo_for_stmt (new_stmt)) = vectype; + } else STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt; prev_stmt_info = vinfo_for_stmt (new_stmt); diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 86c5371..3702c5d 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -633,6 +633,10 @@ typedef struct _stmt_vec_info { /* For both loads and stores. */ bool simd_lane_access_p; + /* True for the first vector statement copy when scalar + statement is vectorized into several vector ones. */ + bool first_copy_p; + /* For reduction loops, this is the type of reduction. */ enum vect_reduction_type v_reduc_type; @@ -666,6 +670,7 @@ STMT_VINFO_BB_VINFO (stmt_vec_info stmt_vinfo) #define STMT_VINFO_GATHER_SCATTER_P(S) (S)->gather_scatter_p #define STMT_VINFO_STRIDED_P(S) (S)->strided_p #define STMT_VINFO_SIMD_LANE_ACCESS_P(S) (S)->simd_lane_access_p +#define STMT_VINFO_FIRST_COPY_P(S) (S)->first_copy_p #define STMT_VINFO_VEC_REDUCTION_TYPE(S) (S)->v_reduc_type #define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address