https://gcc.gnu.org/g:00742daf6cac0ad10835ba0657d0f1a20bdf83db

commit r16-1505-g00742daf6cac0ad10835ba0657d0f1a20bdf83db
Author: Spencer Abson <spencer.ab...@arm.com>
Date:   Fri Jun 13 09:25:28 2025 +0000

    aarch64: Fold NOT+PTEST to NOTS [PR118150]
    
    Add combiner patterns for folding NOT+PTEST to NOTS when they share
    the same governing predicate.
    
    gcc/ChangeLog:
            PR target/118150
            * config/aarch64/aarch64-sve.md (*one_cmpl<mode>3_cc): New
            combiner pattern.
            (*one_cmpl<mode>3_ptest): Likewise.
    
    gcc/testsuite/ChangeLog:
            PR target/118150
            * gcc.target/aarch64/sve/acle/general/not_1.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64-sve.md                  | 37 ++++++++++++++++++++++
 .../gcc.target/aarch64/sve/acle/general/not_1.c    | 22 +++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-sve.md 
b/gcc/config/aarch64/aarch64-sve.md
index c5d3e8cd3b32..7cb13e73d0d4 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -3948,6 +3948,7 @@
 ;; -------------------------------------------------------------------------
 ;; Includes:
 ;; - NOT
+;; - NOTS
 ;; -------------------------------------------------------------------------
 
 ;; Unpredicated predicate inverse.
@@ -3972,6 +3973,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 000000000000..875d78885d60
--- /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} } } */

Reply via email to