The 3rd patch in this series will modify these functions, but I have to re-order
and extract some shared functionality to avoid duplicate and having to forward
declare stuff.

I thus separated out the refactoring bit from the parts that use and change
these functions.

This patch is NFC.

Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.

Any comments? otherwise will commit end of week.

Thanks,
Tamar

gcc/ChangeLog:

        * config/aarch64/aarch64-acle-builtins.cc
        (gimple_folder::fold_to_vl_pred): Refactor folding logic into
        aarch64_fold_sve_ptrue_vl.
        * config/aarch64/aarch64-protos.h (aarch64_fold_sve_ptrue_vl): New.
        * config/aarch64/aarch64.cc (aarch64_instruction_selection): Move down.
        (aarch64_fold_sve_ptrue_vl): New.

---
diff --git a/gcc/config/aarch64/aarch64-acle-builtins.cc 
b/gcc/config/aarch64/aarch64-acle-builtins.cc
index 
426316001ced864081e798b50c7dcb3281a77834..e64c6f00f91717151be0f4d092ca4d5e1123f061
 100644
--- a/gcc/config/aarch64/aarch64-acle-builtins.cc
+++ b/gcc/config/aarch64/aarch64-acle-builtins.cc
@@ -2983,22 +2983,9 @@ gimple *
 gimple_folder::fold_to_vl_pred (unsigned int vl)
 {
   tree vectype = TREE_TYPE (lhs);
-  tree element_type = TREE_TYPE (vectype);
-  tree minus_one = build_all_ones_cst (element_type);
-  tree zero = build_zero_cst (element_type);
   unsigned int element_bytes = type_suffix (0).element_bytes;
-
-  /* Construct COUNT elements that contain the ptrue followed by
-     a repeating sequence of COUNT elements.  */
-  unsigned int count = constant_lower_bound (TYPE_VECTOR_SUBPARTS (vectype));
-  gcc_assert (vl * element_bytes <= count);
-  tree_vector_builder builder (vectype, count, 2);
-  for (unsigned int i = 0; i < count * 2; ++i)
-    {
-      bool bit = (i & (element_bytes - 1)) == 0 && i < vl * element_bytes;
-      builder.quick_push (bit ? minus_one : zero);
-    }
-  return gimple_build_assign (lhs, builder.build ());
+  tree pred = aarch64_fold_sve_ptrue_vl (vectype, vl, element_bytes);
+  return gimple_build_assign (lhs, pred);
 }
 
 /* Try to fold the call to a constant, given that, for integers, the call
diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 
5580f3148d6db754adad6804b506f5a0fe3ecf66..f9943f506c12aec81b3119ceac5d7cafd223dfea
 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -1035,6 +1035,7 @@ unsigned aarch64_debugger_regno (unsigned);
 unsigned aarch64_trampoline_size (void);
 void aarch64_asm_output_labelref (FILE *, const char *);
 void aarch64_cpu_cpp_builtins (cpp_reader *);
+tree aarch64_fold_sve_ptrue_vl (tree, unsigned int, unsigned int);
 const char * aarch64_gen_far_branch (rtx *, int, const char *, const char *);
 const char * aarch64_output_probe_stack_range (rtx, rtx);
 const char * aarch64_output_probe_sve_stack_clash (rtx, rtx, rtx, rtx);
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 
72822ca621f52afee144bffa76bc75aac28adae1..bcd143ac06cc1b3674d05dd087874d9b435cae06
 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -63,6 +63,7 @@
 #include "gimple-iterator.h"
 #include "gimple-fold.h"
 #include "tree-vectorizer.h"
+#include "tree-vector-builder.h"
 #include "aarch64-cost-tables.h"
 #include "dumpfile.h"
 #include "builtins.h"
@@ -2311,72 +2312,6 @@ aarch64_try_widen_mult_by_pow2 (const gassign *convert,
   return true;
 }
 
-/* Implement TARGET_INSTRUCTION_SELECTION.  The target hook is used to
-   change generic sequences to a form AArch64 has an easier time expanding
-   instructions for.  It's not supposed to be used for generic rewriting that
-   all targets would benefit from.  */
-
-static bool
-aarch64_instruction_selection (function * /* fun */, gimple_stmt_iterator *gsi)
-{
-  auto stmt = gsi_stmt (*gsi);
-  gassign *assign = dyn_cast<gassign *> (stmt);
-
-  if (!assign)
-    return false;
-
-  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (assign))
-      && aarch64_try_widen_mult_by_pow2 (assign, gsi))
-    return true;
-
-  /* Convert
-       p == q ? s1 : s2;
-     to
-       p != q ? s2 : s1;
-     where p and q are svbool_t expr.  Due to the absence of predicate
-     comparison instructions, we use bitwise xor for checking inequality.
-     Transforming == to != avoids an extra bitwise inversion to the xor.  */
-  if (gimple_assign_rhs_code (assign) != VEC_COND_EXPR)
-    return false;
-
-  tree lhs = gimple_assign_lhs (assign);
-  tree rhs1 = gimple_assign_rhs1 (assign);
-  tree rhs2 = gimple_assign_rhs2 (assign);
-  tree rhs3 = gimple_assign_rhs3 (assign);
-
-  if (TREE_CODE (rhs1) != SSA_NAME || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE 
(rhs1)))
-    return false;
-
-  gassign *da = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (rhs1));
-
-  if (!da)
-    return false;
-
-  if (gimple_assign_rhs_code (da) != EQ_EXPR)
-    return false;
-
-  tree eqa = gimple_assign_rhs1 (da);
-  tree eqb = gimple_assign_rhs2 (da);
-
-  if (!VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqa))
-      || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqb)))
-    return false;
-
-  tree ne_expr_var = create_tmp_var (TREE_TYPE (rhs1));
-  gimple *ne_stmt = gimple_build_assign (ne_expr_var, NE_EXPR, eqa, eqb);
-  gsi_safe_insert_before (gsi, ne_stmt);
-
-  gimple *g = gimple_build_call_internal (IFN_VCOND_MASK, 3,
-                                         ne_expr_var, rhs3, rhs2);
-  if (!g)
-    return false;
-
-  gimple_set_lhs (g, lhs);
-  gsi_replace (gsi, g, false);
-
-  return true;
-}
-
 /* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST.  If an explicit max was set then
    honor it, otherwise apply a tuning specific scale to branch costs.  */
 
