[gcc r17-2601] AArch64: Move SVE ptrue VL folding helpers

Tamar Christina via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:89c55025122c0a4f27c3a952f3298bd45b7c8207

commit r17-2601-g89c55025122c0a4f27c3a952f3298bd45b7c8207
Author: Tamar Christina <[email protected]>
Date:   Tue Jul 21 20:48:39 2026 +0100

    AArch64: Move SVE ptrue VL folding helpers
    
    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.
    
            * 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:
---
 gcc/config/aarch64/aarch64-acle-builtins.cc |  17 +--
 gcc/config/aarch64/aarch64-protos.h         |   1 +
 gcc/config/aarch64/aarch64.cc               | 158 ++++++++++++++++------------
 3 files changed, 95 insertions(+), 81 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-acle-builtins.cc b/gcc/config/aarch64/aarch64-acle-builtins.cc
index a415cb3771b6..5dc736d30767 100644
--- a/gcc/config/aarch64/aarch64-acle-builtins.cc
+++ b/gcc/config/aarch64/aarch64-acle-builtins.cc
@@ -2982,22 +2982,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 0852c0391a78..bcc833cfaa14 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 61562c94a553..1d7d6fa6a2a9 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"
@@ -2331,72 +2332,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.  */
 
@@ -4502,6 +4437,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.  */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.