This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [vec-cmp, patch 4/6] Support vector mask invariants
- From: Ilya Enkovich <enkovich dot gnu at gmail dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 9 Nov 2015 15:11:18 +0300
- Subject: Re: [vec-cmp, patch 4/6] Support vector mask invariants
- Authentication-results: sourceware.org; auth=none
- References: <20151008151140 dot GE63757 at msticlxl57 dot ims dot intel dot com> <CAFiYyc177iQ+6cQB5WGYiGw5PF0rUbNXThS4vHjMkj7hav=U6A at mail dot gmail dot com> <CAMbmDYYp9bh7MmMAW15PtXmQhRSGNhr3yT9BxEzgZAq7RagitA at mail dot gmail dot com> <CAFiYyc27DhP1tKTD8=oqgzruKK82VBu7Y6W2xTsEA5e9NFBTkQ at mail dot gmail dot com> <CAMbmDYYi_AzriR351U_nCQJpduV356-Ra4Ge=hVm5EanR1B-HA at mail dot gmail dot com> <20151014161352 dot GO63757 at msticlxl57 dot ims dot intel dot com> <CAFiYyc1A1YGE=Ux5syB-Yup5Swm0x0XFTP80DbPsDATW6rQjKA at mail dot gmail dot com>
On 26 Oct 16:21, Richard Biener wrote:
> On Wed, Oct 14, 2015 at 6:13 PM, Ilya Enkovich <enkovich.gnu@gmail.com> 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, >emp, &def, &dts[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, >emp, &def, &dts[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 <enkovich.gnu@gmail.com>
* 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)
STMT_VINFO_VEC_STMT of the defining stmt holds the relevant def.
In case OP is an invariant or constant, a new stmt that creates a vector def
- needs to be introduced. */
+ needs to be introduced. VECTYPE may be used to specify a required type for
+ vector invariant. */
tree
-vect_get_vec_def_for_operand (tree op, gimple *stmt)
+vect_get_vec_def_for_operand (tree op, gimple *stmt, tree vectype)
{
tree vec_oprnd;
gimple *vec_stmt;
gimple *def_stmt;
stmt_vec_info def_stmt_info = NULL;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+ tree stmt_vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
enum vect_def_type dt;
bool is_simple_use;
@@ -1372,7 +1374,14 @@ vect_get_vec_def_for_operand (tree op, gimple *stmt)
case vect_constant_def:
case vect_external_def:
{
- vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
+ if (vectype)
+ vector_type = vectype;
+ else if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE
+ && VECTOR_BOOLEAN_TYPE_P (stmt_vectype))
+ vector_type = build_same_sized_truth_vector_type (stmt_vectype);
+ else
+ vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
+
gcc_assert (vector_type);
return vect_init_vector (stmt, op, vector_type, NULL);
}
@@ -7329,13 +7338,14 @@ 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);
+ vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
+ stmt, comp_vectype);
vect_is_simple_use (TREE_OPERAND (cond_expr, 0),
loop_vinfo, >emp, &dts[0]);
vec_cond_rhs =
vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
- stmt);
+ stmt, comp_vectype);
vect_is_simple_use (TREE_OPERAND (cond_expr, 1),
loop_vinfo, >emp, &dts[1]);
if (reduc_index == 1)
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 58d5f0b..d38d767 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -978,7 +978,7 @@ extern unsigned record_stmt_cost (stmt_vector_for_cost *, int,
extern void vect_finish_stmt_generation (gimple *, gimple *,
gimple_stmt_iterator *);
extern bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
-extern tree vect_get_vec_def_for_operand (tree, gimple *);
+extern tree vect_get_vec_def_for_operand (tree, gimple *, tree = NULL);
extern tree vect_init_vector (gimple *, tree, tree,
gimple_stmt_iterator *);
extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);