Re: [vec-cmp, patch 4/6] Support vector mask invariants

2015-11-09 Thread Richard Biener
On Mon, Nov 9, 2015 at 1:11 PM, Ilya Enkovich  wrote:
> On 26 Oct 16:21, Richard Biener wrote:
>> On Wed, Oct 14, 2015 at 6:13 PM, Ilya Enkovich  
>> wrote:
>> > -   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
>> > +   {
>> > + /* Can't use VIEW_CONVERT_EXPR for booleans because
>> > +of possibly different sizes of scalar value and
>> > +vector element.  */
>> > + if (VECTOR_BOOLEAN_TYPE_P (type))
>> > +   {
>> > + if (integer_zerop (val))
>> > +   val = build_int_cst (TREE_TYPE (type), 0);
>> > + else if (integer_onep (val))
>> > +   val = build_int_cst (TREE_TYPE (type), 1);
>> > + else
>> > +   gcc_unreachable ();
>> > +   }
>> > + else
>> > +   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), 
>> > val);
>>
>> I think the existing code is fine with using fold_convert () here
>> which should also work
>> for the boolean types.  So does just
>>
>>   val = fold_convert (TREE_TYPE (type), val);
>>
>> work?
>
> It seems to work OK.
>
>>
>> > @@ -7428,13 +7459,13 @@ vectorizable_condition (gimple *stmt, 
>> > gimple_stmt_iterator *gsi,
>> >   gimple *gtemp;
>> >   vec_cond_lhs =
>> >   vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
>> > -   stmt, NULL);
>> > +   stmt, NULL, comp_vectype);
>> >   vect_is_simple_use (TREE_OPERAND (cond_expr, 0), stmt,
>> >   loop_vinfo, , , [0]);
>> >
>> >   vec_cond_rhs =
>> > vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
>> > -   stmt, NULL);
>> > + stmt, NULL, comp_vectype);
>> >   vect_is_simple_use (TREE_OPERAND (cond_expr, 1), stmt,
>> >   loop_vinfo, , , [1]);
>>
>> I still don't like this very much but I guess without some major
>> refactoring of all
>> the functions there isn't a better way to do it for now.
>>
>> Thus, ok with trying the change suggested above.
>>
>> Thanks,
>> Richard.
>>
>
> Here is an updated version.

Ok.

Thanks,
Richard.

> Thanks,
> Ilya
> --
> gcc/
>
> 2015-11-09  Ilya Enkovich  
>
> * expr.c (const_vector_mask_from_tree): New.
> (const_vector_from_tree): Use const_vector_mask_from_tree
> for boolean vectors.
> * tree-vect-stmts.c (vect_init_vector): Support boolean vector
> invariants.
> (vect_get_vec_def_for_operand): Add VECTYPE arg.
> (vectorizable_condition): Directly provide vectype for invariants
> used in comparison.
> * tree-vectorizer.h (vect_get_vec_def_for_operand): Add VECTYPE
> arg.
>
>
> diff --git a/gcc/expr.c b/gcc/expr.c
> index 2b2174f..03936ee 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -11423,6 +11423,40 @@ try_tablejump (tree index_type, tree index_expr, 
> tree minval, tree range,
>return 1;
>  }
>
> +/* Return a CONST_VECTOR rtx representing vector mask for
> +   a VECTOR_CST of booleans.  */
> +static rtx
> +const_vector_mask_from_tree (tree exp)
> +{
> +  rtvec v;
> +  unsigned i;
> +  int units;
> +  tree elt;
> +  machine_mode inner, mode;
> +
> +  mode = TYPE_MODE (TREE_TYPE (exp));
> +  units = GET_MODE_NUNITS (mode);
> +  inner = GET_MODE_INNER (mode);
> +
> +  v = rtvec_alloc (units);
> +
> +  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
> +{
> +  elt = VECTOR_CST_ELT (exp, i);
> +
> +  gcc_assert (TREE_CODE (elt) == INTEGER_CST);
> +  if (integer_zerop (elt))
> +   RTVEC_ELT (v, i) = CONST0_RTX (inner);
> +  else if (integer_onep (elt)
> +  || integer_minus_onep (elt))
> +   RTVEC_ELT (v, i) = CONSTM1_RTX (inner);
> +  else
> +   gcc_unreachable ();
> +}
> +
> +  return gen_rtx_CONST_VECTOR (mode, v);
> +}
> +
>  /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
>  static rtx
>  const_vector_from_tree (tree exp)
> @@ -11438,6 +11472,9 @@ const_vector_from_tree (tree exp)
>if (initializer_zerop (exp))
>  return CONST0_RTX (mode);
>
> +  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
> +return const_vector_mask_from_tree (exp);
> +
>units = GET_MODE_NUNITS (mode);
>inner = GET_MODE_INNER (mode);
>
> diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
> index ee549f4..af203ab 100644
> --- a/gcc/tree-vect-stmts.c
> +++ b/gcc/tree-vect-stmts.c
> @@ -1300,7 +1300,7 @@ vect_init_vector (gimple *stmt, tree val, tree type, 
> gimple_stmt_iterator *gsi)
>if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
> {
>   if (CONSTANT_CLASS_P (val))
> -   val 

Re: [vec-cmp, patch 4/6] Support vector mask invariants

2015-11-09 Thread Ilya Enkovich
On 26 Oct 16:21, Richard Biener wrote:
> On Wed, Oct 14, 2015 at 6:13 PM, Ilya Enkovich  wrote:
> > -   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
> > +   {
> > + /* Can't use VIEW_CONVERT_EXPR for booleans because
> > +of possibly different sizes of scalar value and
> > +vector element.  */
> > + if (VECTOR_BOOLEAN_TYPE_P (type))
> > +   {
> > + if (integer_zerop (val))
> > +   val = build_int_cst (TREE_TYPE (type), 0);
> > + else if (integer_onep (val))
> > +   val = build_int_cst (TREE_TYPE (type), 1);
> > + else
> > +   gcc_unreachable ();
> > +   }
> > + else
> > +   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
> 
> I think the existing code is fine with using fold_convert () here
> which should also work
> for the boolean types.  So does just
> 
>   val = fold_convert (TREE_TYPE (type), val);
> 
> work?

It seems to work OK.

> 
> > @@ -7428,13 +7459,13 @@ vectorizable_condition (gimple *stmt, 
> > gimple_stmt_iterator *gsi,
> >   gimple *gtemp;
> >   vec_cond_lhs =
> >   vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
> > -   stmt, NULL);
> > +   stmt, NULL, comp_vectype);
> >   vect_is_simple_use (TREE_OPERAND (cond_expr, 0), stmt,
> >   loop_vinfo, , , [0]);
> >
> >   vec_cond_rhs =
> > vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
> > -   stmt, NULL);
> > + stmt, NULL, comp_vectype);
> >   vect_is_simple_use (TREE_OPERAND (cond_expr, 1), stmt,
> >   loop_vinfo, , , [1]);
> 
> I still don't like this very much but I guess without some major
> refactoring of all
> the functions there isn't a better way to do it for now.
> 
> Thus, ok with trying the change suggested above.
> 
> Thanks,
> Richard.
> 

