https://gcc.gnu.org/g:82a865f3a7f078435ffbd05d415a082d0391286e

commit r16-4280-g82a865f3a7f078435ffbd05d415a082d0391286e
Author: Richard Biener <[email protected]>
Date:   Tue Oct 7 14:31:18 2025 +0200

    tree-optimization/105490 - improve COND_EXPR bool pattern
    
    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.
    
            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.

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

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 000000000000..754168c5646f
--- /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 782327235db1..dccd3c9806e6 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)

Reply via email to