[PATCH 1/1] aarch64: Improve pfirst and brk* intrinsic folding

Dylan Rees <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
The fold method created for 'svbrk_unary_impl' to include some new
folding cases and the expand method was amended for 'svpfirst_svpnext_impl'
to optimise a specific case. Testcase expanded for 'brk*' folding and new
testsuite added for 'pfirst' to verify behaviour.

gcc/ChangeLog:

	* config/aarch64/aarch64-sve-builtins-base.cc: fold method
	created for 'svbrk_unary_impl'. Cases added for folding into
	'ptrue' and 'pfalse' where appropriate and not folding where
	unnecessary. Expand method of 'svpfirst_svpnext_impl' extended
	to handle specific case where 'ptrue' should be emitted but in
	a form where it can be recognised as a flag setting operation.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/sve/pr121604_brk.c: Test extended.
	* gcc.target/aarch64/sve/acle/general/pfirst_2.c: New test.
---
 .../aarch64/aarch64-sve-builtins-base.cc      |  29 +++
 .../aarch64/sve/acle/general/pfirst_2.c       |  67 +++++++
 .../gcc.target/aarch64/sve/pr121604_brk.c     | 169 ++++++++++++++++--
 3 files changed, 255 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/pfirst_2.c

diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 5d01d875a9d..b3dc6fbbdb3 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -346,6 +346,24 @@ class svbrk_unary_impl : public function_base
 public:
   constexpr svbrk_unary_impl (unspec unspec) : m_unspec (unspec) {}
 