Here is an updated version.

Thanks,
Ilya
--
gcc/

2015-11-09  Ilya Enkovich  

* expr.c (const_vector_mask_from_tree): New.
(const_vector_from_tree): Use const_vector_mask_from_tree
for boolean vectors.
* tree-vect-stmts.c (vect_init_vector): Support boolean vector
invariants.
(vect_get_vec_def_for_operand): Add VECTYPE arg.
(vectorizable_condition): Directly provide vectype for invariants
used in comparison.
* tree-vectorizer.h (vect_get_vec_def_for_operand): Add VECTYPE
arg.


diff --git a/gcc/expr.c b/gcc/expr.c
index 2b2174f..03936ee 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11423,6 +11423,40 @@ try_tablejump (tree index_type, tree index_expr, tree 
minval, tree range,
   return 1;
 }
 
+/* Return a CONST_VECTOR rtx representing vector mask for
+   a VECTOR_CST of booleans.  */
+static rtx
+const_vector_mask_from_tree (tree exp)
+{
+  rtvec v;
+  unsigned i;
+  int units;
+  tree elt;
+  machine_mode inner, mode;
+
+  mode = TYPE_MODE (TREE_TYPE (exp));
+  units = GET_MODE_NUNITS (mode);
+  inner = GET_MODE_INNER (mode);
+
+  v = rtvec_alloc (units);
+
+  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
+{
+  elt = VECTOR_CST_ELT (exp, i);
+
+  gcc_assert (TREE_CODE (elt) == INTEGER_CST);
+  if (integer_zerop (elt))
+   RTVEC_ELT (v, i) = CONST0_RTX (inner);
+  else if (integer_onep (elt)
+  || integer_minus_onep (elt))
+   RTVEC_ELT (v, i) = CONSTM1_RTX (inner);
+  else
+   gcc_unreachable ();
+}
+
+  return gen_rtx_CONST_VECTOR (mode, v);
+}
+
 /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
 static rtx
 const_vector_from_tree (tree exp)
@@ -11438,6 +11472,9 @@ const_vector_from_tree (tree exp)
   if (initializer_zerop (exp))
 return CONST0_RTX (mode);
 
