On Mon, Sep 20, 2021 at 2:15 PM Richard Biener via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> This allows vectorization (in practice non-loop vectorization) to
> have a stmt participate in different vector type vectorizations.
> It allows us to remove vect_update_shared_vectype and replace it
> by pushing/popping STMT_VINFO_VECTYPE from SLP_TREE_VECTYPE around
> vect_analyze_stmt and vect_transform_stmt.
>
> For data-ref the situation is a bit more complicated since we
> analyze alignment info with a specific vector type in mind which
> doesn't play well when that changes.
>
> So the bulk of the change is passing down the actual vector type
> used for a vectorized access to the various accessors of alignment
> info, first and foremost dr_misalignment but also aligned_access_p,
> known_alignment_for_access_p, vect_known_alignment_in_bytes and
> vect_supportable_dr_alignment.  I took the liberty to replace
> ALL_CAPS macro accessors with the lower-case function invocations.
>
> The actual changes to the behavior are in dr_misalignment which now
> is the place factoring in the negative step adjustment as well as
> handling alignment queries for a vector type with bigger alignment
> requirements than what we can (or have) analyze(d).
>
> vect_slp_analyze_node_alignment makes use of this and upon receiving
> a vector type with a bigger alingment desire re-analyzes the DR
> with respect to it but keeps an older more precise result if possible.
> In this context it might be possible to do the analysis just once
> but instead of analyzing with respect to a specific desired alignment
> look for the biggest alignment we can compute a not unknown alignment.
>
> The ChangeLog includes the functional changes but not the bulk due
> to the alignment accessor API changes - I hope that's something good.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, testing on SPEC
> CPU 2017 in progress (for stats and correctness).

No surprises there, a small uplift in vectorized BBs and improvements
of 541.leela_r (1%) and 557.xz_r (2%) (both a bit noisy but seems to be
real) on Zen2 with -Ofast -march=znver2.  Otherwise no off-noise changes.

Richard.