+  gimple *
+  fold (gimple_folder &f) const override
+  {
+    unsigned int arg_offset = f.pred == PRED_m ? 1 : 0;
+    tree pg = gimple_call_arg (f.call, arg_offset);
+    tree pn = gimple_call_arg (f.call, arg_offset + 1);
+    if ((f.pred == PRED_z || f.pred == PRED_m)
+	&& is_ptrue (pg, f.type_suffix (0).element_bytes))
+      {
+	if (is_ptrue (pn, f.type_suffix (0).element_bytes))
+	  return (m_unspec == UNSPEC_BRKA
+	    ? f.fold_to_vl_pred (1) : f.fold_to_pfalse ());
+	else if (is_pfalse (pn))
+	  return f.fold_to_ptrue ();
+      }
+    return nullptr;
+  }
+
   rtx
   expand (function_expander &e) const override
   {
@@ -2565,6 +2583,17 @@ public:
   expand (function_expander &e) const override
   {
     machine_mode mode = e.vector_mode (0);
+    if (m_unspec == UNSPEC_PFIRST
+	&& rtx_equal_p (e.args[0], CONSTM1_RTX (mode))
+	&& rtx_equal_p (e.args[1], CONST0_RTX (mode)))
+      {
+	rtx pattern = gen_int_mode (AARCH64_SV_VL1, SImode);
+	rtvec vec = gen_rtvec (2, pattern, CONST0_RTX (mode));
+	rtx ptrue = gen_rtx_CONST (VNx16BImode,
+				   gen_rtx_UNSPEC (VNx16BImode, vec,
+						   UNSPEC_PTRUE));
+	return force_reg (VNx16BImode, ptrue);
+      }
     e.add_ptrue_hint (0, mode);
     return e.use_exact_insn (code_for_aarch64_sve (m_unspec, mode));
   }
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pfirst_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pfirst_2.c
new file mode 100644
index 00000000000..3fba71c4cd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pfirst_2.c
@@ -0,0 +1,67 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <arm_sve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void foo (svbool_t);
+extern void bar (svbool_t);
+
+/*
+** test1:
+**	b	bar
+*/
+__attribute__ ((noipa))
+void test1 (svbool_t a)
+{
+    svbool_t res = svpfirst (svpfalse (), svpfalse ());
+    if (svptest_any (res, a))
+      foo (a);
+    else
+      bar (a);
+}
+
+/*
+** test2:
+**	pfalse	p0\.b
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t test2 (svbool_t a)
+{
+    return svpfirst (svpfalse (), svpfalse ());
+}
+
+/*
+** test3:
+**	ptrues	p3.b, vl1
+**	...
+*/
+__attribute__ ((noipa))
+void test3 (svbool_t a)
+{
+    svbool_t res = svpfirst (svptrue_b8 (), svpfalse ());
+    if (svptest_first (svptrue_b8 (), res))
+      foo (a);
+    else
+      bar (a);
+}
+
+/*
+** test4:
+**	ptrue	p0.b, vl1
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t test4 (svbool_t a)
+{
+return svpfirst (svptrue_b8 (), svpfalse ());
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr121604_brk.c b/gcc/testsuite/gcc.target/aarch64/sve/pr121604_brk.c
index a474a20554d..ccb28d74833 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/pr121604_brk.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr121604_brk.c
@@ -5,21 +5,170 @@
 #include <arm_sve.h>
 
 /*
-** foo:
-**	ptrue	p0\.b, all
-**	brkb	p0\.b, p0/z, p0\.b
+** f1m:
+**	mov	p0.b, p1.b
 **	ret
 */
-svbool_t foo () {
-  return svbrkb_b_m (svpfalse (), svptrue_b8 (), svptrue_b8 ());
+__attribute__ ((noipa))
+svbool_t f1m (svbool_t a, svbool_t b)
+{
+    return svbrka_b_m (b, svpfalse_b(), a);
 }
 
 /*
-** bar:
-**	ptrue	p0\.b, all
-**	brka	p0\.b, p0/z, p0\.b
+** f1z:
+**	pfalse	p0.b
 **	ret
 */
-svbool_t bar () {
-  return svbrka_b_m (svpfalse (), svptrue_b8 (), svptrue_b8 ());
+__attribute__ ((noipa))
+svbool_t f1z (svbool_t a)
+{
+    return svbrka_b_z (svpfalse_b(), a);
 }
+
+/*
+** f2m:
+**	ptrue	p3.b, all
+**	brka	p1.b, p3/m, p0.b
+**	mov	p0.b, p1.b
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t f2m (svbool_t a, svbool_t b)
+{
+    return svbrka_b_m (b, svptrue_b8(), a);
+}
+
+/*
+** f2z:
+**	ptrue	p3.b, all
+**	brka	p0.b, p3/z, p0.b
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t f2z (svbool_t a)
+{
+    return svbrka_b_z (svptrue_b8(), a);
+}
+
+/*
+** f3z:
+**	ptrue	p0.b, vl1
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t f3z (svbool_t a)
+{
+    return svbrka_b_z (svptrue_b8(), svptrue_b8());
+}
+
+/*
+** f3m:
+**	ptrue	p3.b, all
+**	brka	p0.b, p3/m, p0.b
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t f3m (svbool_t a, svbool_t b)
+{
+    return svbrka_b_m (a, svptrue_b8(), a);
+}
+
+/*
+** f4m:
+**	ptrue	p0.b, vl1
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t f4m (svbool_t a)
+{
+    return svbrka_b_m (a, svptrue_b8(), svptrue_b8 ());
+}
+
+/*
+** f4z:
+**	ptrue	p0.b, all
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t f4z ()
+{
+    return svbrka_b_z (svptrue_b8(), svpfalse());
+}
+
+/*
+** g1z:
+**	pfalse	p0.b
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t g1z (svbool_t a)
+{
+    return svbrkb_b_z (svpfalse_b(), a);
+}
+
+/*
+** g1m:
+**	ptrue	p3.b, all
+**	brkb	p0.b, p3/z, p0.b
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t g1m (svbool_t a)
+{
+    return svbrkb_b_m (svpfalse_b(), svptrue_b8(), a);
+}
+
+/*
+** g2z:
+**	ptrue	p3.b, all
+**	brkb	p0.b, p3/z, p0.b
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t g2z (svbool_t a)
+{
+    return svbrkb_b_z (svptrue_b8(), a);
+}
+
+/*
+** g2m:
+**	ptrue	p0.b, all
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t g2m (svbool_t a)
+{
+    return svbrkb_b_m (a, svptrue_b8(), svpfalse ());
+}
+
+/*
+** g3m:
+**	pfalse	p0.b
+**	ret
+*/
+__attribute__ ((noipa))
+svbool_t g3m (svbool_t a)
+{
+    return svbrkb_b_m (a, svptrue_b8(), svptrue_b8 ());
+}
+
+int main ()
+{
+    svbool_t a = svptrue_pat_b16 (SV_VL4);
+    svbool_t b = svptrue_pat_b16 (SV_VL5);
+
+    f1m (a, b);
+    f1z (a);
+    f2m (a, b);
+    f2z (a);
+    f3m (a, b);
+    f3z (a);
+    f4m (a);
+    f4z ();
+    g1z (a);
+    g1m (a);
+    g2z (a);
+    g2m (a);
+    g3m (a);
+}
\ No newline at end of file
-- 
2.43.0
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.