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.
Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues.
Ok for master?
Thanks,
Tamar
gcc/ChangeLog:
PR target/118974
* tree-vect-stmts.cc (supports_vector_compare_and_branch): New.
(vectorizable_early_exit): Use it.
---
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index
25ec87022f2ad5726dcc71aa1630b655e2ecfe0b..eb8f636eeb2976c1b44cc6cb06c2cda8b97662c0
100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -12644,6 +12644,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. */
@@ -12718,8 +12751,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,
@@ -12734,7 +12767,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,
--
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 25ec87022f2ad5726dcc71aa1630b655e2ecfe0b..eb8f636eeb2976c1b44cc6cb06c2cda8b97662c0 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -12644,6 +12644,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. */
@@ -12718,8 +12751,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,
@@ -12734,7 +12767,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,