@@ -4482,6 +4417,97 @@ aarch64_fold_sve_cnt_pat (aarch64_svpattern pattern, 
unsigned int nelts_per_vq)
   return -1;
 }
 
+/* Build a predicate of type VECTYPE in which the first VL elements of size
+   ELEMENT_BYTES are set and the rest are clear.  */
+
+tree
+aarch64_fold_sve_ptrue_vl (tree vectype, unsigned int vl,
+                          unsigned int element_bytes)
+{
+  tree element_type = TREE_TYPE (vectype);
+  tree minus_one = build_all_ones_cst (element_type);
+  tree zero = build_zero_cst (element_type);
+
+  /* Construct COUNT elements that contain the ptrue followed by
+     a repeating sequence of COUNT elements.  */
+  unsigned int count = constant_lower_bound (TYPE_VECTOR_SUBPARTS (vectype));
+  count = MAX (count, vl * element_bytes);
+  count = pow2p_hwi (count) ? count : 1U << ceil_log2 (count);
+  tree_vector_builder builder (vectype, count, 2);
+  for (unsigned int i = 0; i < count * 2; ++i)
+    {
+      bool bit = (i & (element_bytes - 1)) == 0 && i < vl * element_bytes;
+      builder.quick_push (bit ? minus_one : zero);
+    }
+  return builder.build ();
+}
+
+/* Implement TARGET_INSTRUCTION_SELECTION.  The target hook is used to
+   change generic sequences to a form AArch64 has an easier time expanding
+   instructions for.  It's not supposed to be used for generic rewriting that
+   all targets would benefit from.  */
+
+static bool
+aarch64_instruction_selection (function * /* fun */, gimple_stmt_iterator *gsi)
+{
+  auto stmt = gsi_stmt (*gsi);
+  gassign *assign = dyn_cast<gassign *> (stmt);
+
+  if (!assign)
+    return false;
+
+  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (assign))
+      && aarch64_try_widen_mult_by_pow2 (assign, gsi))
+    return true;
+
+  /* Convert
+       p == q ? s1 : s2;
+     to
+       p != q ? s2 : s1;
+     where p and q are svbool_t expr.  Due to the absence of predicate
+     comparison instructions, we use bitwise xor for checking inequality.
+     Transforming == to != avoids an extra bitwise inversion to the xor.  */
+  if (gimple_assign_rhs_code (assign) != VEC_COND_EXPR)
+    return false;
+
+  tree lhs = gimple_assign_lhs (assign);
+  tree rhs1 = gimple_assign_rhs1 (assign);
+  tree rhs2 = gimple_assign_rhs2 (assign);
+  tree rhs3 = gimple_assign_rhs3 (assign);
+
+  if (TREE_CODE (rhs1) != SSA_NAME || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE 
(rhs1)))
+    return false;
+
+  gassign *da = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (rhs1));
+
+  if (!da)
+    return false;
+
+  if (gimple_assign_rhs_code (da) != EQ_EXPR)
+    return false;
+
+  tree eqa = gimple_assign_rhs1 (da);
+  tree eqb = gimple_assign_rhs2 (da);
+
+  if (!VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqa))
+      || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqb)))
+    return false;
+
+  tree ne_expr_var = create_tmp_var (TREE_TYPE (rhs1));
+  gimple *ne_stmt = gimple_build_assign (ne_expr_var, NE_EXPR, eqa, eqb);
+  gsi_safe_insert_before (gsi, ne_stmt);
+
+  gimple *g = gimple_build_call_internal (IFN_VCOND_MASK, 3,
+                                         ne_expr_var, rhs3, rhs2);
+  if (!g)
+    return false;
+
+  gimple_set_lhs (g, lhs);
+  gsi_replace (gsi, g, false);
+
+  return true;
+}
+
 /* Return true if a single CNT[BHWD] instruction can multiply FACTOR
    by the number of 128-bit quadwords in an SVE vector.  */
 


