We can fold svbrka/b to pfalse, if the governing predicate and the operand
are both ptrue.
We implemented this optimization during gimple folding in
svbrk_unary_impl::fold.

The patch was bootstrapped and tested on aarch64-linux-gnu, no regression.
OK for trunk?

Signed-off-by: Jennifer Schmitz <jschm...@nvidia.com>

gcc/
        PR target/121604
        * config/aarch64/aarch64-sve-builtins-base.cc
        (svbrk_unary_impl::fold): Fold calls with ptrue predicate and
        operand to pfalse.

gcc/testsuite/
        PR target/121604
        * gcc.target/aarch64/sve/pr121604_brk.c: Adjust expected outcome.
---
 gcc/config/aarch64/aarch64-sve-builtins-base.cc     | 12 ++++++++++++
 gcc/testsuite/gcc.target/aarch64/sve/pr121604_brk.c |  6 ++----
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc 
b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index ecc06877cac..a2877533c42 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -346,6 +346,18 @@ class svbrk_unary_impl : public function_base
 public:
   CONSTEXPR svbrk_unary_impl (int unspec) : m_unspec (unspec) {}
 
+  gimple *
+  fold (gimple_folder &f) const override
+  {
+    /* If the predicate and operand are ptrue, fold to pfalse.  */
+    if (is_ptrue (gimple_call_arg (f.call, 1),
+                 f.type_suffix (0).element_bytes)
+       && is_ptrue (gimple_call_arg (f.call, 2),
+                    f.type_suffix (0).element_bytes))
+      return f.fold_call_to (build_zero_cst (TREE_TYPE (f.lhs)));
+    return NULL;
+  }
+
   rtx
   expand (function_expander &e) const override
   {
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr121604_brk.c 
b/gcc/testsuite/gcc.target/aarch64/sve/pr121604_brk.c
index a474a20554d..c1965b034cd 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/pr121604_brk.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr121604_brk.c
@@ -6,8 +6,7 @@
 
 /*
 ** foo:
-**     ptrue   p0\.b, all
-**     brkb    p0\.b, p0/z, p0\.b
+**     pfalse  p0\.b
 **     ret
 */
 svbool_t foo () {
@@ -16,8 +15,7 @@ svbool_t foo () {
 
 /*
 ** bar:
-**     ptrue   p0\.b, all
-**     brka    p0\.b, p0/z, p0\.b
+**     pfalse  p0\.b
 **     ret
 */
 svbool_t bar () {
-- 
2.34.1

Reply via email to