]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
aarch64: Fold NOT+PTEST to NOTS [PR118150]
authorSpencer Abson <spencer.abson@arm.com>
Fri, 13 Jun 2025 09:25:28 +0000 (09:25 +0000)
committerSpencer Abson <spencer.abson@arm.com>
Fri, 13 Jun 2025 17:33:33 +0000 (17:33 +0000)
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.

gcc/config/aarch64/aarch64-sve.md
gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c [new file with mode: 0644]

index c5d3e8cd3b32bdaa4220680b96de345df5eb272f..7cb13e73d0d473d0a2394703ab82ebd977e66e08 100644 (file)
 ;; -------------------------------------------------------------------------
 ;; Includes:
 ;; - NOT
+;; - NOTS
 ;; -------------------------------------------------------------------------
 
 ;; Unpredicated predicate inverse.
   "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 (file)
index 0000000..875d788
--- /dev/null
@@ -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} } } */