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} } } */