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