> Any comments?
>
> Thanks,
> Richard.
>
> 2021-09-17  Richard Biener  <rguent...@suse.de>
>
>         PR tree-optimization/97351
>         PR tree-optimization/97352
>         PR tree-optimization/82426
>         * tree-vectorizer.h (dr_misalignment): Add vector type
>         argument.
>         (aligned_access_p): Likewise.
>         (known_alignment_for_access_p): Likewise.
>         (vect_supportable_dr_alignment): Likewise.
>         (vect_known_alignment_in_bytes): Likewise.  Refactor.
>         (DR_MISALIGNMENT): Remove.
>         (vect_update_shared_vectype): Likewise.
>         * tree-vect-data-refs.c (dr_misalignment): Refactor, handle
>         a vector type with larger alignment requirement and apply
>         the negative step adjustment here.
>         (vect_calculate_target_alignment): Remove.
>         (vect_compute_data_ref_alignment): Get explicit vector type
>         argument, do not apply a negative step alignment adjustment
>         here.
>         (vect_slp_analyze_node_alignment): Re-analyze alignment
>         when we re-visit the DR with a bigger desired alignment but
>         keep more precise results from smaller alignments.
>         * tree-vect-slp.c (vect_update_shared_vectype): Remove.
>         (vect_slp_analyze_node_operations_1): Do not update the
>         shared vector type on stmts.
>         * tree-vect-stmts.c (vect_analyze_stmt): Push/pop the
>         vector type of an SLP node to the representative stmt-info.
>         (vect_transform_stmt): Likewise.
>
>         * gcc.target/i386/vect-pr82426.c: New testcase.
>         * gcc.target/i386/vect-pr97352.c: Likewise.
> ---
>  gcc/testsuite/gcc.target/i386/vect-pr82426.c |  32 +++
>  gcc/testsuite/gcc.target/i386/vect-pr97352.c |  22 ++
>  gcc/tree-vect-data-refs.c                    | 217 ++++++++++---------
>  gcc/tree-vect-slp.c                          |  59 -----
>  gcc/tree-vect-stmts.c                        |  77 ++++---
>  gcc/tree-vectorizer.h                        |  32 ++-
>  6 files changed, 231 insertions(+), 208 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/vect-pr82426.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/vect-pr97352.c
>
> diff --git a/gcc/testsuite/gcc.target/i386/vect-pr82426.c 
> b/gcc/testsuite/gcc.target/i386/vect-pr82426.c
> new file mode 100644
> index 00000000000..741a1d14d36
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/vect-pr82426.c
> @@ -0,0 +1,32 @@
> +/* i?86 does not have V2SF, x32 does though.  */
> +/* { dg-do compile { target { lp64 || x32 } } } */
> +/* ???  With AVX512 we only realize one FMA opportunity.  */
> +/* { dg-options "-O3 -mavx -mfma -mno-avx512f" } */
> +
> +struct Matrix
> +{
> +  float m11;
> +  float m12;
> +  float m21;
> +  float m22;
> +  float dx;
> +  float dy;
> +};
> +
> +struct Matrix multiply(const struct Matrix *a, const struct Matrix *b)
> +{
> +  struct Matrix out;
> +  out.m11 = a->m11*b->m11 + a->m12*b->m21;
> +  out.m12 = a->m11*b->m12 + a->m12*b->m22;
> +  out.m21 = a->m21*b->m11 + a->m22*b->m21;
> +  out.m22 = a->m21*b->m12 + a->m22*b->m22;
> +
> +  out.dx = a->dx*b->m11  + a->dy*b->m21 + b->dx;
> +  out.dy = a->dx*b->m12  + a->dy*b->m22 + b->dy;
> +  return out;
> +}
> +
> +/* The whole kernel should be vectorized with V4SF and V2SF operations.  */
> +/* { dg-final { scan-assembler-times "vadd" 1 } } */
> +/* { dg-final { scan-assembler-times "vmul" 2 } } */
> +/* { dg-final { scan-assembler-times "vfma" 2 } } */
> diff --git a/gcc/testsuite/gcc.target/i386/vect-pr97352.c 
> b/gcc/testsuite/gcc.target/i386/vect-pr97352.c
> new file mode 100644
> index 00000000000..d0e120600db
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/vect-pr97352.c
> @@ -0,0 +1,22 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -mavx" } */
> +
> +double x[2], a[4], b[4], c[5];
> +
> +void foo ()
> +{
> +  a[0] = c[0];
> +  a[1] = c[1];
> +  a[2] = c[0];
> +  a[3] = c[1];
> +  b[0] = c[2];
> +  b[1] = c[3];
> +  b[2] = c[2];
> +  b[3] = c[3];
> +  x[0] = c[4];
> +  x[1] = c[4];
> +}
> +
> +/* We should vectorize all three stores and the load from c apart
> +   from c[4] which should be duped.  */
> +/* { dg-final { scan-assembler-times "vmov.pd" 4 } } */
> diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
> index a57700f2c1b..c42fc2fb272 100644
> --- a/gcc/tree-vect-data-refs.c
> +++ b/gcc/tree-vect-data-refs.c
> @@ -887,37 +887,53 @@ vect_slp_analyze_instance_dependence (vec_info *vinfo, 
> slp_instance instance)
>    return res;
>  }
>
> -/* Return the misalignment of DR_INFO.  */
> +/* Return the misalignment of DR_INFO accessed in VECTYPE.  */
>
>  int
> -dr_misalignment (dr_vec_info *dr_info)
> +dr_misalignment (dr_vec_info *dr_info, tree vectype)
>  {
> +  HOST_WIDE_INT diff = 0;
> +  /* Alignment is only analyzed for the first element of a DR group,
> +     use that but adjust misalignment by the offset of the access.  */
>    if (STMT_VINFO_GROUPED_ACCESS (dr_info->stmt))
>      {
>        dr_vec_info *first_dr
>         = STMT_VINFO_DR_INFO (DR_GROUP_FIRST_ELEMENT (dr_info->stmt));
> -      int misalign = first_dr->misalignment;
> -      gcc_assert (misalign != DR_MISALIGNMENT_UNINITIALIZED);
> -      if (misalign == DR_MISALIGNMENT_UNKNOWN)
> -       return misalign;
>        /* vect_analyze_data_ref_accesses guarantees that DR_INIT are
>          INTEGER_CSTs and the first element in the group has the lowest
>          address.  Likewise vect_compute_data_ref_alignment will
>          have ensured that target_alignment is constant and otherwise
>          set misalign to DR_MISALIGNMENT_UNKNOWN.  */
> -      HOST_WIDE_INT diff = (TREE_INT_CST_LOW (DR_INIT (dr_info->dr))
> -                           - TREE_INT_CST_LOW (DR_INIT (first_dr->dr)));
> +      diff = (TREE_INT_CST_LOW (DR_INIT (dr_info->dr))
> +             - TREE_INT_CST_LOW (DR_INIT (first_dr->dr)));
>        gcc_assert (diff >= 0);
> -      unsigned HOST_WIDE_INT target_alignment_c
> -       = first_dr->target_alignment.to_constant ();
> -      return (misalign + diff) % target_alignment_c;
> +      dr_info = first_dr;
>      }
> -  else
> +
> +  int misalign = dr_info->misalignment;
> +  gcc_assert (misalign != DR_MISALIGNMENT_UNINITIALIZED);
> +  if (misalign == DR_MISALIGNMENT_UNKNOWN)
> +    return misalign;
> +
> +  /* If the access is only aligned for a vector type with smaller alignment
> +     requirement the access has unknown misalignment.  */
> +  if (maybe_lt (dr_info->target_alignment * BITS_PER_UNIT,
> +               targetm.vectorize.preferred_vector_alignment (vectype)))
> +    return DR_MISALIGNMENT_UNKNOWN;
> +
> +  /* If this is a backward running DR then first access in the larger
> +     vectype actually is N-1 elements before the address in the DR.
> +     Adjust misalign accordingly.  */
> +  if (tree_int_cst_sgn (DR_STEP (dr_info->dr)) < 0)
>      {
> -      int misalign = dr_info->misalignment;
> -      gcc_assert (misalign != DR_MISALIGNMENT_UNINITIALIZED);
> -      return misalign;
> +      if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant ())
> +       return DR_MISALIGNMENT_UNKNOWN;
> +      diff += ((TYPE_VECTOR_SUBPARTS (vectype).to_constant () - 1)
> +              * -TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype))));
>      }
> +  unsigned HOST_WIDE_INT target_alignment_c
> +    = dr_info->target_alignment.to_constant ();
> +  return (misalign + diff) % target_alignment_c;
>  }
>
>  /* Record the base alignment guarantee given by DRB, which occurs
> @@ -978,34 +994,26 @@ vect_record_base_alignments (vec_info *vinfo)
>      }
>  }
>
> -/* Return the target alignment for the vectorized form of DR_INFO.  */
> -
> -static poly_uint64
> -vect_calculate_target_alignment (dr_vec_info *dr_info)
> -{
> -  tree vectype = STMT_VINFO_VECTYPE (dr_info->stmt);
> -  return targetm.vectorize.preferred_vector_alignment (vectype);
> -}
> -
>  /* Function vect_compute_data_ref_alignment
>
> -   Compute the misalignment of the data reference DR_INFO.
> +   Compute the misalignment of the data reference DR_INFO when vectorizing
> +   with VECTYPE.
>
>     Output:
> -   1. DR_MISALIGNMENT (DR_INFO) is defined.
> +   1. initialized misalignment info for DR_INFO
>
>     FOR NOW: No analysis is actually performed. Misalignment is calculated
>     only for trivial cases. TODO.  */
>
>  static void
> -vect_compute_data_ref_alignment (vec_info *vinfo, dr_vec_info *dr_info)
> +vect_compute_data_ref_alignment (vec_info *vinfo, dr_vec_info *dr_info,
> +                                tree vectype)
>  {
>    stmt_vec_info stmt_info = dr_info->stmt;
>    vec_base_alignments *base_alignments = &vinfo->base_alignments;
>    loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
>    class loop *loop = NULL;
>    tree ref = DR_REF (dr_info->dr);
> -  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
>
>    if (dump_enabled_p ())
>      dump_printf_loc (MSG_NOTE, vect_location,
> @@ -1024,7 +1032,8 @@ vect_compute_data_ref_alignment (vec_info *vinfo, 
> dr_vec_info *dr_info)
>    bool step_preserves_misalignment_p;
>
>    poly_uint64 vector_alignment
> -    = exact_div (vect_calculate_target_alignment (dr_info), BITS_PER_UNIT);
> +    = exact_div (targetm.vectorize.preferred_vector_alignment (vectype),
> +                BITS_PER_UNIT);
>    SET_DR_TARGET_ALIGNMENT (dr_info, vector_alignment);
>
>    /* If the main loop has peeled for alignment we have no way of knowing
> @@ -1147,14 +1156,6 @@ vect_compute_data_ref_alignment (vec_info *vinfo, 
> dr_vec_info *dr_info)
>    poly_int64 misalignment
>      = base_misalignment + wi::to_poly_offset (drb->init).force_shwi ();
>
> -  /* If this is a backward running DR then first access in the larger
> -     vectype actually is N-1 elements before the address in the DR.
> -     Adjust misalign accordingly.  */
> -  if (tree_int_cst_sgn (drb->step) < 0)
> -    /* PLUS because STEP is negative.  */
> -    misalignment += ((TYPE_VECTOR_SUBPARTS (vectype) - 1)
> -                    * -TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE 
> (vectype))));
> -
>    unsigned int const_misalignment;
>    if (!known_misalignment (misalignment, vect_align_c, &const_misalignment))
>      {
> @@ -1169,7 +1170,7 @@ vect_compute_data_ref_alignment (vec_info *vinfo, 
> dr_vec_info *dr_info)
>    if (dump_enabled_p ())
>      dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
>                      "misalign = %d bytes of ref %T\n",
> -                    DR_MISALIGNMENT (dr_info), ref);
> +                    const_misalignment, ref);
>
>    return;
>  }
> @@ -1237,14 +1238,15 @@ vect_update_misalignment_for_peel (dr_vec_info 
> *dr_info,
>      }
>
>    unsigned HOST_WIDE_INT alignment;
> +  tree vectype = STMT_VINFO_VECTYPE (dr_info->stmt);
>    if (DR_TARGET_ALIGNMENT (dr_info).is_constant (&alignment)
> -      && known_alignment_for_access_p (dr_info)
> -      && known_alignment_for_access_p (dr_peel_info))
> +      && known_alignment_for_access_p (dr_info, vectype)
> +      && known_alignment_for_access_p (dr_peel_info, vectype))
>      {
> -      int misal = DR_MISALIGNMENT (dr_info);
> +      int misal = dr_misalignment (dr_info, vectype);
>        misal += npeel * TREE_INT_CST_LOW (DR_STEP (dr_info->dr));
>        misal &= alignment - 1;
> -      SET_DR_MISALIGNMENT (dr_info, misal);
> +      set_dr_misalignment (dr_info, misal);
>        return;
>      }
>
> @@ -1316,13 +1318,13 @@ vector_alignment_reachable_p (dr_vec_info *dr_info)
>        int elem_size, mis_in_elements;
>
>        /* FORNOW: handle only known alignment.  */
> -      if (!known_alignment_for_access_p (dr_info))
> +      if (!known_alignment_for_access_p (dr_info, vectype))
>         return false;
>
>        poly_uint64 nelements = TYPE_VECTOR_SUBPARTS (vectype);
>        poly_uint64 vector_size = GET_MODE_SIZE (TYPE_MODE (vectype));
>        elem_size = vector_element_size (vector_size, nelements);
> -      mis_in_elements = DR_MISALIGNMENT (dr_info) / elem_size;
> +      mis_in_elements = dr_misalignment (dr_info, vectype) / elem_size;
>
>        if (!multiple_p (nelements - mis_in_elements, DR_GROUP_SIZE 
> (stmt_info)))
>         return false;
> @@ -1330,7 +1332,8 @@ vector_alignment_reachable_p (dr_vec_info *dr_info)
>
>    /* If misalignment is known at the compile time then allow peeling
>       only if natural alignment is reachable through peeling.  */
> -  if (known_alignment_for_access_p (dr_info) && !aligned_access_p (dr_info))
> +  if (known_alignment_for_access_p (dr_info, vectype)
> +      && !aligned_access_p (dr_info, vectype))
>      {
>        HOST_WIDE_INT elmsize =
>                 int_cst_value (TYPE_SIZE_UNIT (TREE_TYPE (vectype)));
> @@ -1338,9 +1341,9 @@ vector_alignment_reachable_p (dr_vec_info *dr_info)
>         {
>           dump_printf_loc (MSG_NOTE, vect_location,
>                            "data size = %wd. misalignment = %d.\n", elmsize,
> -                          DR_MISALIGNMENT (dr_info));
> +                          dr_misalignment (dr_info, vectype));
>         }
> -      if (DR_MISALIGNMENT (dr_info) % elmsize)
> +      if (dr_misalignment (dr_info, vectype) % elmsize)
>         {
>           if (dump_enabled_p ())
>             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> @@ -1349,7 +1352,7 @@ vector_alignment_reachable_p (dr_vec_info *dr_info)
>         }
>      }
>
> -  if (!known_alignment_for_access_p (dr_info))
> +  if (!known_alignment_for_access_p (dr_info, vectype))
>      {
>        tree type = TREE_TYPE (DR_REF (dr_info->dr));
>        bool is_packed = not_size_aligned (DR_REF (dr_info->dr));
> @@ -1441,8 +1444,9 @@ vect_peeling_hash_insert (hash_table<peel_info_hasher> 
> *peeling_htab,
>  {
>    struct _vect_peel_info elem, *slot;
>    _vect_peel_info **new_slot;
> +  tree vectype = STMT_VINFO_VECTYPE (dr_info->stmt);
>    bool supportable_dr_alignment
> -    = vect_supportable_dr_alignment (loop_vinfo, dr_info, true);
> +    = vect_supportable_dr_alignment (loop_vinfo, dr_info, vectype, true);
>
>    elem.npeel = npeel;
>    slot = peeling_htab->find (&elem);
> @@ -1508,7 +1512,7 @@ vect_get_peeling_costs_all_drs (loop_vec_info 
> loop_vinfo,
>         continue;
>
>        int save_misalignment;
> -      save_misalignment = DR_MISALIGNMENT (dr_info);
> +      save_misalignment = dr_info->misalignment;
>        if (npeel == 0)
>         ;
>        else if (unknown_misalignment && dr_info == dr0_info)
> @@ -1625,10 +1629,11 @@ vect_peeling_supportable (loop_vec_info loop_vinfo, 
> dr_vec_info *dr0_info,
>        if (!vect_relevant_for_alignment_p (dr_info))
>         continue;
>
> -      save_misalignment = DR_MISALIGNMENT (dr_info);
> +      save_misalignment = dr_info->misalignment;
>        vect_update_misalignment_for_peel (dr_info, dr0_info, npeel);
> +      tree vectype = STMT_VINFO_VECTYPE (dr_info->stmt);
>        supportable_dr_alignment
> -       = vect_supportable_dr_alignment (loop_vinfo, dr_info, false);
> +       = vect_supportable_dr_alignment (loop_vinfo, dr_info, vectype, false);
>        SET_DR_MISALIGNMENT (dr_info, save_misalignment);
>
>        if (!supportable_dr_alignment)
> @@ -1782,7 +1787,7 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>    bool one_misalignment_unknown = false;
>    bool one_dr_unsupportable = false;
>    dr_vec_info *unsupportable_dr_info = NULL;
> -  unsigned int mis, dr0_same_align_drs = 0, first_store_same_align_drs = 0;
> +  unsigned int dr0_same_align_drs = 0, first_store_same_align_drs = 0;
>    hash_table<peel_info_hasher> peeling_htab (1);
>
>    DUMP_VECT_SCOPE ("vect_enhance_data_refs_alignment");
> @@ -1878,12 +1883,13 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>         continue;
>
>        stmt_vec_info stmt_info = dr_info->stmt;
> +      tree vectype = STMT_VINFO_VECTYPE (stmt_info);
>        supportable_dr_alignment
> -       = vect_supportable_dr_alignment (loop_vinfo, dr_info, true);
> +       = vect_supportable_dr_alignment (loop_vinfo, dr_info, vectype, true);
>        do_peeling = vector_alignment_reachable_p (dr_info);
>        if (do_peeling)
>          {
> -          if (known_alignment_for_access_p (dr_info))
> +         if (known_alignment_for_access_p (dr_info, vectype))
>              {
>               unsigned int npeel_tmp = 0;
>               bool negative = tree_int_cst_compare (DR_STEP (dr),
> @@ -1896,10 +1902,9 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>               unsigned int target_align =
>                 DR_TARGET_ALIGNMENT (dr_info).to_constant ();
>               unsigned int dr_size = vect_get_scalar_dr_size (dr_info);
> -             mis = (negative
> -                    ? DR_MISALIGNMENT (dr_info)
> -                    : -DR_MISALIGNMENT (dr_info));
> -             if (DR_MISALIGNMENT (dr_info) != 0)
> +             unsigned int mis = dr_misalignment (dr_info, vectype);
> +             mis = negative ? mis : -mis;
> +             if (mis != 0)
>                 npeel_tmp = (mis & (target_align - 1)) / dr_size;
>
>                /* For multiple types, it is possible that the bigger type 
> access
> @@ -1982,7 +1987,7 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>          }
>        else
>          {
> -          if (!aligned_access_p (dr_info))
> +         if (!aligned_access_p (dr_info, vectype))
>              {
>                if (dump_enabled_p ())
>                  dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> @@ -2152,7 +2157,8 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>    if (do_peeling)
>      {
>        stmt_vec_info stmt_info = dr0_info->stmt;
> -      if (known_alignment_for_access_p (dr0_info))
> +      if (known_alignment_for_access_p (dr0_info,
> +                                       STMT_VINFO_VECTYPE (stmt_info)))
>          {
>           bool negative = tree_int_cst_compare (DR_STEP (dr0_info->dr),
>                                                 size_zero_node) < 0;
> @@ -2163,9 +2169,9 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>                   updating DR_MISALIGNMENT values.  The peeling factor is the
>                   vectorization factor minus the misalignment as an element
>                   count.  */
> -             mis = (negative
> -                    ? DR_MISALIGNMENT (dr0_info)
> -                    : -DR_MISALIGNMENT (dr0_info));
> +             unsigned int mis
> +               = dr_misalignment (dr0_info, STMT_VINFO_VECTYPE (stmt_info));
> +             mis = negative ? mis : -mis;
>               /* If known_alignment_for_access_p then we have set
>                  DR_MISALIGNMENT which is only done if we know it at compiler
>                  time, so it is safe to assume target alignment is constant.
> @@ -2192,7 +2198,10 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>         do_peeling = false;
>
>        /* Check if all datarefs are supportable and log.  */
> -      if (do_peeling && known_alignment_for_access_p (dr0_info) && npeel == 
> 0)
> +      if (do_peeling
> +         && npeel == 0
> +         && known_alignment_for_access_p (dr0_info,
> +                                          STMT_VINFO_VECTYPE (stmt_info)))
>         return opt_result::success ();
>
>        /* Cost model #1 - honor --param vect-max-peeling-for-alignment.  */
> @@ -2304,11 +2313,12 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>        FOR_EACH_VEC_ELT (datarefs, i, dr)
>          {
>           dr_vec_info *dr_info = loop_vinfo->lookup_dr (dr);
> -         if (aligned_access_p (dr_info)
> +         stmt_vec_info stmt_info = dr_info->stmt;
> +         tree vectype = STMT_VINFO_VECTYPE (stmt_info);
> +         if (aligned_access_p (dr_info, vectype)
>               || !vect_relevant_for_alignment_p (dr_info))
>             continue;
>
> -         stmt_vec_info stmt_info = dr_info->stmt;
>           if (STMT_VINFO_STRIDED_P (stmt_info))
>             {
>               do_versioning = false;
> @@ -2316,14 +2326,11 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>             }
>
>           supportable_dr_alignment
> -           = vect_supportable_dr_alignment (loop_vinfo, dr_info, false);
> -
> +           = vect_supportable_dr_alignment (loop_vinfo, dr_info, vectype,
> +                                            false);
>            if (!supportable_dr_alignment)
>              {
> -              int mask;
> -              tree vectype;
> -
> -              if (known_alignment_for_access_p (dr_info)
> +             if (known_alignment_for_access_p (dr_info, vectype)
>                    || LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).length ()
>                   >= (unsigned) param_vect_max_version_for_alignment_checks)
>                  {
> @@ -2331,9 +2338,6 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>                    break;
>                  }
>
> -             vectype = STMT_VINFO_VECTYPE (stmt_info);
> -             gcc_assert (vectype);
> -
>               /* At present we don't support versioning for alignment
>                  with variable VF, since there's no guarantee that the
>                  VF is a power of two.  We could relax this if we added
> @@ -2363,7 +2367,7 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>                   Construct the mask needed for this test.  For example,
>                   GET_MODE_SIZE for the vector mode V4SI is 16 bytes so the
>                   mask must be 15 = 0xf. */
> -             mask = size - 1;
> +             int mask = size - 1;
>
>               /* FORNOW: use the same mask to test all potentially unaligned
>                  references in the loop.  */
> @@ -2444,7 +2448,8 @@ vect_analyze_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>           if (STMT_VINFO_GROUPED_ACCESS (dr_info->stmt)
>               && DR_GROUP_FIRST_ELEMENT (dr_info->stmt) != dr_info->stmt)
>             continue;
> -         vect_compute_data_ref_alignment (loop_vinfo, dr_info);
> +         vect_compute_data_ref_alignment (loop_vinfo, dr_info,
> +                                          STMT_VINFO_VECTYPE 
> (dr_info->stmt));
>         }
>      }
>
> @@ -2460,21 +2465,30 @@ vect_slp_analyze_node_alignment (vec_info *vinfo, 
> slp_tree node)
>    /* Alignment is maintained in the first element of the group.  */
>    stmt_vec_info first_stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
>    first_stmt_info = DR_GROUP_FIRST_ELEMENT (first_stmt_info);
> -
> -  /* We need to commit to a vector type for the group now.  */
> -  if (is_a <bb_vec_info> (vinfo)
> -      && !vect_update_shared_vectype (first_stmt_info, SLP_TREE_VECTYPE 
> (node)))
> -    {
> -      if (dump_enabled_p ())
> -       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> -                        "desired vector type conflicts with earlier one "
> -                        "for %G", first_stmt_info->stmt);
> -      return false;
> -    }
> -
>    dr_vec_info *dr_info = STMT_VINFO_DR_INFO (first_stmt_info);
> +  tree vectype = SLP_TREE_VECTYPE (node);
> +  poly_uint64 vector_alignment
> +    = exact_div (targetm.vectorize.preferred_vector_alignment (vectype),
> +                BITS_PER_UNIT);
>    if (dr_info->misalignment == DR_MISALIGNMENT_UNINITIALIZED)
> -    vect_compute_data_ref_alignment (vinfo, dr_info);
> +    vect_compute_data_ref_alignment (vinfo, dr_info, SLP_TREE_VECTYPE 
> (node));
> +  /* Re-analyze alignment when we're facing a vectorization with a bigger
> +     alignment requirement.  */
> +  else if (known_lt (dr_info->target_alignment, vector_alignment))
> +    {
> +      poly_uint64 old_target_alignment = dr_info->target_alignment;
> +      int old_misalignment = dr_info->misalignment;
> +      vect_compute_data_ref_alignment (vinfo, dr_info, SLP_TREE_VECTYPE 
> (node));
> +      /* But keep knowledge about a smaller alignment.  */
> +      if (old_misalignment != DR_MISALIGNMENT_UNKNOWN
> +         && dr_info->misalignment == DR_MISALIGNMENT_UNKNOWN)
> +       {
> +         dr_info->target_alignment = old_target_alignment;
> +         dr_info->misalignment = old_misalignment;
> +       }
> +    }
> +  /* When we ever face unordered target alignments the first one wins in 
> terms
> +     of analyzing and the other will become unknown in dr_misalignment.  */
>    return true;
>  }
>
> @@ -3259,12 +3273,12 @@ vect_vfa_access_size (vec_info *vinfo, dr_vec_info 
> *dr_info)
>        gcc_assert (DR_GROUP_FIRST_ELEMENT (stmt_vinfo) == stmt_vinfo);
>        access_size *= DR_GROUP_SIZE (stmt_vinfo) - DR_GROUP_GAP (stmt_vinfo);
>      }
> +  tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
>    if (STMT_VINFO_VEC_STMTS (stmt_vinfo).exists ()
> -      && (vect_supportable_dr_alignment (vinfo, dr_info, false)
> +      && (vect_supportable_dr_alignment (vinfo, dr_info, vectype, false)
>           == dr_explicit_realign_optimized))
>      {
>        /* We might access a full vector's worth.  */
> -      tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
>        access_size += tree_to_uhwi (TYPE_SIZE_UNIT (vectype)) - ref_size;
>      }
>    return access_size;
> @@ -4730,7 +4744,7 @@ vect_create_addr_base_for_vector_ref (vec_info *vinfo, 
> stmt_vec_info stmt_info,
>                           unshare_expr (DR_REF (dr)));
>      }
>
> -  vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info));
> +  vect_ptr_type = build_pointer_type (TREE_TYPE (DR_REF (dr)));
>    dest = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var, base_name);
>    addr_base = force_gimple_operand (addr_base, &seq, true, dest);
>    gimple_seq_add_seq (new_stmt_list, seq);
> @@ -6581,17 +6595,16 @@ vect_can_force_dr_alignment_p (const_tree decl, 
> poly_uint64 alignment)
>
>  enum dr_alignment_support
>  vect_supportable_dr_alignment (vec_info *vinfo, dr_vec_info *dr_info,
> -                               bool check_aligned_accesses)
> +                              tree vectype, bool check_aligned_accesses)
>  {
>    data_reference *dr = dr_info->dr;
>    stmt_vec_info stmt_info = dr_info->stmt;
> -  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
>    machine_mode mode = TYPE_MODE (vectype);
>    loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
>    class loop *vect_loop = NULL;
>    bool nested_in_vect_loop = false;
>
> -  if (aligned_access_p (dr_info) && !check_aligned_accesses)
> +  if (aligned_access_p (dr_info, vectype) && !check_aligned_accesses)
>      return dr_aligned;
>
>    /* For now assume all conditional loads/stores support unaligned
> @@ -6680,8 +6693,6 @@ vect_supportable_dr_alignment (vec_info *vinfo, 
> dr_vec_info *dr_info,
>           && (!targetm.vectorize.builtin_mask_for_load
>               || targetm.vectorize.builtin_mask_for_load ()))
>         {
> -         tree vectype = STMT_VINFO_VECTYPE (stmt_info);
> -
>           /* If we are doing SLP then the accesses need not have the
>              same alignment, instead it depends on the SLP group size.  */
>           if (loop_vinfo
> @@ -6699,11 +6710,11 @@ vect_supportable_dr_alignment (vec_info *vinfo, 
> dr_vec_info *dr_info,
>           else
>             return dr_explicit_realign_optimized;
>         }
> -      if (!known_alignment_for_access_p (dr_info))
> +      if (!known_alignment_for_access_p (dr_info, vectype))
>         is_packed = not_size_aligned (DR_REF (dr));
>
>        if (targetm.vectorize.support_vector_misalignment
> -           (mode, type, DR_MISALIGNMENT (dr_info), is_packed))
> +           (mode, type, dr_misalignment (dr_info, vectype), is_packed))
>         /* Can't software pipeline the loads, but can at least do them.  */
>         return dr_unaligned_supported;
>      }
> @@ -6712,11 +6723,11 @@ vect_supportable_dr_alignment (vec_info *vinfo, 
> dr_vec_info *dr_info,
>        bool is_packed = false;
>        tree type = (TREE_TYPE (DR_REF (dr)));
>
> -      if (!known_alignment_for_access_p (dr_info))
> +      if (!known_alignment_for_access_p (dr_info, vectype))
>         is_packed = not_size_aligned (DR_REF (dr));
>
>       if (targetm.vectorize.support_vector_misalignment
> -          (mode, type, DR_MISALIGNMENT (dr_info), is_packed))
> +          (mode, type, dr_misalignment (dr_info, vectype), is_packed))
>         return dr_unaligned_supported;
>      }
>
> diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
> index 024a1c38a23..c70d06e5f20 100644
> --- a/gcc/tree-vect-slp.c
> +++ b/gcc/tree-vect-slp.c
> @@ -779,56 +779,6 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned 
> char swap,
>    return 0;
>  }
>
> -/* Try to assign vector type VECTYPE to STMT_INFO for BB vectorization.
> -   Return true if we can, meaning that this choice doesn't conflict with
> -   existing SLP nodes that use STMT_INFO.  */
> -
> -bool
> -vect_update_shared_vectype (stmt_vec_info stmt_info, tree vectype)
> -{
> -  tree old_vectype = STMT_VINFO_VECTYPE (stmt_info);
> -  if (old_vectype)
> -    return useless_type_conversion_p (vectype, old_vectype);
> -
> -  if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
> -    {
> -      /* We maintain the invariant that if any statement in the group is
> -        used, all other members of the group have the same vector type.  */
> -      stmt_vec_info first_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
> -      stmt_vec_info member_info = first_info;
> -      for (; member_info; member_info = DR_GROUP_NEXT_ELEMENT (member_info))
> -       if (is_pattern_stmt_p (member_info)
> -           && !useless_type_conversion_p (vectype,
> -                                          STMT_VINFO_VECTYPE (member_info)))
> -         break;
> -
> -      if (!member_info)
> -       {
> -         for (member_info = first_info; member_info;
> -              member_info = DR_GROUP_NEXT_ELEMENT (member_info))
> -           STMT_VINFO_VECTYPE (member_info) = vectype;
> -         return true;
> -       }
> -    }
> -  else if (!is_pattern_stmt_p (stmt_info))
> -    {
> -      STMT_VINFO_VECTYPE (stmt_info) = vectype;
> -      return true;
> -    }
> -
> -  if (dump_enabled_p ())
> -    {
> -      dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> -                      "Build SLP failed: incompatible vector"
> -                      " types for: %G", stmt_info->stmt);
> -      dump_printf_loc (MSG_NOTE, vect_location,
> -                      "    old vector type: %T\n", old_vectype);
> -      dump_printf_loc (MSG_NOTE, vect_location,
> -                      "    new vector type: %T\n", vectype);
> -    }
> -  return false;
> -}
> -
>  /* Return true if call statements CALL1 and CALL2 are similar enough
>     to be combined into the same SLP group.  */
>
> @@ -4508,15 +4458,6 @@ vect_slp_analyze_node_operations_1 (vec_info *vinfo, 
> slp_tree node,
>      return vectorizable_slp_permutation (vinfo, NULL, node, cost_vec);
>
>    gcc_assert (STMT_SLP_TYPE (stmt_info) != loop_vect);
> -  if (is_a <bb_vec_info> (vinfo)
> -      && !vect_update_shared_vectype (stmt_info, SLP_TREE_VECTYPE (node)))
> -    {
> -      if (dump_enabled_p ())
> -       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> -                        "desired vector type conflicts with earlier one "
> -                        "for %G", stmt_info->stmt);
> -      return false;
> -    }
>
>    bool dummy;
>    return vect_analyze_stmt (vinfo, stmt_info, &dummy,
> diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
> index 17849b575b7..a9c9e3d7c37 100644
> --- a/gcc/tree-vect-stmts.c
> +++ b/gcc/tree-vect-stmts.c
> @@ -1026,8 +1026,9 @@ vect_get_store_cost (vec_info *vinfo, stmt_vec_info 
> stmt_info, int ncopies,
>                      stmt_vector_for_cost *body_cost_vec)
>  {
>    dr_vec_info *dr_info = STMT_VINFO_DR_INFO (stmt_info);
> +  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
>    int alignment_support_scheme
> -    = vect_supportable_dr_alignment (vinfo, dr_info, false);
> +    = vect_supportable_dr_alignment (vinfo, dr_info, vectype, false);
>
>    switch (alignment_support_scheme)
>      {
> @@ -1048,7 +1049,7 @@ vect_get_store_cost (vec_info *vinfo, stmt_vec_info 
> stmt_info, int ncopies,
>          /* Here, we assign an additional cost for the unaligned store.  */
>         *inside_cost += record_stmt_cost (body_cost_vec, ncopies,
>                                           unaligned_store, stmt_info,
> -                                         DR_MISALIGNMENT (dr_info),
> +                                         dr_misalignment (dr_info, vectype),
>                                           vect_body);
>          if (dump_enabled_p ())
>            dump_printf_loc (MSG_NOTE, vect_location,
> @@ -1216,8 +1217,9 @@ vect_get_load_cost (vec_info *vinfo, stmt_vec_info 
> stmt_info, int ncopies,
>                     bool record_prologue_costs)
>  {
>    dr_vec_info *dr_info = STMT_VINFO_DR_INFO (stmt_info);
> +  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
>    int alignment_support_scheme
> -    = vect_supportable_dr_alignment (vinfo, dr_info, false);
> +    = vect_supportable_dr_alignment (vinfo, dr_info, vectype, false);
>
>    switch (alignment_support_scheme)
>      {
> @@ -1237,7 +1239,7 @@ vect_get_load_cost (vec_info *vinfo, stmt_vec_info 
> stmt_info, int ncopies,
>          /* Here, we assign an additional cost for the unaligned load.  */
>         *inside_cost += record_stmt_cost (body_cost_vec, ncopies,
>                                           unaligned_load, stmt_info,
> -                                         DR_MISALIGNMENT (dr_info),
> +                                         dr_misalignment (dr_info, vectype),
>                                           vect_body);
>
>          if (dump_enabled_p ())
> @@ -1984,8 +1986,8 @@ get_negative_load_store_type (vec_info *vinfo,
>        return VMAT_ELEMENTWISE;
>      }
>
> -  alignment_support_scheme = vect_supportable_dr_alignment (vinfo,
> -                                                           dr_info, false);
> +  alignment_support_scheme = vect_supportable_dr_alignment (vinfo, dr_info,
> +                                                           vectype, false);
>    if (alignment_support_scheme != dr_aligned
>        && alignment_support_scheme != dr_unaligned_supported)
>      {
> @@ -2169,7 +2171,8 @@ get_group_load_store_type (vec_info *vinfo, 
> stmt_vec_info stmt_info,
>              be a multiple of B and so we are guaranteed to access a
>              non-gap element in the same B-sized block.  */
>           if (overrun_p
> -             && gap < (vect_known_alignment_in_bytes (first_dr_info)
> +             && gap < (vect_known_alignment_in_bytes (first_dr_info,
> +                                                      vectype)
>                         / vect_get_scalar_dr_size (first_dr_info)))
>             overrun_p = false;
>
> @@ -2182,8 +2185,8 @@ get_group_load_store_type (vec_info *vinfo, 
> stmt_vec_info stmt_info,
>           if (overrun_p
>               && !masked_p
>               && (((alignment_support_scheme
> -                     = vect_supportable_dr_alignment (vinfo,
> -                                                      first_dr_info, false)))
> +                     = vect_supportable_dr_alignment (vinfo, first_dr_info,
> +                                                      vectype, false)))
>                    == dr_aligned
>                   || alignment_support_scheme == dr_unaligned_supported)
>               && known_eq (nunits, (group_size - gap) * 2)
> @@ -2240,7 +2243,7 @@ get_group_load_store_type (vec_info *vinfo, 
> stmt_vec_info stmt_info,
>          same B-sized block.  */
>        if (would_overrun_p
>           && !masked_p
> -         && gap < (vect_known_alignment_in_bytes (first_dr_info)
> +         && gap < (vect_known_alignment_in_bytes (first_dr_info, vectype)
>                     / vect_get_scalar_dr_size (first_dr_info)))
>         would_overrun_p = false;
>
> @@ -2294,7 +2297,7 @@ get_group_load_store_type (vec_info *vinfo, 
> stmt_vec_info stmt_info,
>      *alignment_support_scheme = dr_unaligned_supported;
>    else
>      *alignment_support_scheme
> -      = vect_supportable_dr_alignment (vinfo, first_dr_info, false);
> +      = vect_supportable_dr_alignment (vinfo, first_dr_info, vectype, false);
>
>    if (vls_type != VLS_LOAD && first_stmt_info == stmt_info)
>      {
> @@ -2435,7 +2438,7 @@ get_load_store_type (vec_info  *vinfo, stmt_vec_info 
> stmt_info,
>           *alignment_support_scheme
>             = vect_supportable_dr_alignment (vinfo,
>                                              STMT_VINFO_DR_INFO (stmt_info),
> -                                            false);
> +                                            vectype, false);
>         }
>      }
>
> @@ -7907,7 +7910,7 @@ vectorizable_store (vec_info *vinfo,
>      alignment_support_scheme = dr_unaligned_supported;
>    else
>      alignment_support_scheme
> -      = vect_supportable_dr_alignment (vinfo, first_dr_info, false);
> +      = vect_supportable_dr_alignment (vinfo, first_dr_info, vectype, false);
>
>    gcc_assert (alignment_support_scheme);
>    vec_loop_masks *loop_masks
> @@ -8218,15 +8221,16 @@ vectorizable_store (vec_info *vinfo,
>                 vec_oprnd = result_chain[i];
>
>               align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info));
> -             if (aligned_access_p (first_dr_info))
> +             if (aligned_access_p (first_dr_info, vectype))
>                 misalign = 0;
> -             else if (DR_MISALIGNMENT (first_dr_info) == -1)
> +             else if (dr_misalignment (first_dr_info, vectype)
> +                      == DR_MISALIGNMENT_UNKNOWN)
>                 {
>                   align = dr_alignment (vect_dr_behavior (vinfo, 
> first_dr_info));
>                   misalign = 0;
>                 }
>               else
> -               misalign = DR_MISALIGNMENT (first_dr_info);
> +               misalign = dr_misalignment (first_dr_info, vectype);
>               if (dataref_offset == NULL_TREE
>                   && TREE_CODE (dataref_ptr) == SSA_NAME)
>                 set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
> @@ -8303,7 +8307,7 @@ vectorizable_store (vec_info *vinfo,
>                                           dataref_offset
>                                           ? dataref_offset
>                                           : build_int_cst (ref_type, 0));
> -                 if (aligned_access_p (first_dr_info))
> +                 if (aligned_access_p (first_dr_info, vectype))
>                     ;
>                   else
>                     TREE_TYPE (data_ref)
> @@ -9551,17 +9555,17 @@ vectorizable_load (vec_info *vinfo,
>                       known_alignment (DR_TARGET_ALIGNMENT (first_dr_info));
>                     if (alignment_support_scheme == dr_aligned)
>                       {
> -                       gcc_assert (aligned_access_p (first_dr_info));
> +                       gcc_assert (aligned_access_p (first_dr_info, 
> vectype));
>                         misalign = 0;
>                       }
> -                   else if (DR_MISALIGNMENT (first_dr_info) == -1)
> +                   else if (dr_misalignment (first_dr_info, vectype) == -1)
>                       {
>                         align = dr_alignment
>                           (vect_dr_behavior (vinfo, first_dr_info));
>                         misalign = 0;
>                       }
>                     else
> -                     misalign = DR_MISALIGNMENT (first_dr_info);
> +                     misalign = dr_misalignment (first_dr_info, vectype);
>                     if (dataref_offset == NULL_TREE
>                         && TREE_CODE (dataref_ptr) == SSA_NAME)
>                       set_ptr_info_alignment (get_ptr_info (dataref_ptr),
> @@ -9624,7 +9628,8 @@ vectorizable_load (vec_info *vinfo,
>                         unsigned HOST_WIDE_INT gap
>                           = DR_GROUP_GAP (first_stmt_info);
>                         unsigned int vect_align
> -                         = vect_known_alignment_in_bytes (first_dr_info);
> +                         = vect_known_alignment_in_bytes (first_dr_info,
> +                                                          vectype);
>                         unsigned int scalar_dr_size
>                           = vect_get_scalar_dr_size (first_dr_info);
>                         /* If there's no peeling for gaps but we have a gap
> @@ -10897,6 +10902,10 @@ vect_analyze_stmt (vec_info *vinfo,
>          gcc_unreachable ();
>      }
>
> +  tree saved_vectype = STMT_VINFO_VECTYPE (stmt_info);
> +  if (node)
> +    STMT_VINFO_VECTYPE (stmt_info) = SLP_TREE_VECTYPE (node);
> +
>    if (STMT_VINFO_RELEVANT_P (stmt_info))
>      {
>        gcall *call = dyn_cast <gcall *> (stmt_info->stmt);
> @@ -10967,6 +10976,9 @@ vect_analyze_stmt (vec_info *vinfo,
>               || vectorizable_phi (vinfo, stmt_info, NULL, node, cost_vec));
>      }
>
> +  if (node)
> +    STMT_VINFO_VECTYPE (stmt_info) = saved_vectype;
> +
>    if (!ok)
>      return opt_result::failure_at (stmt_info->stmt,
>                                    "not vectorized:"
> @@ -11005,6 +11017,10 @@ vect_transform_stmt (vec_info *vinfo,
>
>    gcc_assert (slp_node || !PURE_SLP_STMT (stmt_info));
>
> +  tree saved_vectype = STMT_VINFO_VECTYPE (stmt_info);
> +  if (slp_node)
> +    STMT_VINFO_VECTYPE (stmt_info) = SLP_TREE_VECTYPE (slp_node);
> +
>    switch (STMT_VINFO_TYPE (stmt_info))
>      {
>      case type_demotion_vec_info_type:
> @@ -11123,16 +11139,19 @@ vect_transform_stmt (vec_info *vinfo,
>    if (!slp_node && vec_stmt)
>      gcc_assert (STMT_VINFO_VEC_STMTS (stmt_info).exists ());
>
> -  if (STMT_VINFO_TYPE (stmt_info) == store_vec_info_type)
> -    return is_store;
> +  if (STMT_VINFO_TYPE (stmt_info) != store_vec_info_type)
> +    {
> +      /* Handle stmts whose DEF is used outside the loop-nest that is
> +        being vectorized.  */
> +      done = can_vectorize_live_stmts (vinfo, stmt_info, gsi, slp_node,
> +                                      slp_node_instance, true, NULL);
> +      gcc_assert (done);
> +    }
>
> -  /* Handle stmts whose DEF is used outside the loop-nest that is
> -     being vectorized.  */
> -  done = can_vectorize_live_stmts (vinfo, stmt_info, gsi, slp_node,
> -                                  slp_node_instance, true, NULL);
> -  gcc_assert (done);
> +  if (slp_node)
> +    STMT_VINFO_VECTYPE (stmt_info) = saved_vectype;
>
> -  return false;
> +  return is_store;
>  }
>
>
> diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
> index c4c5678e7f1..ed4a7ff646c 100644
> --- a/gcc/tree-vectorizer.h
> +++ b/gcc/tree-vectorizer.h
> @@ -1606,11 +1606,8 @@ set_dr_misalignment (dr_vec_info *dr_info, int val)
>    dr_info->misalignment = val;
>  }
>
> -extern int dr_misalignment (dr_vec_info *dr_info);
> +extern int dr_misalignment (dr_vec_info *dr_info, tree vectype);
>
> -/* Reflects actual alignment of first access in the vectorized loop,
> -   taking into account peeling/versioning if applied.  */
> -#define DR_MISALIGNMENT(DR) dr_misalignment (DR)
>  #define SET_DR_MISALIGNMENT(DR, VAL) set_dr_misalignment (DR, VAL)
>
>  /* Only defined once DR_MISALIGNMENT is defined.  */
> @@ -1630,35 +1627,37 @@ set_dr_target_alignment (dr_vec_info *dr_info, 
> poly_uint64 val)
>  }
>  #define SET_DR_TARGET_ALIGNMENT(DR, VAL) set_dr_target_alignment (DR, VAL)
>
> -/* Return true if data access DR_INFO is aligned to its target alignment
> -   (which may be less than a full vector).  */
> +/* Return true if data access DR_INFO is aligned to the targets
> +   preferred alignment for VECTYPE (which may be less than a full vector).  
> */
>
>  static inline bool
> -aligned_access_p (dr_vec_info *dr_info)
> +aligned_access_p (dr_vec_info *dr_info, tree vectype)
>  {
> -  return (DR_MISALIGNMENT (dr_info) == 0);
> +  return (dr_misalignment (dr_info, vectype) == 0);
>  }
>
> -/* Return TRUE if the alignment of the data access is known, and FALSE
> +/* Return TRUE if the (mis-)alignment of the data access is known with
> +   respect to the targets preferred alignment for VECTYPE, and FALSE
>     otherwise.  */
>
>  static inline bool
> -known_alignment_for_access_p (dr_vec_info *dr_info)
> +known_alignment_for_access_p (dr_vec_info *dr_info, tree vectype)
>  {
> -  return (DR_MISALIGNMENT (dr_info) != DR_MISALIGNMENT_UNKNOWN);
> +  return (dr_misalignment (dr_info, vectype) != DR_MISALIGNMENT_UNKNOWN);
>  }
>
>  /* Return the minimum alignment in bytes that the vectorized version
>     of DR_INFO is guaranteed to have.  */
>
>  static inline unsigned int
> -vect_known_alignment_in_bytes (dr_vec_info *dr_info)
> +vect_known_alignment_in_bytes (dr_vec_info *dr_info, tree vectype)
>  {
> -  if (DR_MISALIGNMENT (dr_info) == DR_MISALIGNMENT_UNKNOWN)
> +  int misalignment = dr_misalignment (dr_info, vectype);
> +  if (misalignment == DR_MISALIGNMENT_UNKNOWN)
>      return TYPE_ALIGN_UNIT (TREE_TYPE (DR_REF (dr_info->dr)));
> -  if (DR_MISALIGNMENT (dr_info) == 0)
> +  else if (misalignment == 0)
>      return known_alignment (DR_TARGET_ALIGNMENT (dr_info));
> -  return DR_MISALIGNMENT (dr_info) & -DR_MISALIGNMENT (dr_info);
> +  return misalignment & -misalignment;
>  }
>
>  /* Return the behavior of DR_INFO with respect to the vectorization context
> @@ -1971,7 +1970,7 @@ extern opt_tree vect_get_mask_type_for_stmt 
> (stmt_vec_info, unsigned int = 0);
>  /* In tree-vect-data-refs.c.  */
>  extern bool vect_can_force_dr_alignment_p (const_tree, poly_uint64);
>  extern enum dr_alignment_support vect_supportable_dr_alignment
> -                                           (vec_info *, dr_vec_info *, bool);
> +                                  (vec_info *, dr_vec_info *, tree, bool);
>  extern tree vect_get_smallest_scalar_type (stmt_vec_info, tree);
>  extern opt_result vect_analyze_data_ref_dependences (loop_vec_info, unsigned 
> int *);
>  extern bool vect_slp_analyze_instance_dependence (vec_info *, slp_instance);
> @@ -2110,7 +2109,6 @@ extern bool can_duplicate_and_interleave_p (vec_info *, 
> unsigned int, tree,
>  extern void duplicate_and_interleave (vec_info *, gimple_seq *, tree,
>                                       const vec<tree> &, unsigned int, 
> vec<tree> &);
>  extern int vect_get_place_in_interleaving_chain (stmt_vec_info, 
> stmt_vec_info);
> -extern bool vect_update_shared_vectype (stmt_vec_info, tree);
>  extern slp_tree vect_create_new_slp_node (unsigned, tree_code);
>  extern void vect_free_slp_tree (slp_tree);
>
> --
> 2.31.1

Reply via email to