On Wed, 26 Nov 2014, Jakub Jelinek wrote:

> Hi!
> 
> As discussed in the PR and on IRC, the problem here is that peeling
> for alignment can for some linear argument that during vect analysis
> passed simple_iv no longer pass it during vect transform phase.
> 
> So, to fix this, this patch remembers the base and step values from
> simple_iv during vect analysis and uses them during transform phase
> (biased by what the peeling for alignment advanced of course).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2014-11-26  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/64024
>       * tree-vectorizer.h (struct _stmt_vec_info): Remove simd_clone_fndecl
>       field.  Add simd_clone_info field.
>       (STMT_VINFO_SIMD_CLONE_FNDECL): Remove.
>       (STMT_VINFO_SIMD_CLONE_INFO): Define.
>       * tree-vect-stmts.c (vectorizable_simd_clone_call): Adjust for
>       STMT_VINFO_SIMD_CLONE_FNDECL becoming first element of
>       STMT_VINFO_SIMD_CLONE_INFO vector.  For linear arguments, remember
>       base and linear_step from analysis phase and use it during transform
>       phase, biased by the difference between LOOP_VINFO_NITERS{_UNCHANGED,}
>       multiplied by linear_step.
>       (free_stmt_vec_info): Release STMT_VINFO_SIMD_CLONE_INFO.
> 
>       * gcc.dg/vect/vect-simd-clone-13.c: New test.
>       * gcc.dg/vect/vect-simd-clone-14.c: New test.
> 
> --- gcc/tree-vectorizer.h.jj  2014-11-19 18:48:07.000000000 +0100
> +++ gcc/tree-vectorizer.h     2014-11-26 12:56:00.899824766 +0100
> @@ -602,8 +602,10 @@ typedef struct _stmt_vec_info {
>       of this stmt.  */
>    vec<dr_p> same_align_refs;
>  
> -  /* Selected SIMD clone's function decl.  */
> -  tree simd_clone_fndecl;
> +  /* Selected SIMD clone's function info.  First vector element
> +     is SIMD clone's function decl, followed by a pair of trees (base + step)
> +     for linear arguments (pair of NULLs for other arguments).  */
> +  vec<tree> simd_clone_info;
>  
>    /* Classify the def of this stmt.  */
>    enum vect_def_type def_type;
> @@ -677,7 +679,7 @@ typedef struct _stmt_vec_info {
>  #define STMT_VINFO_RELATED_STMT(S)         (S)->related_stmt
>  #define STMT_VINFO_PATTERN_DEF_SEQ(S)      (S)->pattern_def_seq
>  #define STMT_VINFO_SAME_ALIGN_REFS(S)      (S)->same_align_refs
> -#define STMT_VINFO_SIMD_CLONE_FNDECL(S)         (S)->simd_clone_fndecl
> +#define STMT_VINFO_SIMD_CLONE_INFO(S)           (S)->simd_clone_info
>  #define STMT_VINFO_DEF_TYPE(S)             (S)->def_type
>  #define STMT_VINFO_GROUP_FIRST_ELEMENT(S)  (S)->first_element
>  #define STMT_VINFO_GROUP_NEXT_ELEMENT(S)   (S)->next_element
> --- gcc/tree-vect-stmts.c.jj  2014-11-19 18:47:59.000000000 +0100
> +++ gcc/tree-vect-stmts.c     2014-11-26 15:38:59.883409014 +0100
> @@ -2715,12 +2715,40 @@ vectorizable_simd_clone_call (gimple stm
>        else
>       gcc_assert (thisarginfo.vectype != NULL_TREE);
>  
> -      if (thisarginfo.dt != vect_constant_def
> -       && thisarginfo.dt != vect_external_def
> -       && loop_vinfo
> -       && TREE_CODE (op) == SSA_NAME
> -       && simple_iv (loop, loop_containing_stmt (stmt), op, &iv, false)
> -       && tree_fits_shwi_p (iv.step))
> +      /* For linear arguments, the analyze phase should have saved
> +      the base and step in STMT_VINFO_SIMD_CLONE_INFO.  */
> +      if (i * 2 + 3 <= STMT_VINFO_SIMD_CLONE_INFO (stmt_info).length ()
> +       && STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[i * 2 + 2])
> +     {
> +       gcc_assert (vec_stmt);
> +       thisarginfo.linear_step
> +         = tree_to_shwi (STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[i * 2 + 2]);
> +       thisarginfo.op
> +         = STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[i * 2 + 1];
> +       /* If loop has been peeled for alignment, we need to adjust it.  */
> +       tree n1 = LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo);
> +       tree n2 = LOOP_VINFO_NITERS (loop_vinfo);
> +       if (n1 != n2)
> +         {
> +           tree bias = fold_build2 (MINUS_EXPR, TREE_TYPE (n1), n1, n2);
> +           tree step = STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[i * 2 + 2];
> +           tree opt = TREE_TYPE (thisarginfo.op);
> +           bias = fold_convert (TREE_TYPE (step), bias);
> +           bias = fold_build2 (MULT_EXPR, TREE_TYPE (step), bias, step);
> +           thisarginfo.op
> +             = fold_build2 (POINTER_TYPE_P (opt)
> +                            ? POINTER_PLUS_EXPR : PLUS_EXPR, opt,
> +                            thisarginfo.op, bias);
> +         }
> +     }
> +      else if (!vec_stmt
> +            && thisarginfo.dt != vect_constant_def
> +            && thisarginfo.dt != vect_external_def
> +            && loop_vinfo
> +            && TREE_CODE (op) == SSA_NAME
> +            && simple_iv (loop, loop_containing_stmt (stmt), op,
> +                          &iv, false)
> +            && tree_fits_shwi_p (iv.step))
>       {
>         thisarginfo.linear_step = tree_to_shwi (iv.step);
>         thisarginfo.op = iv.base;
> @@ -2735,8 +2763,8 @@ vectorizable_simd_clone_call (gimple stm
>  
>    unsigned int badness = 0;
>    struct cgraph_node *bestn = NULL;
> -  if (STMT_VINFO_SIMD_CLONE_FNDECL (stmt_info))
> -    bestn = cgraph_node::get (STMT_VINFO_SIMD_CLONE_FNDECL (stmt_info));
> +  if (STMT_VINFO_SIMD_CLONE_INFO (stmt_info).exists ())
> +    bestn = cgraph_node::get (STMT_VINFO_SIMD_CLONE_INFO (stmt_info)[0]);
>    else
>      for (struct cgraph_node *n = node->simd_clones; n != NULL;
>        n = n->simdclone->next_clone)
> @@ -2855,7 +2883,19 @@ vectorizable_simd_clone_call (gimple stm
>  
>    if (!vec_stmt) /* transformation not required.  */
>      {
> -      STMT_VINFO_SIMD_CLONE_FNDECL (stmt_info) = bestn->decl;
> +      STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (bestn->decl);
> +      for (i = 0; i < nargs; i++)
> +     if (bestn->simdclone->args[i].arg_type
> +         == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
> +       {
> +         STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_grow_cleared (i * 2
> +                                                                     + 1);
> +         STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (arginfo[i].op);
> +         tree lst = POINTER_TYPE_P (TREE_TYPE (arginfo[i].op))
> +                    ? size_type_node : TREE_TYPE (arginfo[i].op);
> +         tree ls = build_int_cst (lst, arginfo[i].linear_step);
> +         STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (ls);
> +       }
>        STMT_VINFO_TYPE (stmt_info) = call_simd_clone_vec_info_type;
>        if (dump_enabled_p ())
>       dump_printf_loc (MSG_NOTE, vect_location,
> @@ -7479,6 +7519,7 @@ free_stmt_vec_info (gimple stmt)
>      }
>  
>    STMT_VINFO_SAME_ALIGN_REFS (stmt_info).release ();
> +  STMT_VINFO_SIMD_CLONE_INFO (stmt_info).release ();
>    set_vinfo_for_stmt (stmt, NULL);
>    free (stmt_info);
>  }
> --- gcc/testsuite/gcc.dg/vect/vect-simd-clone-13.c.jj 2014-11-26 
> 15:42:26.162690785 +0100
> +++ gcc/testsuite/gcc.dg/vect/vect-simd-clone-13.c    2014-11-26 
> 15:42:49.252278876 +0100
> @@ -0,0 +1,7 @@
> +/* { dg-require-effective-target vect_simd_clones } */
> +/* { dg-additional-options "-fopenmp-simd -fcommon" } */
> +/* { dg-additional-options "-mavx" { target avx_runtime } } */
> +
> +#include "vect-simd-clone-6.c"
> +
> +/* { dg-final { cleanup-tree-dump "vect" } } */
> --- gcc/testsuite/gcc.dg/vect/vect-simd-clone-14.c.jj 2014-11-26 
> 15:43:09.522919202 +0100
> +++ gcc/testsuite/gcc.dg/vect/vect-simd-clone-14.c    2014-11-26 
> 15:43:24.566652273 +0100
> @@ -0,0 +1,7 @@
> +/* { dg-require-effective-target vect_simd_clones } */
> +/* { dg-additional-options "-fopenmp-simd -fcommon" } */
> +/* { dg-additional-options "-mavx" { target avx_runtime } } */
> +
> +#include "vect-simd-clone-11.c"
> +
> +/* { dg-final { cleanup-tree-dump "vect" } } */
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendoerffer, HRB 21284
(AG Nuernberg)
Maxfeldstrasse 5, 90409 Nuernberg, Germany

Reply via email to