Re: [mask conversion, patch 1/2] Add pattern for mask conversions

2015-10-27 Thread Richard Biener
On Mon, Oct 19, 2015 at 2:22 PM, Ilya Enkovich  wrote:
> Hi,
>
> This patch adds a vectorization pattern which detects cases where mask 
> conversion is needed and adds it.  It is done for all statements which may 
> consume mask.  Some additional changes were made to support MASK_LOAD with 
> pattern and allow scalar mode for vectype of pattern stmt.  It is applied on 
> top of all other boolean vector series.  Does it look OK?

Ick - more patterns.  I was really hoping we could get away without
patterns for bools :/

Ok.

Thanks,
Richard.

> Thanks,
> Ilya
> --
> gcc/
>
> 2015-10-19  Ilya Enkovich  
>
> * optabs.c (expand_binop_directly): Allow scalar mode for
> vec_pack_trunc_optab.
> * tree-vect-loop.c (vect_determine_vectorization_factor): Skip
> boolean vector producers from pattern sequence when computing VF.
> * tree-vect-patterns.c (vect_vect_recog_func_ptrs) Add
> vect_recog_mask_conversion_pattern.
> (search_type_for_mask): Choose the smallest
> type if different size types are mixed.
> (build_mask_conversion): New.
> (vect_recog_mask_conversion_pattern): New.
> (vect_pattern_recog_1): Allow scalar mode for boolean vectype.
> * tree-vect-stmts.c (vectorizable_mask_load_store): Support masked
> load with pattern.
> (vectorizable_conversion): Support boolean vectors.
> (free_stmt_vec_info): Allow patterns for statements with no lhs.
> * tree-vectorizer.h (NUM_PATTERNS): Increase to 14.
>
>
> diff --git a/gcc/optabs.c b/gcc/optabs.c
> index 83f4be3..8d61d33 100644
> --- a/gcc/optabs.c
> +++ b/gcc/optabs.c
> @@ -1055,7 +1055,8 @@ expand_binop_directly (machine_mode mode, optab 
> binoptab,
>/* The mode of the result is different then the mode of the
>  arguments.  */
>tmp_mode = insn_data[(int) icode].operand[0].mode;
> -  if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
> +  if (VECTOR_MODE_P (mode)
> + && GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
> {
>   delete_insns_since (last);
>   return NULL_RTX;
> diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
> index 14804b3..e388533 100644
> --- a/gcc/tree-vect-loop.c
> +++ b/gcc/tree-vect-loop.c
> @@ -497,6 +497,17 @@ vect_determine_vectorization_factor (loop_vec_info 
> loop_vinfo)
> }
>  }
>
> + /* Boolean vectors don't affect VF.  */
> + if (VECTOR_BOOLEAN_TYPE_P (vectype))
> +   {
> + if (!analyze_pattern_stmt && gsi_end_p (pattern_def_si))
> +   {
> + pattern_def_seq = NULL;
> + gsi_next ();
> +   }
> + continue;
> +   }
> +
>   /* The vectorization factor is according to the smallest
>  scalar type (or the largest vector size, but we only
>  support one vector size per loop).  */
> diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
> index a737129..34b1ea6 100644
> --- a/gcc/tree-vect-patterns.c
> +++ b/gcc/tree-vect-patterns.c
> @@ -76,6 +76,7 @@ static gimple *vect_recog_mult_pattern (vec *,
>  static gimple *vect_recog_mixed_size_cond_pattern (vec *,
>   tree *, tree *);
>  static gimple *vect_recog_bool_pattern (vec *, tree *, tree *);
> +static gimple *vect_recog_mask_conversion_pattern (vec *, tree *, 
> tree *);
>  static vect_recog_func_ptr vect_vect_recog_func_ptrs[NUM_PATTERNS] = {
> vect_recog_widen_mult_pattern,
> vect_recog_widen_sum_pattern,
> @@ -89,7 +90,8 @@ static vect_recog_func_ptr 
> vect_vect_recog_func_ptrs[NUM_PATTERNS] = {
> vect_recog_divmod_pattern,
> vect_recog_mult_pattern,
> vect_recog_mixed_size_cond_pattern,
> -   vect_recog_bool_pattern};
> +   vect_recog_bool_pattern,
> +   vect_recog_mask_conversion_pattern};
>
>  static inline void
>  append_pattern_def_seq (stmt_vec_info stmt_info, gimple *stmt)
> @@ -3180,7 +3182,7 @@ search_type_for_mask (tree var, vec_info *vinfo)
>enum vect_def_type dt;
>tree rhs1;
>enum tree_code rhs_code;
> -  tree res = NULL;
> +  tree res = NULL, res2;
>
>if (TREE_CODE (var) != SSA_NAME)
>  return NULL;
> @@ -3213,13 +3215,26 @@ search_type_for_mask (tree var, vec_info *vinfo)
>  case BIT_AND_EXPR:
>  case BIT_IOR_EXPR:
>  case BIT_XOR_EXPR:
> -  if (!(res = search_type_for_mask (rhs1, vinfo)))
> -   res = search_type_for_mask (gimple_assign_rhs2 (def_stmt), vinfo);
> +  res = search_type_for_mask (rhs1, vinfo);
> +  res2 = search_type_for_mask (gimple_assign_rhs2 (def_stmt), vinfo);
> +  if (!res || (res2 && TYPE_PRECISION (res) > TYPE_PRECISION (res2)))
> +   res = res2;
>break;
>
>  default:
>if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
> {
> 

[mask conversion, patch 1/2] Add pattern for mask conversions

2015-10-19 Thread Ilya Enkovich
Hi,

This patch adds a vectorization pattern which detects cases where mask 
conversion is needed and adds it.  It is done for all statements which may 
consume mask.  Some additional changes were made to support MASK_LOAD with 
pattern and allow scalar mode for vectype of pattern stmt.  It is applied on 
top of all other boolean vector series.  Does it look OK?

Thanks,
Ilya
--
gcc/

2015-10-19  Ilya Enkovich  

* optabs.c (expand_binop_directly): Allow scalar mode for
vec_pack_trunc_optab.
* tree-vect-loop.c (vect_determine_vectorization_factor): Skip
boolean vector producers from pattern sequence when computing VF.
* tree-vect-patterns.c (vect_vect_recog_func_ptrs) Add
vect_recog_mask_conversion_pattern.
(search_type_for_mask): Choose the smallest
type if different size types are mixed.
(build_mask_conversion): New.
(vect_recog_mask_conversion_pattern): New.
(vect_pattern_recog_1): Allow scalar mode for boolean vectype.
* tree-vect-stmts.c (vectorizable_mask_load_store): Support masked
load with pattern.
(vectorizable_conversion): Support boolean vectors.
(free_stmt_vec_info): Allow patterns for statements with no lhs.
* tree-vectorizer.h (NUM_PATTERNS): Increase to 14.


diff --git a/gcc/optabs.c b/gcc/optabs.c
index 83f4be3..8d61d33 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -1055,7 +1055,8 @@ expand_binop_directly (machine_mode mode, optab binoptab,
   /* The mode of the result is different then the mode of the
 arguments.  */
   tmp_mode = insn_data[(int) icode].operand[0].mode;
-  if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
+  if (VECTOR_MODE_P (mode)
+ && GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
{
  delete_insns_since (last);
  return NULL_RTX;
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 14804b3..e388533 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -497,6 +497,17 @@ vect_determine_vectorization_factor (loop_vec_info 
loop_vinfo)
}
 }
 
+ /* Boolean vectors don't affect VF.  */
+ if (VECTOR_BOOLEAN_TYPE_P (vectype))
+   {
+ if (!analyze_pattern_stmt && gsi_end_p (pattern_def_si))
+   {
+ pattern_def_seq = NULL;
+ gsi_next ();
+   }
+ continue;
+   }
+
  /* The vectorization factor is according to the smallest
 scalar type (or the largest vector size, but we only
 support one vector size per loop).  */
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index a737129..34b1ea6 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -76,6 +76,7 @@ static gimple *vect_recog_mult_pattern (vec *,
 static gimple *vect_recog_mixed_size_cond_pattern (vec *,
  tree *, tree *);
 static gimple *vect_recog_bool_pattern (vec *, tree *, tree *);
+static gimple *vect_recog_mask_conversion_pattern (vec *, tree *, 
tree *);
 static vect_recog_func_ptr vect_vect_recog_func_ptrs[NUM_PATTERNS] = {
vect_recog_widen_mult_pattern,
vect_recog_widen_sum_pattern,
@@ -89,7 +90,8 @@ static vect_recog_func_ptr 
vect_vect_recog_func_ptrs[NUM_PATTERNS] = {
vect_recog_divmod_pattern,
vect_recog_mult_pattern,
vect_recog_mixed_size_cond_pattern,
-   vect_recog_bool_pattern};
+   vect_recog_bool_pattern,
+   vect_recog_mask_conversion_pattern};
 
 static inline void
 append_pattern_def_seq (stmt_vec_info stmt_info, gimple *stmt)
@@ -3180,7 +3182,7 @@ search_type_for_mask (tree var, vec_info *vinfo)
   enum vect_def_type dt;
   tree rhs1;
   enum tree_code rhs_code;
-  tree res = NULL;
+  tree res = NULL, res2;
 
   if (TREE_CODE (var) != SSA_NAME)
 return NULL;
@@ -3213,13 +3215,26 @@ search_type_for_mask (tree var, vec_info *vinfo)
 case BIT_AND_EXPR:
 case BIT_IOR_EXPR:
 case BIT_XOR_EXPR:
-  if (!(res = search_type_for_mask (rhs1, vinfo)))
-   res = search_type_for_mask (gimple_assign_rhs2 (def_stmt), vinfo);
+  res = search_type_for_mask (rhs1, vinfo);
+  res2 = search_type_for_mask (gimple_assign_rhs2 (def_stmt), vinfo);
+  if (!res || (res2 && TYPE_PRECISION (res) > TYPE_PRECISION (res2)))
+   res = res2;
   break;
 
 default:
   if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
{
+ tree comp_vectype, mask_type;
+
+ comp_vectype = get_vectype_for_scalar_type (TREE_TYPE (rhs1));
+ if (comp_vectype == NULL_TREE)
+   return NULL;
+
+ mask_type = get_mask_type_for_scalar_type (TREE_TYPE (rhs1));
+ if (!mask_type
+ || !expand_vec_cmp_expr_p (comp_vectype, mask_type))
+   return NULL;
+
  if (TREE_CODE (TREE_TYPE (rhs1)) !=