From: Richard Biener Date: Fri, 5 Jun 2020 08:13:27 +0000 (+0200) Subject: tree-optimization/95539 - fix SLP_TREE_REPRESENTATIVE vs. dr_info X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9758d196f57950ea89baa5cdf6ebd7125b5056e0;p=gcc.git tree-optimization/95539 - fix SLP_TREE_REPRESENTATIVE vs. dr_info This fixes a disconnect between the stmt_info used for dr_info analysis and the one in SLP_TREE_REPRESENTATIVE with a temporary workaround. 2020-06-05 Richard Biener PR tree-optimization/95539 * tree-vect-data-refs.c (vect_slp_analyze_and_verify_instance_alignment): Use SLP_TREE_REPRESENTATIVE for the data-ref check. * tree-vect-stmts.c (vectorizable_load): Reset stmt_info back to the first scalar stmt rather than the SLP_TREE_REPRESENTATIVE to match previous behavior. * gcc.dg/vect/pr95539.c: New testcase. --- diff --git a/gcc/testsuite/gcc.dg/vect/pr95539.c b/gcc/testsuite/gcc.dg/vect/pr95539.c new file mode 100644 index 00000000000..de3b393879e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr95539.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ + +typedef unsigned short uint16_t; +typedef short __v8hi __attribute__ ((__vector_size__ (16))); +typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__)); +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__)) +_mm_set_epi16 (short __q7, short __q6, short __q5, short __q4, + short __q3, short __q2, short __q1, short __q0) +{ + return __extension__ (__m128i)(__v8hi){ + __q0, __q1, __q2, __q3, __q4, __q5, __q6, __q7 }; +} +void gcm_HashMult_hw(__m128i *x, const unsigned char *buf, unsigned int count) +{ + unsigned i; + __m128i bin __attribute__((aligned(16))); + for (i = 0; i < count; i++, buf += 16) + { + bin = _mm_set_epi16(((uint16_t)buf[0] << 8) | buf[1], + ((uint16_t)buf[2] << 8) | buf[3], + ((uint16_t)buf[4] << 8) | buf[5], + ((uint16_t)buf[6] << 8) | buf[7], + ((uint16_t)buf[8] << 8) | buf[9], + ((uint16_t)buf[10] << 8) | buf[11], + ((uint16_t)buf[12] << 8) | buf[13], + ((uint16_t)buf[14] << 8) | buf[15]); + *(x++) = bin; + } +} diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index b950aa9e50d..fe543606a52 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -2471,7 +2471,7 @@ vect_slp_analyze_and_verify_instance_alignment (vec_info *vinfo, return false; node = SLP_INSTANCE_TREE (instance); - if (STMT_VINFO_DATA_REF (SLP_TREE_SCALAR_STMTS (node)[0]) + if (STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (node)) && ! vect_slp_analyze_and_verify_node_alignment (vinfo, SLP_INSTANCE_TREE (instance))) return false; diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index c0be6ef502c..b24b0fe4304 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -8661,6 +8661,20 @@ vectorizable_load (vec_info *vinfo, && ! vec_stmt) return false; + if (!STMT_VINFO_DATA_REF (stmt_info)) + return false; + + /* ??? Alignment analysis for SLP looks at SLP_TREE_SCALAR_STMTS[0] + for unpermuted loads but we get passed SLP_TREE_REPRESENTATIVE + which can be different when reduction chains were re-ordered. + Now that we figured we're a dataref reset stmt_info back to + SLP_TREE_SCALAR_STMTS[0]. When we're SLP only things should be + refactored in a way to maintain the dr_vec_info pointer for the + relevant access explicitely. */ + stmt_vec_info orig_stmt_info = stmt_info; + if (slp_node) + stmt_info = SLP_TREE_SCALAR_STMTS (slp_node)[0]; + tree mask = NULL_TREE, mask_vectype = NULL_TREE; if (gassign *assign = dyn_cast (stmt_info->stmt)) { @@ -8703,9 +8717,6 @@ vectorizable_load (vec_info *vinfo, } } - if (!STMT_VINFO_DATA_REF (stmt_info)) - return false; - tree vectype = STMT_VINFO_VECTYPE (stmt_info); poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); @@ -8876,7 +8887,7 @@ vectorizable_load (vec_info *vinfo, check_load_store_masking (loop_vinfo, vectype, VLS_LOAD, group_size, memory_access_type, &gs_info, mask); - STMT_VINFO_TYPE (stmt_info) = load_vec_info_type; + STMT_VINFO_TYPE (orig_stmt_info) = load_vec_info_type; vect_model_load_cost (vinfo, stmt_info, ncopies, vf, memory_access_type, slp_node, cost_vec); return true;