https://gcc.gnu.org/g:b24f73a8a5210b9877ae98112b0a87f2aeae0c62
commit r16-5586-gb24f73a8a5210b9877ae98112b0a87f2aeae0c62 Author: Tamar Christina <[email protected]> Date: Tue Nov 25 12:51:52 2025 +0000 vect: check support for gcond with {cond{_len}_}vec_cbranch_{any|all} optabs [PR118974] This change allows a target to only implement the explicit vec_cbranch optabs. To do this the vectorizer is updated to check for the new optabs directly. Targets that have a different type for BOOLEAN_VECTOR_TYPE_P for instance can use only the new optabs. gcc/ChangeLog: PR target/118974 * tree-vect-stmts.cc (supports_vector_compare_and_branch): New. (vectorizable_early_exit): Use it. Diff: --- gcc/tree-vect-stmts.cc | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index ce68c8770a98..264475ff0913 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -12664,6 +12664,39 @@ vectorizable_comparison (vec_info *vinfo, return true; } +/* Check to see if the target supports any of the compare and branch optabs for + vectors with MODE as these would be required when expanding. */ +static bool +supports_vector_compare_and_branch (loop_vec_info loop_vinfo, machine_mode mode) +{ + bool masked_loop_p = LOOP_VINFO_FULLY_MASKED_P (loop_vinfo); + bool len_loop_p = LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo); + + /* The vectorizer only produces vec_cbranch_any_optab directly. So only + check for support for that or vec_cbranch_any_optab when masked. + We can't produce vcond_cbranch_any directly from the vectorizer as we + want to keep gimple_cond as the GIMPLE representation. But we'll fold + it in expand. For that reason we require a backend to support the + unconditional vector cbranch optab if they support the conditional one, + which is just an optimization on the unconditional one. */ + if (masked_loop_p + && direct_optab_handler (cond_vec_cbranch_any_optab, mode) + != CODE_FOR_nothing) + return true; + else if (len_loop_p + && direct_optab_handler (cond_len_vec_cbranch_any_optab, mode) + != CODE_FOR_nothing) + return true; + else if (!masked_loop_p && !len_loop_p + && direct_optab_handler (vec_cbranch_any_optab, mode) + != CODE_FOR_nothing) + return true; + + /* The target can implement cbranch to distinguish between boolean vector + types and data types if they don't have a different mode for both. */ + return direct_optab_handler (cbranch_optab, mode) != CODE_FOR_nothing; +} + /* Check to see if the current early break given in STMT_INFO is valid for vectorization. */ @@ -12738,8 +12771,8 @@ vectorizable_early_exit (loop_vec_info loop_vinfo, stmt_vec_info stmt_info, tree tmp_type = build_vector_type (itype, TYPE_VECTOR_SUBPARTS (vectype)); narrow_type = truth_type_for (tmp_type); - if (direct_optab_handler (cbranch_optab, TYPE_MODE (narrow_type)) - == CODE_FOR_nothing) + if (!supports_vector_compare_and_branch (loop_vinfo, + TYPE_MODE (narrow_type))) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -12754,7 +12787,7 @@ vectorizable_early_exit (loop_vec_info loop_vinfo, stmt_vec_info stmt_info, if (cost_vec) { if (!addhn_supported_p - && direct_optab_handler (cbranch_optab, mode) == CODE_FOR_nothing) + && !supports_vector_compare_and_branch (loop_vinfo, mode)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
