From: Andrew Pinski <apin...@marvell.com> So the problem is even though there was a csneg with a zero_extend in the front, there was not one for csinv. This fixes it by extending that pattern.
OK? Bootstrapped and tested on aarch64-linux-gnu with no regressions. gcc/ChangeLog: PR target/101205 * config/aarch64/aarch64.md (csneg3_uxtw_insn): Rename to ... (*cs<neg_not_cs>3_uxtw_insn4): and extend to NEG_NOT. gcc/testsuite/ChangeLog: PR target/101205 * gcc.target/aarch64/csinv-neg-1.c: New test. --- gcc/config/aarch64/aarch64.md | 6 +- .../gcc.target/aarch64/csinv-neg-1.c | 112 ++++++++++++++++++ 2 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/csinv-neg-1.c diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index f12a0bebd3d..8cd259fca9c 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -4203,15 +4203,15 @@ (define_insn "*csinv3<mode>_insn" [(set_attr "type" "csel")] ) -(define_insn "csneg3_uxtw_insn" +(define_insn "*cs<neg_not_cs>3_uxtw_insn4" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (if_then_else:SI (match_operand 1 "aarch64_comparison_operation" "") - (neg:SI (match_operand:SI 2 "register_operand" "r")) + (NEG_NOT:SI (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 3 "aarch64_reg_or_zero" "rZ"))))] "" - "csneg\\t%w0, %w3, %w2, %M1" + "cs<neg_not_cs>\\t%w0, %w3, %w2, %M1" [(set_attr "type" "csel")] ) diff --git a/gcc/testsuite/gcc.target/aarch64/csinv-neg-1.c b/gcc/testsuite/gcc.target/aarch64/csinv-neg-1.c new file mode 100644 index 00000000000..e528883198d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/csinv-neg-1.c @@ -0,0 +1,112 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* +** inv1: +** cmp w0, 0 +** csinv w0, w1, w2, ne +** ret +*/ +unsigned long long +inv1(unsigned a, unsigned b, unsigned c) +{ + unsigned t = a ? b : ~c; + return t; +} + +/* +** inv1_local: +** cmp w0, 0 +** csinv w0, w1, w2, ne +** ret +*/ +unsigned long long +inv1_local(unsigned a, unsigned b, unsigned c) +{ + unsigned d = ~c; + unsigned t = a ? b : d; + return t; +} + +/* +** inv_zero1: +** cmp w0, 0 +** csinv w0, wzr, w1, ne +** ret +*/ +unsigned long long +inv_zero1(unsigned a, unsigned b) +{ + unsigned t = a ? 0 : ~b; + return t; +} + +/* +** inv_zero2: +** cmp w0, 0 +** csinv w0, wzr, w1, eq +** ret +*/ +unsigned long long +inv_zero2(unsigned a, unsigned b) +{ + unsigned t = a ? ~b : 0; + return t; +} + + +/* +** inv2: +** cmp w0, 0 +** csinv w0, w2, w1, eq +** ret +*/ +unsigned long long +inv2(unsigned a, unsigned b, unsigned c) +{ + unsigned t = a ? ~b : c; + return t; +} + +/* +** inv2_local: +** cmp w0, 0 +** csinv w0, w2, w1, eq +** ret +*/ +unsigned long long +inv2_local(unsigned a, unsigned b, unsigned c) +{ + unsigned d = ~b; + unsigned t = a ? d : c; + return t; +} + +/* +** neg1: +** cmp w0, 0 +** csneg w0, w1, w2, ne +** ret +*/ +unsigned long long +neg1(unsigned a, unsigned b, unsigned c) +{ + unsigned t = a ? b : -c; + return t; +} + + +/* +** neg2: +** cmp w0, 0 +** csneg w0, w2, w1, eq +** ret +*/ +unsigned long long +neg2(unsigned a, unsigned b, unsigned c) +{ + unsigned t = a ? -b : c; + return t; +} + +/* { dg-final { check-function-bodies "**" "" "" } } */ -- 2.27.0