Hi Omar, From: Omar Tahir <omar.ta...@arm.com> Sent: 04 August 2020 17:13 To: Kyrylo Tkachov <kyrylo.tkac...@arm.com>; ni...@redhat.com; Ramana Radhakrishnan <ramana.radhakrish...@arm.com>; Richard Earnshaw <richard.earns...@arm.com>; gcc-patches@gcc.gnu.org Subject: [PATCH 3/5][Arm] New pattern for CSINC instructions
This patch adds a new pattern, *thumb2_csinc, for generating CSINC instructions. It also modifies an existing pattern, *thumb2_cond_arith, to output CINC when the operation is an addition and TARGET_COND_ARITH is true. Regression tested on arm-none-eabi. 2020-07-30: Sudakshina Das <mailto:sudi....@arm.com> Omar Tahir <mailto:omar.ta...@arm.com> * config/arm/thumb2.md (*thumb2_csinc): New. (*thumb2_cond_arith): Generate CINC where possible. gcc/testsuite/ChangeLog: 2020-07-30: Sudakshina Das <mailto:sudi....@arm.com> Omar Tahir <mailto:omar.ta...@arm.com> * gcc.target/arm/csinc-1.c: New test. diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 0b00aef7ef7..79cf684e5cb 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -743,6 +743,9 @@ if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) return \"%i5\\t%0, %1, %2, lsr #31\"; + if (GET_CODE (operands[5]) == PLUS && TARGET_COND_ARITH) + return \"cinc\\t%0, %1, %d4\"; + output_asm_insn (\"cmp\\t%2, %3\", operands); Hmmm, this looks wrong. The pattern needs to perform the comparison (setting the CC reg) as well as do the conditional increment. Emitting a cinc without a cmp won't set the CC flags. Also, cinc increments only by 1, whereas the "arm_rhs_operand" predicate accepts a wider variety of immediates, so just checking for GET_CODE (operands[5]) == PLUS isn't enough. Thanks, Kyrill if (GET_CODE (operands[5]) == AND) { @@ -952,6 +955,21 @@ (set_attr "predicable" "no")] ) +(define_insn "*thumb2_csinc" + [(set (match_operand:SI 0 "arm_general_register_operand" "=r, r") + (if_then_else:SI + (match_operand 1 "arm_comparison_operation" "") + (plus:SI (match_operand:SI 2 "arm_general_register_operand" "r, r") + (const_int 1)) + (match_operand:SI 3 "reg_or_zero_operand" "r, Z")))] + "TARGET_COND_ARITH" + "@ + csinc\\t%0, %3, %2, %D1 + csinc\\t%0, zr, %2, %D1" + [(set_attr "type" "csel") + (set_attr "predicable" "no")] +) + (define_insn "*thumb2_movcond" [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts") (if_then_else:SI diff --git a/gcc/testsuite/gcc.target/arm/csinc-1.c b/gcc/testsuite/gcc.target/arm/csinc-1.c new file mode 100644 index 00000000000..b9928493862 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/csinc-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_arch_v8_1m_main_ok } */ +/* { dg-options "-O2 -march=armv8.1-m.main" } */ + +int +test_csinc32_condasn1(int w0, int w1, int w2, int w3) +{ + int w4; + + /* { dg-final { scan-assembler "csinc\tr\[0-9\]*.*ne" } } */ + w4 = (w0 == w1) ? (w2 + 1) : w3; + return w4; +} + +int +test_csinc32_condasn2(int w0, int w1, int w2, int w3) +{ + int w4; + + /* { dg-final { scan-assembler "csinc\tr\[0-9\]*.*eq" } } */ + w4 = (w0 == w1) ? w3 : (w2 + 1); + return w4; +}