+  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
+return const_vector_mask_from_tree (exp);
+
   units = GET_MODE_NUNITS (mode);
   inner = GET_MODE_INNER (mode);
 
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index ee549f4..af203ab 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1300,7 +1300,7 @@ vect_init_vector (gimple *stmt, tree val, tree type, 
gimple_stmt_iterator *gsi)
   if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
{
  if (CONSTANT_CLASS_P (val))
-   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
+   val = fold_convert (TREE_TYPE (type), val);
  else
{
  new_temp = make_ssa_name (TREE_TYPE (type));
@@ -1328,16 +1328,18 @@ vect_init_vector (gimple *stmt, tree val, tree type, 
gimple_stmt_iterator *gsi)

Re: [vec-cmp, patch 4/6] Support vector mask invariants

2015-10-26 Thread Richard Biener
On Wed, Oct 14, 2015 at 6:13 PM, Ilya Enkovich  wrote:
> On 14 Oct 13:50, Ilya Enkovich wrote:
>> 2015-10-14 11:49 GMT+03:00 Richard Biener :
>> > On Tue, Oct 13, 2015 at 4:52 PM, Ilya Enkovich  
>> > wrote:
>> >> I don't understand what you mean. vect_get_vec_def_for_operand has two
>> >> changes made.
>> >> 1. For boolean invariants use build_same_sized_truth_vector_type
>> >> instead of get_vectype_for_scalar_type in case statement produces a
>> >> boolean vector. This covers cases when we use invariants in
>> >> comparison, AND, IOR, XOR.
>> >
>> > Yes, I understand we need this special-casing to differentiate between
>> > the vector type
>> > used for boolean-typed loads/stores and the type for boolean typed 
>> > constants.
>> > What happens if we mix them btw, like with
>> >
>> >   _Bool b = bools[i];
>> >   _Bool c = b || d;
>> >   ...
>> >
>> > ?
>>
>> Here both statements should get vector of char as a vectype and we
>> never go VECTOR_BOOLEAN_TYPE_P way for them
>>
>> >
>> >> 2. COND_EXPR is an exception because it has built-in boolean vector
>> >> result not reflected in its vecinfo. Thus I added additional operand
>> >> for vect_get_vec_def_for_operand to directly specify vectype for
>> >> vector definition in case it is a loop invariant.
>> >> So what do you propose to do with these changes?
>> >
>> > This is the change I don't like and don't see why we need it.  It works 
>> > today
>> > and the comparison operands should be of appropriate type already?
>>
>> Today it works because we always create vector of integer constant.
>> With boolean vectors it may be either integer vector or boolean vector
>> depending on context. Consider:
>>
>> _Bool _1;
>> int _2;
>>
>> _2 = _1 != 0 ? 0 : 1
>>
>> We have two zero constants here requiring different vectypes.
>>
>> Ilya
>>
>> >
>> > Richard.
>> >
>> >> Thanks,
>> >> Ilya
>
> Here is an updated patch version.
>
> Thanks,
> Ilya
> --
> gcc/
>
> 2015-10-14  Ilya Enkovich  
>
> * expr.c (const_vector_mask_from_tree): New.
> (const_vector_from_tree): Use const_vector_mask_from_tree
> for boolean vectors.
> * tree-vect-stmts.c (vect_init_vector): Support boolean vector
> invariants.
> (vect_get_vec_def_for_operand): Add VECTYPE arg.
> (vectorizable_condition): Directly provide vectype for invariants
> used in comparison.
> * tree-vectorizer.h (vect_get_vec_def_for_operand): Add VECTYPE
> arg.
>
>
> diff --git a/gcc/expr.c b/gcc/expr.c
> index b5ff598..ab25d1a 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -11344,6 +11344,40 @@ try_tablejump (tree index_type, tree index_expr, 
> tree minval, tree range,
>return 1;
>  }
>
> +/* Return a CONST_VECTOR rtx representing vector mask for
> +   a VECTOR_CST of booleans.  */
> +static rtx
> +const_vector_mask_from_tree (tree exp)
> +{
> +  rtvec v;
> +  unsigned i;
> +  int units;
> +  tree elt;
> +  machine_mode inner, mode;
> +
> +  mode = TYPE_MODE (TREE_TYPE (exp));
> +  units = GET_MODE_NUNITS (mode);
> +  inner = GET_MODE_INNER (mode);
> +
> +  v = rtvec_alloc (units);
> +
> +  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
> +{
> +  elt = VECTOR_CST_ELT (exp, i);
> +
> +  gcc_assert (TREE_CODE (elt) == INTEGER_CST);
> +  if (integer_zerop (elt))
> +   RTVEC_ELT (v, i) = CONST0_RTX (inner);
> +  else if (integer_onep (elt)
> +  || integer_minus_onep (elt))
> +   RTVEC_ELT (v, i) = CONSTM1_RTX (inner);
> +  else
> +   gcc_unreachable ();
> +}
> +
> +  return gen_rtx_CONST_VECTOR (mode, v);
> +}
> +
>  /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
>  static rtx
>  const_vector_from_tree (tree exp)
> @@ -11359,6 +11393,9 @@ const_vector_from_tree (tree exp)
>if (initializer_zerop (exp))
>  return CONST0_RTX (mode);
>
> +  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
> +return const_vector_mask_from_tree (exp);
> +
>units = GET_MODE_NUNITS (mode);
>inner = GET_MODE_INNER (mode);
>
> diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
> index 6a52895..01168ae 100644
> --- a/gcc/tree-vect-stmts.c
> +++ b/gcc/tree-vect-stmts.c
> @@ -1308,7 +1308,22 @@ vect_init_vector (gimple *stmt, tree val, tree type, 
> gimple_stmt_iterator *gsi)
>if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
> {
>   if (CONSTANT_CLASS_P (val))
> -   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
> +   {
> + /* Can't use VIEW_CONVERT_EXPR for booleans because
> +of possibly different sizes of scalar value and
> +vector element.  */
> + if (VECTOR_BOOLEAN_TYPE_P (type))
> +   {
> + if (integer_zerop (val))
> +   val = build_int_cst (TREE_TYPE (type), 0);
> + else if (integer_onep (val))
> +  

Re: [vec-cmp, patch 4/6] Support vector mask invariants

2015-10-14 Thread Ilya Enkovich
On 14 Oct 13:50, Ilya Enkovich wrote:
> 2015-10-14 11:49 GMT+03:00 Richard Biener :
> > On Tue, Oct 13, 2015 at 4:52 PM, Ilya Enkovich  
> > wrote:
> >> I don't understand what you mean. vect_get_vec_def_for_operand has two
> >> changes made.
> >> 1. For boolean invariants use build_same_sized_truth_vector_type
> >> instead of get_vectype_for_scalar_type in case statement produces a
> >> boolean vector. This covers cases when we use invariants in
> >> comparison, AND, IOR, XOR.
> >
> > Yes, I understand we need this special-casing to differentiate between
> > the vector type
> > used for boolean-typed loads/stores and the type for boolean typed 
> > constants.
> > What happens if we mix them btw, like with
> >
> >   _Bool b = bools[i];
> >   _Bool c = b || d;
> >   ...
> >
> > ?
> 
> Here both statements should get vector of char as a vectype and we
> never go VECTOR_BOOLEAN_TYPE_P way for them
> 
> >
> >> 2. COND_EXPR is an exception because it has built-in boolean vector
> >> result not reflected in its vecinfo. Thus I added additional operand
> >> for vect_get_vec_def_for_operand to directly specify vectype for
> >> vector definition in case it is a loop invariant.
> >> So what do you propose to do with these changes?
> >
> > This is the change I don't like and don't see why we need it.  It works 
> > today
> > and the comparison operands should be of appropriate type already?
> 
> Today it works because we always create vector of integer constant.
> With boolean vectors it may be either integer vector or boolean vector
> depending on context. Consider:
> 
> _Bool _1;
> int _2;
> 
> _2 = _1 != 0 ? 0 : 1
> 
> We have two zero constants here requiring different vectypes.
> 
> Ilya
> 
> >
> > Richard.
> >
> >> Thanks,
> >> Ilya

Here is an updated patch version.

Thanks,
Ilya
--
gcc/

2015-10-14  Ilya Enkovich  

* expr.c (const_vector_mask_from_tree): New.
(const_vector_from_tree): Use const_vector_mask_from_tree
for boolean vectors.
* tree-vect-stmts.c (vect_init_vector): Support boolean vector
invariants.
(vect_get_vec_def_for_operand): Add VECTYPE arg.
(vectorizable_condition): Directly provide vectype for invariants
used in comparison.
* tree-vectorizer.h (vect_get_vec_def_for_operand): Add VECTYPE
arg.


diff --git a/gcc/expr.c b/gcc/expr.c
index b5ff598..ab25d1a 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11344,6 +11344,40 @@ try_tablejump (tree index_type, tree index_expr, tree 
minval, tree range,
   return 1;
 }
 
+/* Return a CONST_VECTOR rtx representing vector mask for
+   a VECTOR_CST of booleans.  */
+static rtx
+const_vector_mask_from_tree (tree exp)
+{
+  rtvec v;
+  unsigned i;
+  int units;
+  tree elt;
+  machine_mode inner, mode;
+
+  mode = TYPE_MODE (TREE_TYPE (exp));
+  units = GET_MODE_NUNITS (mode);
+  inner = GET_MODE_INNER (mode);
+
+  v = rtvec_alloc (units);
+
+  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
+{
+  elt = VECTOR_CST_ELT (exp, i);
+
+  gcc_assert (TREE_CODE (elt) == INTEGER_CST);
+  if (integer_zerop (elt))
+   RTVEC_ELT (v, i) = CONST0_RTX (inner);
+  else if (integer_onep (elt)
+  || integer_minus_onep (elt))
+   RTVEC_ELT (v, i) = CONSTM1_RTX (inner);
+  else
+   gcc_unreachable ();
+}
+
+  return gen_rtx_CONST_VECTOR (mode, v);
+}
+
 /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
 static rtx
 const_vector_from_tree (tree exp)
@@ -11359,6 +11393,9 @@ const_vector_from_tree (tree exp)
   if (initializer_zerop (exp))
 return CONST0_RTX (mode);
 
+  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
+return const_vector_mask_from_tree (exp);
+
   units = GET_MODE_NUNITS (mode);
   inner = GET_MODE_INNER (mode);
 
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 6a52895..01168ae 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1308,7 +1308,22 @@ vect_init_vector (gimple *stmt, tree val, tree type, 
gimple_stmt_iterator *gsi)
   if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
{
  if (CONSTANT_CLASS_P (val))
-   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
+   {
+ /* Can't use VIEW_CONVERT_EXPR for booleans because
+of possibly different sizes of scalar value and
+vector element.  */
+ if (VECTOR_BOOLEAN_TYPE_P (type))
+   {
+ if (integer_zerop (val))
+   val = build_int_cst (TREE_TYPE (type), 0);
+ else if (integer_onep (val))
+   val = build_int_cst (TREE_TYPE (type), 1);
+ else
+   gcc_unreachable ();
+   }
+ else
+   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
+   }
  else
{
  new_temp = 

Re: [vec-cmp, patch 4/6] Support vector mask invariants

2015-10-14 Thread Richard Biener
On Tue, Oct 13, 2015 at 4:52 PM, Ilya Enkovich  wrote:
> 2015-10-13 16:54 GMT+03:00 Richard Biener :
>> On Thu, Oct 8, 2015 at 5:11 PM, Ilya Enkovich  wrote:
>>> Hi,
>>>
>>> This patch adds a special handling of boolean vector invariants.  We need 
>>> additional code to determine type of generated invariant.  For 
>>> VEC_COND_EXPR case we even provide this type directly because statement 
>>> vectype doesn't allow us to compute it.  Separate code is used to generate 
>>> and expand such vectors.
>>>
>>> Thanks,
>>> Ilya
>>> --
>>> gcc/
>>>
>>> 2015-10-08  Ilya Enkovich  
>>>
>>> * expr.c (const_vector_mask_from_tree): New.
>>> (const_vector_from_tree): Use const_vector_mask_from_tree
>>> for boolean vectors.
>>> * tree-vect-stmts.c (vect_init_vector): Support boolean vector
>>> invariants.
>>> (vect_get_vec_def_for_operand): Add VECTYPE arg.
>>> (vectorizable_condition): Directly provide vectype for invariants
>>> used in comparison.
>>> * tree-vectorizer.h (vect_get_vec_def_for_operand): Add VECTYPE
>>> arg.
>>>
>>>
>>> diff --git a/gcc/expr.c b/gcc/expr.c
>>> index 88da8cb..a624a34 100644
>>> --- a/gcc/expr.c
>>> +++ b/gcc/expr.c
>>> @@ -11320,6 +11320,40 @@ try_tablejump (tree index_type, tree index_expr, 
>>> tree minval, tree range,
>>>return 1;
>>>  }
>>>
>>> +/* Return a CONST_VECTOR rtx representing vector mask for
>>> +   a VECTOR_CST of booleans.  */
>>> +static rtx
>>> +const_vector_mask_from_tree (tree exp)
>>> +{
>>> +  rtvec v;
>>> +  unsigned i;
>>> +  int units;
>>> +  tree elt;
>>> +  machine_mode inner, mode;
>>> +
>>> +  mode = TYPE_MODE (TREE_TYPE (exp));
>>> +  units = GET_MODE_NUNITS (mode);
>>> +  inner = GET_MODE_INNER (mode);
>>> +
>>> +  v = rtvec_alloc (units);
>>> +
>>> +  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
>>> +{
>>> +  elt = VECTOR_CST_ELT (exp, i);
>>> +
>>> +  gcc_assert (TREE_CODE (elt) == INTEGER_CST);
>>> +  if (integer_zerop (elt))
>>> +   RTVEC_ELT (v, i) = CONST0_RTX (inner);
>>> +  else if (integer_onep (elt)
>>> +  || integer_minus_onep (elt))
>>> +   RTVEC_ELT (v, i) = CONSTM1_RTX (inner);
>>> +  else
>>> +   gcc_unreachable ();
>>> +}
>>> +
>>> +  return gen_rtx_CONST_VECTOR (mode, v);
>>> +}
>>> +
>>>  /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
>>>  static rtx
>>>  const_vector_from_tree (tree exp)
>>> @@ -11335,6 +11369,9 @@ const_vector_from_tree (tree exp)
>>>if (initializer_zerop (exp))
>>>  return CONST0_RTX (mode);
>>>
>>> +  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
>>> +  return const_vector_mask_from_tree (exp);
>>> +
>>>units = GET_MODE_NUNITS (mode);
>>>inner = GET_MODE_INNER (mode);
>>>
>>> diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
>>> index 6949c71..337ea7b 100644
>>> --- a/gcc/tree-vect-stmts.c
>>> +++ b/gcc/tree-vect-stmts.c
>>> @@ -1308,27 +1308,61 @@ vect_init_vector_1 (gimple *stmt, gimple *new_stmt, 
>>> gimple_stmt_iterator *gsi)
>>>  tree
>>>  vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator 
>>> *gsi)
>>>  {
>>> +  tree val_type = TREE_TYPE (val);
>>> +  machine_mode mode = TYPE_MODE (type);
>>> +  machine_mode val_mode = TYPE_MODE(val_type);
>>>tree new_var;
>>>gimple *init_stmt;
>>>tree vec_oprnd;
>>>tree new_temp;
>>>
>>>if (TREE_CODE (type) == VECTOR_TYPE
>>> -  && TREE_CODE (TREE_TYPE (val)) != VECTOR_TYPE)
>>> -{
>>> -  if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
>>> +  && TREE_CODE (val_type) != VECTOR_TYPE)
>>> +{
>>> +  /* Handle vector of bool represented as a vector of
>>> +integers here rather than on expand because it is
>>> +a default mask type for targets.  Vector mask is
>>> +built in a following way:
>>> +
>>> +tmp = (int)val
>>> +vec_tmp = {tmp, ..., tmp}
>>> +vec_cst = VIEW_CONVERT_EXPR(vec_tmp);  */
>>> +  if (TREE_CODE (val_type) == BOOLEAN_TYPE
>>> + && VECTOR_MODE_P (mode)
>>> + && SCALAR_INT_MODE_P (GET_MODE_INNER (mode))
>>> + && GET_MODE_INNER (mode) != val_mode)
>>> {
>>> - if (CONSTANT_CLASS_P (val))
>>> -   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
>>> - else
>>> + unsigned size = GET_MODE_BITSIZE (GET_MODE_INNER (mode));
>>> + tree stype = build_nonstandard_integer_type (size, 1);
>>> + tree vectype = get_vectype_for_scalar_type (stype);
>>> +
>>> + new_temp = make_ssa_name (stype);
>>> + init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val);
>>> + vect_init_vector_1 (stmt, init_stmt, gsi);
>>> +
>>> + val = make_ssa_name (vectype);
>>> + new_temp = build_vector_from_val (vectype, new_temp);
>>> + init_stmt = 

Re: [vec-cmp, patch 4/6] Support vector mask invariants

2015-10-14 Thread Ilya Enkovich
2015-10-14 11:49 GMT+03:00 Richard Biener :
> On Tue, Oct 13, 2015 at 4:52 PM, Ilya Enkovich  wrote:
>> I don't understand what you mean. vect_get_vec_def_for_operand has two
>> changes made.
>> 1. For boolean invariants use build_same_sized_truth_vector_type
>> instead of get_vectype_for_scalar_type in case statement produces a
>> boolean vector. This covers cases when we use invariants in
>> comparison, AND, IOR, XOR.
>
> Yes, I understand we need this special-casing to differentiate between
> the vector type
> used for boolean-typed loads/stores and the type for boolean typed constants.
> What happens if we mix them btw, like with
>
>   _Bool b = bools[i];
>   _Bool c = b || d;
>   ...
>
> ?

Here both statements should get vector of char as a vectype and we
never go VECTOR_BOOLEAN_TYPE_P way for them

>
>> 2. COND_EXPR is an exception because it has built-in boolean vector
>> result not reflected in its vecinfo. Thus I added additional operand
>> for vect_get_vec_def_for_operand to directly specify vectype for
>> vector definition in case it is a loop invariant.
>> So what do you propose to do with these changes?
>
> This is the change I don't like and don't see why we need it.  It works today
> and the comparison operands should be of appropriate type already?

Today it works because we always create vector of integer constant.
With boolean vectors it may be either integer vector or boolean vector
depending on context. Consider:

_Bool _1;
int _2;

_2 = _1 != 0 ? 0 : 1

We have two zero constants here requiring different vectypes.

Ilya

>
> Richard.
>
>> Thanks,
>> Ilya


Re: [vec-cmp, patch 4/6] Support vector mask invariants

2015-10-13 Thread Richard Biener
On Thu, Oct 8, 2015 at 5:11 PM, Ilya Enkovich  wrote:
> Hi,
>
> This patch adds a special handling of boolean vector invariants.  We need 
> additional code to determine type of generated invariant.  For VEC_COND_EXPR 
> case we even provide this type directly because statement vectype doesn't 
> allow us to compute it.  Separate code is used to generate and expand such 
> vectors.
>
> Thanks,
> Ilya
> --
> gcc/
>
> 2015-10-08  Ilya Enkovich  
>
> * expr.c (const_vector_mask_from_tree): New.
> (const_vector_from_tree): Use const_vector_mask_from_tree
> for boolean vectors.
> * tree-vect-stmts.c (vect_init_vector): Support boolean vector
> invariants.
> (vect_get_vec_def_for_operand): Add VECTYPE arg.
> (vectorizable_condition): Directly provide vectype for invariants
> used in comparison.
> * tree-vectorizer.h (vect_get_vec_def_for_operand): Add VECTYPE
> arg.
>
>
> diff --git a/gcc/expr.c b/gcc/expr.c
> index 88da8cb..a624a34 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -11320,6 +11320,40 @@ try_tablejump (tree index_type, tree index_expr, 
> tree minval, tree range,
>return 1;
>  }
>
> +/* Return a CONST_VECTOR rtx representing vector mask for
> +   a VECTOR_CST of booleans.  */
> +static rtx
> +const_vector_mask_from_tree (tree exp)
> +{
> +  rtvec v;
> +  unsigned i;
> +  int units;
> +  tree elt;
> +  machine_mode inner, mode;
> +
> +  mode = TYPE_MODE (TREE_TYPE (exp));
> +  units = GET_MODE_NUNITS (mode);
> +  inner = GET_MODE_INNER (mode);
> +
> +  v = rtvec_alloc (units);
> +
> +  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
> +{
> +  elt = VECTOR_CST_ELT (exp, i);
> +
> +  gcc_assert (TREE_CODE (elt) == INTEGER_CST);
> +  if (integer_zerop (elt))
> +   RTVEC_ELT (v, i) = CONST0_RTX (inner);
> +  else if (integer_onep (elt)
> +  || integer_minus_onep (elt))
> +   RTVEC_ELT (v, i) = CONSTM1_RTX (inner);
> +  else
> +   gcc_unreachable ();
> +}
> +
> +  return gen_rtx_CONST_VECTOR (mode, v);
> +}
> +
>  /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
>  static rtx
>  const_vector_from_tree (tree exp)
> @@ -11335,6 +11369,9 @@ const_vector_from_tree (tree exp)
>if (initializer_zerop (exp))
>  return CONST0_RTX (mode);
>
> +  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
> +  return const_vector_mask_from_tree (exp);
> +
>units = GET_MODE_NUNITS (mode);
>inner = GET_MODE_INNER (mode);
>
> diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
> index 6949c71..337ea7b 100644
> --- a/gcc/tree-vect-stmts.c
> +++ b/gcc/tree-vect-stmts.c
> @@ -1308,27 +1308,61 @@ vect_init_vector_1 (gimple *stmt, gimple *new_stmt, 
> gimple_stmt_iterator *gsi)
>  tree
>  vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator 
> *gsi)
>  {
> +  tree val_type = TREE_TYPE (val);
> +  machine_mode mode = TYPE_MODE (type);
> +  machine_mode val_mode = TYPE_MODE(val_type);
>tree new_var;
>gimple *init_stmt;
>tree vec_oprnd;
>tree new_temp;
>
>if (TREE_CODE (type) == VECTOR_TYPE
> -  && TREE_CODE (TREE_TYPE (val)) != VECTOR_TYPE)
> -{
> -  if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
> +  && TREE_CODE (val_type) != VECTOR_TYPE)
> +{
> +  /* Handle vector of bool represented as a vector of
> +integers here rather than on expand because it is
> +a default mask type for targets.  Vector mask is
> +built in a following way:
> +
> +tmp = (int)val
> +vec_tmp = {tmp, ..., tmp}
> +vec_cst = VIEW_CONVERT_EXPR(vec_tmp);  */
> +  if (TREE_CODE (val_type) == BOOLEAN_TYPE
> + && VECTOR_MODE_P (mode)
> + && SCALAR_INT_MODE_P (GET_MODE_INNER (mode))
> + && GET_MODE_INNER (mode) != val_mode)
> {
> - if (CONSTANT_CLASS_P (val))
> -   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
> - else
> + unsigned size = GET_MODE_BITSIZE (GET_MODE_INNER (mode));
> + tree stype = build_nonstandard_integer_type (size, 1);
> + tree vectype = get_vectype_for_scalar_type (stype);
> +
> + new_temp = make_ssa_name (stype);
> + init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val);
> + vect_init_vector_1 (stmt, init_stmt, gsi);
> +
> + val = make_ssa_name (vectype);
> + new_temp = build_vector_from_val (vectype, new_temp);
> + init_stmt = gimple_build_assign (val, new_temp);
> + vect_init_vector_1 (stmt, init_stmt, gsi);
> +
> + val = build1 (VIEW_CONVERT_EXPR, type, val);

So I don't quite understand - why don't we want to build

   tmp = (bool-element-type)val;
   vec_cst = {tmp, tmp, tmp ... };

?

> +   }
> +  else
> +   {
> + if (!types_compatible_p (TREE_TYPE (type), val_type))
> {
> - new_temp = 

Re: [vec-cmp, patch 4/6] Support vector mask invariants

2015-10-13 Thread Ilya Enkovich
2015-10-13 16:54 GMT+03:00 Richard Biener :
> On Thu, Oct 8, 2015 at 5:11 PM, Ilya Enkovich  wrote:
>> Hi,
>>
>> This patch adds a special handling of boolean vector invariants.  We need 
>> additional code to determine type of generated invariant.  For VEC_COND_EXPR 
>> case we even provide this type directly because statement vectype doesn't 
>> allow us to compute it.  Separate code is used to generate and expand such 
>> vectors.
>>
>> Thanks,
>> Ilya
>> --
>> gcc/
>>
>> 2015-10-08  Ilya Enkovich  
>>
>> * expr.c (const_vector_mask_from_tree): New.
>> (const_vector_from_tree): Use const_vector_mask_from_tree
>> for boolean vectors.
>> * tree-vect-stmts.c (vect_init_vector): Support boolean vector
>> invariants.
>> (vect_get_vec_def_for_operand): Add VECTYPE arg.
>> (vectorizable_condition): Directly provide vectype for invariants
>> used in comparison.
>> * tree-vectorizer.h (vect_get_vec_def_for_operand): Add VECTYPE
>> arg.
>>
>>
>> diff --git a/gcc/expr.c b/gcc/expr.c
>> index 88da8cb..a624a34 100644
>> --- a/gcc/expr.c
>> +++ b/gcc/expr.c
>> @@ -11320,6 +11320,40 @@ try_tablejump (tree index_type, tree index_expr, 
>> tree minval, tree range,
>>return 1;
>>  }
>>
>> +/* Return a CONST_VECTOR rtx representing vector mask for
>> +   a VECTOR_CST of booleans.  */
>> +static rtx
>> +const_vector_mask_from_tree (tree exp)
>> +{
>> +  rtvec v;
>> +  unsigned i;
>> +  int units;
>> +  tree elt;
>> +  machine_mode inner, mode;
>> +
>> +  mode = TYPE_MODE (TREE_TYPE (exp));
>> +  units = GET_MODE_NUNITS (mode);
>> +  inner = GET_MODE_INNER (mode);
>> +
>> +  v = rtvec_alloc (units);
>> +
>> +  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
>> +{
>> +  elt = VECTOR_CST_ELT (exp, i);
>> +
>> +  gcc_assert (TREE_CODE (elt) == INTEGER_CST);
>> +  if (integer_zerop (elt))
>> +   RTVEC_ELT (v, i) = CONST0_RTX (inner);
>> +  else if (integer_onep (elt)
>> +  || integer_minus_onep (elt))
>> +   RTVEC_ELT (v, i) = CONSTM1_RTX (inner);
>> +  else
>> +   gcc_unreachable ();
>> +}
>> +
>> +  return gen_rtx_CONST_VECTOR (mode, v);
>> +}
>> +
>>  /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
>>  static rtx
>>  const_vector_from_tree (tree exp)
>> @@ -11335,6 +11369,9 @@ const_vector_from_tree (tree exp)
>>if (initializer_zerop (exp))
>>  return CONST0_RTX (mode);
>>
>> +  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
>> +  return const_vector_mask_from_tree (exp);
>> +
>>units = GET_MODE_NUNITS (mode);
>>inner = GET_MODE_INNER (mode);
>>
>> diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
>> index 6949c71..337ea7b 100644
>> --- a/gcc/tree-vect-stmts.c
>> +++ b/gcc/tree-vect-stmts.c
>> @@ -1308,27 +1308,61 @@ vect_init_vector_1 (gimple *stmt, gimple *new_stmt, 
>> gimple_stmt_iterator *gsi)
>>  tree
>>  vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator 
>> *gsi)
>>  {
>> +  tree val_type = TREE_TYPE (val);
>> +  machine_mode mode = TYPE_MODE (type);
>> +  machine_mode val_mode = TYPE_MODE(val_type);
>>tree new_var;
>>gimple *init_stmt;
>>tree vec_oprnd;
>>tree new_temp;
>>
>>if (TREE_CODE (type) == VECTOR_TYPE
>> -  && TREE_CODE (TREE_TYPE (val)) != VECTOR_TYPE)
>> -{
>> -  if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
>> +  && TREE_CODE (val_type) != VECTOR_TYPE)
>> +{
>> +  /* Handle vector of bool represented as a vector of
>> +integers here rather than on expand because it is
>> +a default mask type for targets.  Vector mask is
>> +built in a following way:
>> +
>> +tmp = (int)val
>> +vec_tmp = {tmp, ..., tmp}
>> +vec_cst = VIEW_CONVERT_EXPR(vec_tmp);  */
>> +  if (TREE_CODE (val_type) == BOOLEAN_TYPE
>> + && VECTOR_MODE_P (mode)
>> + && SCALAR_INT_MODE_P (GET_MODE_INNER (mode))
>> + && GET_MODE_INNER (mode) != val_mode)
>> {
>> - if (CONSTANT_CLASS_P (val))
>> -   val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
>> - else
>> + unsigned size = GET_MODE_BITSIZE (GET_MODE_INNER (mode));
>> + tree stype = build_nonstandard_integer_type (size, 1);
>> + tree vectype = get_vectype_for_scalar_type (stype);
>> +
>> + new_temp = make_ssa_name (stype);
>> + init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val);
>> + vect_init_vector_1 (stmt, init_stmt, gsi);
>> +
>> + val = make_ssa_name (vectype);
>> + new_temp = build_vector_from_val (vectype, new_temp);
>> + init_stmt = gimple_build_assign (val, new_temp);
>> + vect_init_vector_1 (stmt, init_stmt, gsi);
>> +
>> + val = build1 (VIEW_CONVERT_EXPR, type, val);
>l
> So I don't quite understand - why don't we want to build
>
>