On 21 Oct 11:45, Jeff Law wrote:
> On 10/08/2015 09:15 AM, Ilya Enkovich wrote:
> >Hi,
> >
> >This patch disables transformation of boolean computations into integer ones 
> >in case target supports vector comparison.  Pattern still applies to 
> >transform resulting boolean value into integer or avoid COND_EXPR with 
> >SSA_NAME as condition.
> >
> >Thanks,
> >Ilya
> >--
> >2015-10-08  Ilya Enkovich  <enkovich....@gmail.com>
> >
> >     * tree-vect-patterns.c (check_bool_pattern): Check fails
> >     if we can vectorize comparison directly.
> >     (search_type_for_mask): New.
> >     (vect_recog_bool_pattern): Support cases when bool pattern
> >     check fails.
> >
> >
> >diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
> >index 830801a..e3be3d1 100644
> >--- a/gcc/tree-vect-patterns.c
> >+++ b/gcc/tree-vect-patterns.c
> >@@ -2962,6 +2962,11 @@ check_bool_pattern (tree var, loop_vec_info 
> >loop_vinfo, bb_vec_info bb_vinfo)
> >       if (comp_vectype == NULL_TREE)
> >         return false;
> >
> >+      mask_type = get_mask_type_for_scalar_type (TREE_TYPE (rhs1));
> >+      if (mask_type
> >+          && expand_vec_cmp_expr_p (comp_vectype, mask_type))
> >+        return false;
> >+
> >       if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE)
> >         {
> >           machine_mode mode = TYPE_MODE (TREE_TYPE (rhs1));
> So we're essentially saying here that we've got another preferred method for
> optimizing this case, right?
> 
> Can you update the function comment for check_bool_pattern?  In particular
> change the "if bool VAR can ..." to "can and should".
> 
> I think that more clearly states the updated purpose of that code.
> 
> 
> 
> 
> >@@ -3186,6 +3191,75 @@ adjust_bool_pattern (tree var, tree out_type, tree 
> >trueval,
> >  }
> >
> >
> >+/* Try to determine a proper type for converting bool VAR
> >+   into an integer value.  The type is chosen so that
> >+   conversion has the same number of elements as a mask
> >+   producer.  */
> >+
> >+static tree
> >+search_type_for_mask (tree var, loop_vec_info loop_vinfo, bb_vec_info 
> >bb_vinfo)
> What is the return value here?  Presumably the type or NULL.
> 
> So instead of "Try to determine a proper type" how about
> "Return the proper type or NULL_TREE if no such type exists ..."?
> 
> Please change the references to NULL to instead use NULL_TREE in that
> function as well.  They're functionally equivalent, but the latter is
> considered more correct these days.
> 
> 
> 
> >+    {
> >+      tree type = search_type_for_mask (var, loop_vinfo, bb_vinfo);
> >+      tree cst0, cst1, cmp, tmp;
> >+
> >+      if (!type)
> >+        return NULL;
> >+
> >+      /* We may directly use cond with narrowed type to avoid
> >+         multiple cond exprs with following result packing and
> >+         perform single cond with packed mask intead.  In case
> s/intead/instead/
> 
> With those changes above, this should be OK for the trunk.
> 
> jeff
> 

Thanks for review!  Here is an updated version with all mentioned issues fixed.

Thanks,
Ilya
--
2015-09-12  Ilya Enkovich  <enkovich....@gmail.com>

        * tree-vect-patterns.c (check_bool_pattern): Check fails
        if we can vectorize comparison directly.
        (search_type_for_mask): New.
        (vect_recog_bool_pattern): Support cases when bool pattern
        check fails.


diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 3fe094c..516034d 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -2879,7 +2879,9 @@ vect_recog_mixed_size_cond_pattern (vec<gimple *> *stmts, 
tree *type_in,
 
 
 /* Helper function of vect_recog_bool_pattern.  Called recursively, return
-   true if bool VAR can be optimized that way.  */
+   true if bool VAR can and should be optimized that way.  Assume it shouldn't
+   in case it's a result of a comparison which can be directly vectorized into
+   a vector comparison.  */
 
 static bool
 check_bool_pattern (tree var, vec_info *vinfo)
@@ -2928,7 +2930,7 @@ check_bool_pattern (tree var, vec_info *vinfo)
     default:
       if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
        {
-         tree vecitype, comp_vectype;
+         tree vecitype, comp_vectype, mask_type;
 
          /* If the comparison can throw, then is_gimple_condexpr will be
             false and we can't make a COND_EXPR/VEC_COND_EXPR out of it.  */
@@ -2939,6 +2941,11 @@ check_bool_pattern (tree var, vec_info *vinfo)
          if (comp_vectype == NULL_TREE)
            return false;
 
+         mask_type = get_mask_type_for_scalar_type (TREE_TYPE (rhs1));
+         if (mask_type
+             && expand_vec_cmp_expr_p (comp_vectype, mask_type))
+           return false;
+
          if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE)
            {
              machine_mode mode = TYPE_MODE (TREE_TYPE (rhs1));
@@ -3163,6 +3170,73 @@ adjust_bool_pattern (tree var, tree out_type, tree 
trueval,
 }
 
 
+/* Return the proper type for converting bool VAR into
+   an integer value or NULL_TREE if no such type exists.
+   The type is chosen so that converted value has the
+   same number of elements as VAR's vector type.  */
+
+static tree
+search_type_for_mask (tree var, vec_info *vinfo)
+{
+  gimple *def_stmt;
+  enum vect_def_type dt;
+  tree rhs1;
+  enum tree_code rhs_code;
+  tree res = NULL_TREE;
+
+  if (TREE_CODE (var) != SSA_NAME)
+    return NULL_TREE;
+
+  if ((TYPE_PRECISION (TREE_TYPE (var)) != 1
+       || !TYPE_UNSIGNED (TREE_TYPE (var)))
+      && TREE_CODE (TREE_TYPE (var)) != BOOLEAN_TYPE)
+    return NULL_TREE;
+
+  if (!vect_is_simple_use (var, vinfo, &def_stmt, &dt))
+    return NULL_TREE;
+
+  if (dt != vect_internal_def)
+    return NULL_TREE;
+
+  if (!is_gimple_assign (def_stmt))
+    return NULL_TREE;
+
+  rhs_code = gimple_assign_rhs_code (def_stmt);
+  rhs1 = gimple_assign_rhs1 (def_stmt);
+
+  switch (rhs_code)
+    {
+    case SSA_NAME:
+    case BIT_NOT_EXPR:
+    CASE_CONVERT:
+      res = search_type_for_mask (rhs1, vinfo);
+      break;
+
+    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);
+      break;
+
+    default:
+      if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
+       {
+         if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE
+             || !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
+           {
+             machine_mode mode = TYPE_MODE (TREE_TYPE (rhs1));
+             res = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), 1);
+           }
+         else
+           res = TREE_TYPE (rhs1);
+       }
+    }
+
+  return res;
+}
+
+
 /* Function vect_recog_bool_pattern
 
    Try to find pattern like following:
@@ -3220,6 +3294,7 @@ vect_recog_bool_pattern (vec<gimple *> *stmts, tree 
*type_in,
   enum tree_code rhs_code;
   tree var, lhs, rhs, vectype;
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
+  stmt_vec_info new_stmt_info;
   vec_info *vinfo = stmt_vinfo->vinfo;
   gimple *pattern_stmt;
 
@@ -3244,16 +3319,52 @@ vect_recog_bool_pattern (vec<gimple *> *stmts, tree 
*type_in,
       if (vectype == NULL_TREE)
        return NULL;
 
-      if (!check_bool_pattern (var, vinfo))
-       return NULL;
-
-      rhs = adjust_bool_pattern (var, TREE_TYPE (lhs), NULL_TREE, stmts);
-      lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
-      if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
-       pattern_stmt = gimple_build_assign (lhs, SSA_NAME, rhs);
+      if (check_bool_pattern (var, vinfo))
+       {
+         rhs = adjust_bool_pattern (var, TREE_TYPE (lhs), NULL_TREE, stmts);
+         lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
+         if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
+           pattern_stmt = gimple_build_assign (lhs, SSA_NAME, rhs);
+         else
+           pattern_stmt
+             = gimple_build_assign (lhs, NOP_EXPR, rhs);
+       }
       else
-       pattern_stmt
-         = gimple_build_assign (lhs, NOP_EXPR, rhs);
+       {
+         tree type = search_type_for_mask (var, vinfo);
+         tree cst0, cst1, cmp, tmp;
+
+         if (!type)
+           return NULL;
+
+         /* We may directly use cond with narrowed type to avoid
+            multiple cond exprs with following result packing and
+            perform single cond with packed mask instead.  In case
+            of widening we better make cond first and then extract
+            results.  */
+         if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (lhs)))
+           type = TREE_TYPE (lhs);
+
+         cst0 = build_int_cst (type, 0);
+         cst1 = build_int_cst (type, 1);
+         tmp = vect_recog_temp_ssa_var (type, NULL);
+         cmp = build2 (NE_EXPR, boolean_type_node,
+                       var, build_int_cst (TREE_TYPE (var), 0));
+         pattern_stmt = gimple_build_assign (tmp, COND_EXPR, cmp, cst1, cst0);
+
+         if (!useless_type_conversion_p (type, TREE_TYPE (lhs)))
+           {
+             tree new_vectype = get_vectype_for_scalar_type (type);
+             new_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
+             set_vinfo_for_stmt (pattern_stmt, new_stmt_info);
+             STMT_VINFO_VECTYPE (new_stmt_info) = new_vectype;
+             new_pattern_def_seq (stmt_vinfo, pattern_stmt);
+
+             lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
+             pattern_stmt = gimple_build_assign (lhs, CONVERT_EXPR, tmp);
+           }
+       }
+
       *type_out = vectype;
       *type_in = vectype;
       stmts->safe_push (last_stmt);
