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)