-- 
diff --git a/gcc/config/aarch64/aarch64-acle-builtins.cc b/gcc/config/aarch64/aarch64-acle-builtins.cc
index 426316001ced864081e798b50c7dcb3281a77834..e64c6f00f91717151be0f4d092ca4d5e1123f061 100644
--- a/gcc/config/aarch64/aarch64-acle-builtins.cc
+++ b/gcc/config/aarch64/aarch64-acle-builtins.cc
@@ -2983,22 +2983,9 @@ gimple *
 gimple_folder::fold_to_vl_pred (unsigned int vl)
 {
   tree vectype = TREE_TYPE (lhs);
-  tree element_type = TREE_TYPE (vectype);
-  tree minus_one = build_all_ones_cst (element_type);
-  tree zero = build_zero_cst (element_type);
   unsigned int element_bytes = type_suffix (0).element_bytes;
-
-  /* Construct COUNT elements that contain the ptrue followed by
-     a repeating sequence of COUNT elements.  */
-  unsigned int count = constant_lower_bound (TYPE_VECTOR_SUBPARTS (vectype));
-  gcc_assert (vl * element_bytes <= count);
-  tree_vector_builder builder (vectype, count, 2);
-  for (unsigned int i = 0; i < count * 2; ++i)
-    {
-      bool bit = (i & (element_bytes - 1)) == 0 && i < vl * element_bytes;
-      builder.quick_push (bit ? minus_one : zero);
-    }
-  return gimple_build_assign (lhs, builder.build ());
+  tree pred = aarch64_fold_sve_ptrue_vl (vectype, vl, element_bytes);
+  return gimple_build_assign (lhs, pred);
 }
 
 /* Try to fold the call to a constant, given that, for integers, the call
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 5580f3148d6db754adad6804b506f5a0fe3ecf66..f9943f506c12aec81b3119ceac5d7cafd223dfea 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -1035,6 +1035,7 @@ unsigned aarch64_debugger_regno (unsigned);
 unsigned aarch64_trampoline_size (void);
 void aarch64_asm_output_labelref (FILE *, const char *);
 void aarch64_cpu_cpp_builtins (cpp_reader *);
+tree aarch64_fold_sve_ptrue_vl (tree, unsigned int, unsigned int);
 const char * aarch64_gen_far_branch (rtx *, int, const char *, const char *);
 const char * aarch64_output_probe_stack_range (rtx, rtx);
 const char * aarch64_output_probe_sve_stack_clash (rtx, rtx, rtx, rtx);
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 72822ca621f52afee144bffa76bc75aac28adae1..bcd143ac06cc1b3674d05dd087874d9b435cae06 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -63,6 +63,7 @@
 #include "gimple-iterator.h"
 #include "gimple-fold.h"
 #include "tree-vectorizer.h"
+#include "tree-vector-builder.h"
 #include "aarch64-cost-tables.h"
 #include "dumpfile.h"
 #include "builtins.h"
@@ -2311,72 +2312,6 @@ aarch64_try_widen_mult_by_pow2 (const gassign *convert,
   return true;
 }
 
-/* Implement TARGET_INSTRUCTION_SELECTION.  The target hook is used to
-   change generic sequences to a form AArch64 has an easier time expanding
-   instructions for.  It's not supposed to be used for generic rewriting that
-   all targets would benefit from.  */
-
-static bool
-aarch64_instruction_selection (function * /* fun */, gimple_stmt_iterator *gsi)
-{
-  auto stmt = gsi_stmt (*gsi);
-  gassign *assign = dyn_cast<gassign *> (stmt);
-
-  if (!assign)
-    return false;
-
-  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (assign))
-      && aarch64_try_widen_mult_by_pow2 (assign, gsi))
-    return true;
-
-  /* Convert
-	p == q ? s1 : s2;
-     to
-	p != q ? s2 : s1;
-     where p and q are svbool_t expr.  Due to the absence of predicate
-     comparison instructions, we use bitwise xor for checking inequality.
-     Transforming == to != avoids an extra bitwise inversion to the xor.  */
-  if (gimple_assign_rhs_code (assign) != VEC_COND_EXPR)
-    return false;
-
-  tree lhs = gimple_assign_lhs (assign);
-  tree rhs1 = gimple_assign_rhs1 (assign);
-  tree rhs2 = gimple_assign_rhs2 (assign);
-  tree rhs3 = gimple_assign_rhs3 (assign);
-
-  if (TREE_CODE (rhs1) != SSA_NAME || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)))
-    return false;
-
-  gassign *da = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (rhs1));
-
-  if (!da)
-    return false;
-
-  if (gimple_assign_rhs_code (da) != EQ_EXPR)
-    return false;
-
-  tree eqa = gimple_assign_rhs1 (da);
-  tree eqb = gimple_assign_rhs2 (da);
-
-  if (!VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqa))
-      || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqb)))
-    return false;
-
-  tree ne_expr_var = create_tmp_var (TREE_TYPE (rhs1));
-  gimple *ne_stmt = gimple_build_assign (ne_expr_var, NE_EXPR, eqa, eqb);
-  gsi_safe_insert_before (gsi, ne_stmt);
-
-  gimple *g = gimple_build_call_internal (IFN_VCOND_MASK, 3,
-					  ne_expr_var, rhs3, rhs2);
-  if (!g)
-    return false;
-
-  gimple_set_lhs (g, lhs);
-  gsi_replace (gsi, g, false);
-
-  return true;
-}
-
 /* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST.  If an explicit max was set then
    honor it, otherwise apply a tuning specific scale to branch costs.  */
 
