As we consider bitwise operations possible mask operations we have
to consider the case of only one operand arriving as mask.  The
following compensates for this by creating mask from the other operand
and insert possibly required mask conversions.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

        PR tree-optimization/110223
        PR tree-optimization/122128
        * tree-vect-patterns.cc (vect_recog_bool_pattern): Add
        compensation for mixed mask/data bitwise operations.

        * gcc.dg/vect/vect-bool-2.c: New testcase.
        * gcc.dg/vect/vect-bool-cmp-3.c: Likewise.
        * gcc.dg/vect/vect-bool-cmp-4.c: Likewise.
---
 gcc/testsuite/gcc.dg/vect/vect-bool-2.c     | 17 ++++++
 gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c | 14 +++++
 gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c | 14 +++++
 gcc/tree-vect-patterns.cc                   | 62 +++++++++++++++++++++
 4 files changed, 107 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-bool-2.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c

diff --git a/gcc/testsuite/gcc.dg/vect/vect-bool-2.c 
b/gcc/testsuite/gcc.dg/vect/vect-bool-2.c
new file mode 100644
index 00000000000..88db018a4f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-bool-2.c
@@ -0,0 +1,17 @@
+/* PR122128 */
+/* { dg-do compile } */
+
+_Bool a[1024];
+signed char b[1024];
+
+void foo ()
+{
+  for (int i = 0; i < 1024; ++i)
+    {
+      bool x = a[i];
+      bool y = b[i] < 17;
+      a[i] = x & y;
+    }
+}
+
+/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c 
b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c
new file mode 100644
index 00000000000..c522008211c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c
@@ -0,0 +1,14 @@
+/* PR110223 */
+/* { dg-do compile } */
+
+_Bool k[1024];
+_Bool res[1024];
+
+int main ()
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    res[i] = k[i] != (i == 0);
+}
+
+/* { dg-final { scan-tree-dump "optimized: loop vectorized" { target 
vect_unpack } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c 
b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c
new file mode 100644
index 00000000000..162f22835da
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c
@@ -0,0 +1,14 @@
+/* PR110223 */
+/* { dg-do compile } */
+
+_Bool k[1024];
+_Bool res[1024];
+
+int main ()
+{
+  char i;
+  for (i = 0; i < 64; i++)
+    res[i] = k[i] != (i == 0);
+}
+
+/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" } } */
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 8b4f9840181..5581f44a6a8 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -5754,6 +5754,68 @@ vect_recog_bool_pattern (vec_info *vinfo,
       *type_out = vectype;
       vect_pattern_detected ("vect_recog_bool_pattern", last_stmt);
 
+      return pattern_stmt;
+    }
+  else if (rhs_code == BIT_XOR_EXPR
+          || rhs_code == BIT_AND_EXPR
+          || rhs_code == BIT_IOR_EXPR)
+    {
+      tree lhs_type = integer_type_for_mask (lhs, vinfo);
+      if (!lhs_type)
+       return NULL;
+      vectype = get_mask_type_for_scalar_type (vinfo, lhs_type);
+      if (!vectype)
+       return NULL;
+      tree rhs2 = gimple_assign_rhs2 (last_stmt);
+      tree rhs1_type = integer_type_for_mask (var, vinfo);
+      tree rhs2_type = integer_type_for_mask (rhs2, vinfo);
+      if (rhs1_type && rhs2_type)
+       return NULL;
+      /* When one input is a mask and the other is not create a pattern
+        stmt sequence that creates a mask for the non-mask input and
+        convert it to one suitable for the output mask used.  */
+      if (rhs1_type && !rhs2_type)
+       {
+         tree rhs1_vectype = get_mask_type_for_scalar_type (vinfo, rhs1_type);
+         if (!rhs1_vectype)
+           return NULL;
+         tree rhs2_vectype = get_vectype_for_scalar_type (vinfo,
+                                                          TREE_TYPE (rhs2));
+         if (!rhs2_vectype)
+           return NULL;
+         tree new_vectype = truth_type_for (rhs2_vectype);
+         tree tem = vect_recog_temp_ssa_var (TREE_TYPE (new_vectype), NULL);
+         pattern_stmt = gimple_build_assign (tem, NE_EXPR, rhs2,
+                                             build_zero_cst
+                                               (TREE_TYPE (rhs2)));
+         append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt,
+                                 new_vectype, TREE_TYPE (new_vectype));
+         rhs2 = vect_convert_mask_for_vectype (tem, rhs1_vectype,
+                                               stmt_vinfo, vinfo);
+       }
+      else if (!rhs1_type && rhs2_type)
+       {
+         tree rhs2_vectype = get_mask_type_for_scalar_type (vinfo, rhs2_type);
+         if (!rhs2_vectype)
+           return NULL;
+         tree rhs1_vectype = get_vectype_for_scalar_type (vinfo,
+                                                          TREE_TYPE (var));
+         if (!rhs1_vectype)
+           return NULL;
+         tree new_vectype = truth_type_for (rhs1_vectype);
+         tree tem = vect_recog_temp_ssa_var (TREE_TYPE (new_vectype), NULL);
+         pattern_stmt = gimple_build_assign (tem, NE_EXPR, var,
+                                             build_zero_cst
+                                               (TREE_TYPE (var)));
+         append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt,
+                                 new_vectype, TREE_TYPE (new_vectype));
+         var = vect_convert_mask_for_vectype (tem, rhs2_vectype,
+                                              stmt_vinfo, vinfo);
+       }
+      lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
+      pattern_stmt = gimple_build_assign (lhs, rhs_code, var, rhs2);
+      vect_pattern_detected ("vect_recog_bool_pattern", last_stmt);
+      *type_out = vectype;
       return pattern_stmt;
     }
   else if (rhs_code == SSA_NAME
-- 
2.43.0

Reply via email to