@@ -4549,7 +4549,7 @@ (define_insn "aarch64_<crc_variant>"
(define_insn "*csinc2<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r")
(plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
- (match_operand:GPI 1 "register_operand" "r")))]
+ (match_operand:GPI 1 "general_operand" "r")))]
""
"cinc\\t%<w>0, %<w>1, %m2"
[(set_attr "type" "csel")]
new file mode 100644
@@ -0,0 +1,11 @@
+/* { dg-options "-O2" } */
+/* PR target/112304 */
+
+int f(int a)
+{
+ return (a!=0)+42;
+}
+
+/* This function should produce a cinc with a mov instead of a cset with an add. */
+/* { dg-final { scan-assembler-not "cset\t" } } */
+/* { dg-final { scan-assembler "cinc\t" } } */
On many cores, the mov instruction is "free" so the sequence: cmp w0, #0 cset w0, ne add w0, w0, 42 is more expensive than just: cmp w0, #0 mov w1, #42 cinc w0, w1, ne The reason why we get the add case is that the pattern csinc2<mode>_insn only accepts registers for the predicate and we so we don't get an cinc without that. The small change to the predicate of using general_operand instead allows the combine to match and then the mov is generated with the register allocator checks the constraints. Built and tested on aarch64-linux-gnu with no regressions. PR target/112304 gcc/ChangeLog: * config/aarch64/aarch64.md (*csinc2<mode>_insn): Change the predicate of the 1st operand to general_operand. gcc/testsuite/ChangeLog: * gcc.target/aarch64/cinc-2.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com> --- gcc/config/aarch64/aarch64.md | 2 +- gcc/testsuite/gcc.target/aarch64/cinc-2.c | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/cinc-2.c