@@ -3282,15 +3393,19 @@ vect_recog_bool_pattern (vec<gimple *> *stmts, tree 
*type_in,
       if (get_vectype_for_scalar_type (type) == NULL_TREE)
        return NULL;
 
-      if (!check_bool_pattern (var, vinfo))
-       return NULL;
+      if (check_bool_pattern (var, vinfo))
+       {
+         rhs = adjust_bool_pattern (var, type, NULL_TREE, stmts);
+         rhs = build2 (NE_EXPR, boolean_type_node,
+                       rhs, build_int_cst (type, 0));
+       }
+      else
+       rhs = build2 (NE_EXPR, boolean_type_node,
+                     var, build_int_cst (TREE_TYPE (var), 0)),
 
-      rhs = adjust_bool_pattern (var, type, NULL_TREE, stmts);
       lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
       pattern_stmt 
-         = gimple_build_assign (lhs, COND_EXPR,
-                                build2 (NE_EXPR, boolean_type_node,
-                                        rhs, build_int_cst (type, 0)),
+         = gimple_build_assign (lhs, COND_EXPR, rhs,
                                 gimple_assign_rhs2 (last_stmt),
                                 gimple_assign_rhs3 (last_stmt));
       *type_out = vectype;
@@ -3310,16 +3425,43 @@ vect_recog_bool_pattern (vec<gimple *> *stmts, tree 
*type_in,
       gcc_assert (vectype != NULL_TREE);
       if (!VECTOR_MODE_P (TYPE_MODE (vectype)))
        return NULL;
-      if (!check_bool_pattern (var, vinfo))
-       return NULL;
 
-      rhs = adjust_bool_pattern (var, TREE_TYPE (vectype), NULL_TREE, stmts);
+      if (check_bool_pattern (var, vinfo))
+       rhs = adjust_bool_pattern (var, TREE_TYPE (vectype),
+                                  NULL_TREE, stmts);
+      else
+       {
+         tree type = search_type_for_mask (var, vinfo);
+         tree cst0, cst1, cmp, new_vectype;
+
+         if (!type)
+           return NULL;
+
+         if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (vectype)))
+           type = TREE_TYPE (vectype);
+
+         cst0 = build_int_cst (type, 0);
+         cst1 = build_int_cst (type, 1);
+         new_vectype = get_vectype_for_scalar_type (type);
+
+         rhs = vect_recog_temp_ssa_var (type, NULL);
+         cmp = build2 (NE_EXPR, boolean_type_node,
+                       var, build_int_cst (TREE_TYPE (var), 0));
+         pattern_stmt = gimple_build_assign (rhs, COND_EXPR,
+                                             cmp, cst1, cst0);
+
+         pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
+         set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
+         STMT_VINFO_VECTYPE (pattern_stmt_info) = new_vectype;
+         append_pattern_def_seq (stmt_vinfo, pattern_stmt);
+       }
+
       lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (vectype), lhs);
       if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
        {
          tree rhs2 = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
          gimple *cast_stmt = gimple_build_assign (rhs2, NOP_EXPR, rhs);
-         new_pattern_def_seq (stmt_vinfo, cast_stmt);
+         append_pattern_def_seq (stmt_vinfo, cast_stmt);
          rhs = rhs2;
        }
       pattern_stmt = gimple_build_assign (lhs, SSA_NAME, rhs);

Reply via email to