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,

Reply via email to