Hi,

This patch supports boolean vectors in vector lowering.  Main change is to 
lower vector comparison into comparisons, not cond_exprs.

Thanks,
Ilya
--
2015-10-02  Ilya Enkovich  <enkovich....@gmail.com>

        * tree-vect-generic.c (elem_op_func): Add new operand to hold
        vector type.
        (do_unop): Adjust to modified function type.
        (do_binop): Likewise.
        (do_plus_minus): Likewise.
        (do_negate); Likewise.
        (expand_vector_piecewise): Likewise.
        (do_cond): Likewise.
        (do_compare): Use comparison instead of condition.
        (expand_vector_divmod): Use boolean vector type for comparison.
        (expand_vector_operations_1): Skip scalar mask operations.


diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index dad38a2..a20b9af 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -105,14 +105,27 @@ build_word_mode_vector_type (int nunits)
 }
 
 typedef tree (*elem_op_func) (gimple_stmt_iterator *,
-                             tree, tree, tree, tree, tree, enum tree_code);
+                             tree, tree, tree, tree, tree, enum tree_code,
+                             tree);
 
 static inline tree
 tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
                  tree t, tree bitsize, tree bitpos)
 {
   if (bitpos)
-    return gimplify_build3 (gsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
+    {
+      if (TREE_CODE (type) == BOOLEAN_TYPE)
+       {
+         tree itype
+           = build_nonstandard_integer_type (tree_to_uhwi (bitsize), 0);
+         tree field = gimplify_build3 (gsi, BIT_FIELD_REF, itype, t,
+                                       bitsize, bitpos);
+         return gimplify_build2 (gsi, NE_EXPR, type, field,
+                                 build_zero_cst (itype));
+       }
+      else
+       return gimplify_build3 (gsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
+    }
   else
     return gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t);
 }
@@ -120,7 +133,7 @@ tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
 static tree
 do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
         tree b ATTRIBUTE_UNUSED, tree bitpos, tree bitsize,
-        enum tree_code code)
+        enum tree_code code, tree type ATTRIBUTE_UNUSED)
 {
   a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
   return gimplify_build1 (gsi, code, inner_type, a);
@@ -128,7 +141,8 @@ do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
 
 static tree
 do_binop (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
-         tree bitpos, tree bitsize, enum tree_code code)
+         tree bitpos, tree bitsize, enum tree_code code,
+         tree type ATTRIBUTE_UNUSED)
 {
   if (TREE_CODE (TREE_TYPE (a)) == VECTOR_TYPE)
     a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
@@ -145,20 +159,12 @@ do_binop (gimple_stmt_iterator *gsi, tree inner_type, 
tree a, tree b,
    size equal to the size of INNER_TYPE.  */
 static tree
 do_compare (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
-         tree bitpos, tree bitsize, enum tree_code code)
+           tree bitpos, tree bitsize, enum tree_code code, tree type)
 {
-  tree comp_type;
-
   a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
   b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
 
-  comp_type = build_nonstandard_integer_type
-                     (GET_MODE_BITSIZE (TYPE_MODE (inner_type)), 0);
-
-  return gimplify_build3 (gsi, COND_EXPR, comp_type,
-                         fold_build2 (code, boolean_type_node, a, b),
-                         build_int_cst (comp_type, -1),
-                         build_int_cst (comp_type, 0));
+  return gimplify_build2 (gsi, code, TREE_TYPE (type), a, b);
 }
 
 /* Expand vector addition to scalars.  This does bit twiddling
@@ -177,7 +183,7 @@ do_compare (gimple_stmt_iterator *gsi, tree inner_type, 
tree a, tree b,
 static tree
 do_plus_minus (gimple_stmt_iterator *gsi, tree word_type, tree a, tree b,
               tree bitpos ATTRIBUTE_UNUSED, tree bitsize ATTRIBUTE_UNUSED,
-              enum tree_code code)
+              enum tree_code code, tree type ATTRIBUTE_UNUSED)
 {
   tree inner_type = TREE_TYPE (TREE_TYPE (a));
   unsigned HOST_WIDE_INT max;
@@ -209,7 +215,8 @@ static tree
 do_negate (gimple_stmt_iterator *gsi, tree word_type, tree b,
           tree unused ATTRIBUTE_UNUSED, tree bitpos ATTRIBUTE_UNUSED,
           tree bitsize ATTRIBUTE_UNUSED,
-          enum tree_code code ATTRIBUTE_UNUSED)
+          enum tree_code code ATTRIBUTE_UNUSED,
+          tree type ATTRIBUTE_UNUSED)
 {
   tree inner_type = TREE_TYPE (TREE_TYPE (b));
   HOST_WIDE_INT max;
@@ -255,7 +262,7 @@ expand_vector_piecewise (gimple_stmt_iterator *gsi, 
elem_op_func f,
   for (i = 0; i < nunits;
        i += delta, index = int_const_binop (PLUS_EXPR, index, part_width))
     {
-      tree result = f (gsi, inner_type, a, b, index, part_width, code);
+      tree result = f (gsi, inner_type, a, b, index, part_width, code, type);
       constructor_elt ce = {NULL_TREE, result};
       v->quick_push (ce);
     }
@@ -298,7 +305,7 @@ expand_vector_parallel (gimple_stmt_iterator *gsi, 
elem_op_func f, tree type,
       /* Use a single scalar operation with a mode no wider than word_mode.  */
       mode = mode_for_size (tree_to_uhwi (TYPE_SIZE (type)), MODE_INT, 0);
       compute_type = lang_hooks.types.type_for_mode (mode, 1);
-      result = f (gsi, compute_type, a, b, NULL_TREE, NULL_TREE, code);
+      result = f (gsi, compute_type, a, b, NULL_TREE, NULL_TREE, code, type);
       warning_at (loc, OPT_Wvector_operation_performance,
                  "vector operation will be expanded with a "
                  "single scalar operation");
@@ -615,11 +622,12 @@ expand_vector_divmod (gimple_stmt_iterator *gsi, tree 
type, tree op0,
          if (addend == NULL_TREE
              && expand_vec_cond_expr_p (type, type))
            {
-             tree zero, cst, cond;
+             tree zero, cst, cond, mask_type;
              gimple *stmt;
 
+             mask_type = build_same_sized_truth_vector_type (type);
              zero = build_zero_cst (type);
-             cond = build2 (LT_EXPR, type, op0, zero);
+             cond = build2 (LT_EXPR, mask_type, op0, zero);
              for (i = 0; i < nunits; i++)
                vec[i] = build_int_cst (TREE_TYPE (type),
                                        ((unsigned HOST_WIDE_INT) 1
@@ -1386,7 +1394,8 @@ count_type_subparts (tree type)
 
 static tree
 do_cond (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
-        tree bitpos, tree bitsize, enum tree_code code)
+        tree bitpos, tree bitsize, enum tree_code code,
+        tree type ATTRIBUTE_UNUSED)
 {
   if (TREE_CODE (TREE_TYPE (a)) == VECTOR_TYPE)
     a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
@@ -1496,6 +1505,12 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
   if (TREE_CODE (type) != VECTOR_TYPE)
     return;
 
+  /* A scalar operation pretending to be a vector one.  */
+  if (VECTOR_BOOLEAN_TYPE_P (type)
+      && !VECTOR_MODE_P (TYPE_MODE (type))
+      && TYPE_MODE (type) != BLKmode)
+    return;
+
   if (CONVERT_EXPR_CODE_P (code)
       || code == FLOAT_EXPR
       || code == FIX_TRUNC_EXPR

Reply via email to