@@ -4482,6 +4417,97 @@ aarch64_fold_sve_cnt_pat (aarch64_svpattern pattern, unsigned int nelts_per_vq)
   return -1;
 }
 
+/* Build a predicate of type VECTYPE in which the first VL elements of size
+   ELEMENT_BYTES are set and the rest are clear.  */
+
+tree
+aarch64_fold_sve_ptrue_vl (tree vectype, unsigned int vl,
+			   unsigned int element_bytes)
+{
+  tree element_type = TREE_TYPE (vectype);
+  tree minus_one = build_all_ones_cst (element_type);
+  tree zero = build_zero_cst (element_type);
+
+  /* Construct COUNT elements that contain the ptrue followed by
+     a repeating sequence of COUNT elements.  */
+  unsigned int count = constant_lower_bound (TYPE_VECTOR_SUBPARTS (vectype));
+  count = MAX (count, vl * element_bytes);
+  count = pow2p_hwi (count) ? count : 1U << ceil_log2 (count);
+  tree_vector_builder builder (vectype, count, 2);
+  for (unsigned int i = 0; i < count * 2; ++i)
+    {
+      bool bit = (i & (element_bytes - 1)) == 0 && i < vl * element_bytes;
+      builder.quick_push (bit ? minus_one : zero);
+    }
+  return builder.build ();
+}
+
+/* Implement TARGET_INSTRUCTION_SELECTION.  The target hook is used to
+   change generic sequences to a form AArch64 has an easier time expanding
+   instructions for.  It's not supposed to be used for generic rewriting that
+   all targets would benefit from.  */
+
+static bool
+aarch64_instruction_selection (function * /* fun */, gimple_stmt_iterator *gsi)
+{
+  auto stmt = gsi_stmt (*gsi);
+  gassign *assign = dyn_cast<gassign *> (stmt);
+
+  if (!assign)
+    return false;
+
+  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (assign))
+      && aarch64_try_widen_mult_by_pow2 (assign, gsi))
+    return true;
+
+  /* Convert
+	p == q ? s1 : s2;
+     to
+	p != q ? s2 : s1;
+     where p and q are svbool_t expr.  Due to the absence of predicate
+     comparison instructions, we use bitwise xor for checking inequality.
+     Transforming == to != avoids an extra bitwise inversion to the xor.  */
+  if (gimple_assign_rhs_code (assign) != VEC_COND_EXPR)
+    return false;
+
+  tree lhs = gimple_assign_lhs (assign);
+  tree rhs1 = gimple_assign_rhs1 (assign);
+  tree rhs2 = gimple_assign_rhs2 (assign);
+  tree rhs3 = gimple_assign_rhs3 (assign);
+
+  if (TREE_CODE (rhs1) != SSA_NAME || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)))
+    return false;
+
+  gassign *da = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (rhs1));
+
+  if (!da)
+    return false;
+
+  if (gimple_assign_rhs_code (da) != EQ_EXPR)
+    return false;
+
+  tree eqa = gimple_assign_rhs1 (da);
+  tree eqb = gimple_assign_rhs2 (da);
+
+  if (!VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqa))
+      || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqb)))
+    return false;
+
+  tree ne_expr_var = create_tmp_var (TREE_TYPE (rhs1));
+  gimple *ne_stmt = gimple_build_assign (ne_expr_var, NE_EXPR, eqa, eqb);
+  gsi_safe_insert_before (gsi, ne_stmt);
+
+  gimple *g = gimple_build_call_internal (IFN_VCOND_MASK, 3,
+					  ne_expr_var, rhs3, rhs2);
+  if (!g)
+    return false;
+
+  gimple_set_lhs (g, lhs);
+  gsi_replace (gsi, g, false);
+
+  return true;
+}
+
 /* Return true if a single CNT[BHWD] instruction can multiply FACTOR
    by the number of 128-bit quadwords in an SVE vector.  */
 

Reply via email to