Add the missing combiner patterns for folding NOT+PTEST to NOTS when
they share the same GP.
gcc/ChangeLog:
* config/aarch64/aarch64-sve.md (*one_cmpl<mode>3_cc): New
combiner pattern.
(*one_cmpl<mode>3_ptest): Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/sve/acle/general/not_1.c: New test.
---
Bootstapped & regtested on aarch64-linux-gnu. OK for master?
Thanks,
Spencer
---
gcc/config/aarch64/aarch64-sve.md | 36 +++++++++++++++++++
.../aarch64/sve/acle/general/not_1.c | 22 ++++++++++++
2 files changed, 58 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c
diff --git a/gcc/config/aarch64/aarch64-sve.md
b/gcc/config/aarch64/aarch64-sve.md
index c5d3e8cd3b3..0f85cafa16a 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -3972,6 +3972,42 @@
"not\t%0.b, %1/z, %2.b"
)
+;; Predicated predicate inverse in which the flags are set in the same
+;; way as a PTEST.
+(define_insn "*one_cmpl<mode>3_cc"
+ [(set (reg:CC_NZC CC_REGNUM)
+ (unspec:CC_NZC
+ [(match_operand:VNx16BI 1 "register_operand" "Upa")
+ (match_operand 3)
+ (match_operand:SI 4 "aarch64_sve_ptrue_flag")
+ (and:PRED_ALL
+ (not:PRED_ALL
+ (match_operand:PRED_ALL 2 "register_operand" "Upa"))
+ (match_dup 3))]
+ UNSPEC_PTEST))
+ (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
+ (and:PRED_ALL (not:PRED_ALL (match_dup 2)) (match_dup 3)))]
+ "TARGET_SVE"
+ "nots\t%0.b, %1/z, %2.b"
+)
+
+;; Same, where only the flags result is interesting.
+(define_insn "*one_cmpl<mode>3_ptest"
+ [(set (reg:CC_NZC CC_REGNUM)
+ (unspec:CC_NZC
+ [(match_operand:VNx16BI 1 "register_operand" "Upa")
+ (match_operand 3)
+ (match_operand:SI 4 "aarch64_sve_ptrue_flag")
+ (and:PRED_ALL
+ (not:PRED_ALL
+ (match_operand:PRED_ALL 2 "register_operand" "Upa"))
+ (match_dup 3))]
+ UNSPEC_PTEST))
+ (clobber (match_scratch:PRED_ALL 0 "=Upa"))]
+ "TARGET_SVE"
+ "nots\t%0.b, %1/z, %2.b"
+)
+
;; =========================================================================
;; == Binary arithmetic
;; =========================================================================
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c
b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c
new file mode 100644
index 00000000000..875d78885d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+
+void
+test1 (svbool_t pg, svbool_t x, int *any, svbool_t *ptr)
+{
+ svbool_t res = svnot_z (pg, x);
+ *any = svptest_last (pg, res);
+ *ptr = res;
+}
+
+int
+test2 (svbool_t pg, svbool_t x)
+{
+ svbool_t res = svnot_z (pg, x);
+ return svptest_first (pg, res);
+}
+
+/* { dg-final { scan-assembler-times {\tnots\t} 2 } } */
+/* { dg-final { scan-assembler-not {\tnot\t} } } */
--
2.34.1