We miss to add a mask conversion from the mask producer to the
appropriate mask for the condition operation.  The following moves
required helpers and adds the missing part of the pattern.  That's
required both for the case we have different mask element sizes
and for the case we have a different number of elements because
cond expression vectorization doesn't handle the mask having
different nunits than the data vector.

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

        PR tree-optimization/105490
        * tree-vect-patterns.cc (build_mask_conversion): Move earlier.
        (vect_convert_mask_for_vectype): Likewise.
        (vect_recog_bool_pattern): Remove redundant truth type
        construction.  Add missing possibly required mask conversion.

        * gcc.dg/vect/vect-cond-14.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/vect-cond-14.c | 38 ++++++++++
 gcc/tree-vect-patterns.cc                | 95 +++++++++++++-----------
 2 files changed, 88 insertions(+), 45 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-cond-14.c

diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-14.c 
b/gcc/testsuite/gcc.dg/vect/vect-cond-14.c
new file mode 100644
index 00000000000..754168c5646
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cond-14.c
@@ -0,0 +1,38 @@
+#include "tree-vect.h"
+
+short a[256];
+short b[256];
+short c[256];
+_Bool pb[256];
+
+void __attribute__((noipa))
+predicate_by_bool()
+{
+  for (int i = 0; i < 256; i++)
+    c[i] = pb[i] ? a[i] : b[i];
+}
+
+int
+main ()
+{
+  check_vect ();
+
+#pragma GCC novector
+  for (int i = 0; i < 256; i++)
+    {
+      a[i] = i;
+      b[i] = -i;
+      pb[i] = (i % 3) == 0;
+    }
+
+  predicate_by_bool();
+
+#pragma GCC novector
+  for (int i = 0; i < 256; i++)
+    if (c[i] != (pb[i] ? a[i] : b[i]))
+      abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" { target { 
vect_unpack && vect_condition } } } } */
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 782327235db..dccd3c9806e 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -5533,6 +5533,53 @@ vect_recog_gcond_pattern (vec_info *vinfo,
   return pattern_stmt;
 }
 
+
+/* A helper for vect_recog_mask_conversion_pattern.  Build
+   conversion of MASK to a type suitable for masking VECTYPE.
+   Built statement gets required vectype and is appended to
+   a pattern sequence of STMT_VINFO.
+
+   Return converted mask.  */
+
+static tree
+build_mask_conversion (vec_info *vinfo,
+                      tree mask, tree vectype, stmt_vec_info stmt_vinfo)
+{
+  gimple *stmt;
+  tree masktype, tmp;
+
+  masktype = truth_type_for (vectype);
+  tmp = vect_recog_temp_ssa_var (TREE_TYPE (masktype), NULL);
+  stmt = gimple_build_assign (tmp, CONVERT_EXPR, mask);
+  append_pattern_def_seq (vinfo, stmt_vinfo,
+                         stmt, masktype, TREE_TYPE (vectype));
+
+  return tmp;
+}
+
+
+/* Return MASK if MASK is suitable for masking an operation on vectors
+   of type VECTYPE, otherwise convert it into such a form and return
+   the result.  Associate any conversion statements with STMT_INFO's
+   pattern.  */
+
+static tree
+vect_convert_mask_for_vectype (tree mask, tree vectype,
+                              stmt_vec_info stmt_info, vec_info *vinfo)
+{
+  tree mask_type = integer_type_for_mask (mask, vinfo);
+  if (mask_type)
+    {
+      tree mask_vectype = get_mask_type_for_scalar_type (vinfo, mask_type);
+      if (mask_vectype
+         && maybe_ne (TYPE_VECTOR_SUBPARTS (vectype),
+                      TYPE_VECTOR_SUBPARTS (mask_vectype)))
+       mask = build_mask_conversion (vinfo, mask, vectype, stmt_info);
+    }
+  return mask;
+}
+
+
 /* Function vect_recog_bool_pattern
 
    Try to find pattern like following:
@@ -5691,10 +5738,12 @@ vect_recog_bool_pattern (vec_info *vinfo,
       if (!new_vectype)
        return NULL;
 
-      new_vectype = truth_type_for (new_vectype);
       append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt, new_vectype,
                              TREE_TYPE (var));
 
+      lhs_var = vect_convert_mask_for_vectype (lhs_var, vectype, stmt_vinfo,
+                                              vinfo);
+
       lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
       pattern_stmt
        = gimple_build_assign (lhs, COND_EXPR, lhs_var,
@@ -5750,29 +5799,6 @@ vect_recog_bool_pattern (vec_info *vinfo,
     return NULL;
 }
 
-/* A helper for vect_recog_mask_conversion_pattern.  Build
-   conversion of MASK to a type suitable for masking VECTYPE.
-   Built statement gets required vectype and is appended to
-   a pattern sequence of STMT_VINFO.
-
-   Return converted mask.  */
-
-static tree
-build_mask_conversion (vec_info *vinfo,
-                      tree mask, tree vectype, stmt_vec_info stmt_vinfo)
-{
-  gimple *stmt;
-  tree masktype, tmp;
-
-  masktype = truth_type_for (vectype);
-  tmp = vect_recog_temp_ssa_var (TREE_TYPE (masktype), NULL);
-  stmt = gimple_build_assign (tmp, CONVERT_EXPR, mask);
-  append_pattern_def_seq (vinfo, stmt_vinfo,
-                         stmt, masktype, TREE_TYPE (vectype));
-
-  return tmp;
-}
-
 
 /* Function vect_recog_mask_conversion_pattern
 
@@ -6005,27 +6031,6 @@ vect_get_load_store_mask (stmt_vec_info stmt_info)
   gcc_unreachable ();
 }
 
-/* Return MASK if MASK is suitable for masking an operation on vectors
-   of type VECTYPE, otherwise convert it into such a form and return
-   the result.  Associate any conversion statements with STMT_INFO's
-   pattern.  */
-
-static tree
-vect_convert_mask_for_vectype (tree mask, tree vectype,
-                              stmt_vec_info stmt_info, vec_info *vinfo)
-{
-  tree mask_type = integer_type_for_mask (mask, vinfo);
-  if (mask_type)
-    {
-      tree mask_vectype = get_mask_type_for_scalar_type (vinfo, mask_type);
-      if (mask_vectype
-         && maybe_ne (TYPE_VECTOR_SUBPARTS (vectype),
-                      TYPE_VECTOR_SUBPARTS (mask_vectype)))
-       mask = build_mask_conversion (vinfo, mask, vectype, stmt_info);
-    }
-  return mask;
-}
-
 /* Return the equivalent of:
 
      fold_convert (TYPE, VALUE)
-- 
2.43.0

Reply via email to