Hi all, Currently for code: int foo (unsigned a, unsigned b) { int r = 0; r = a & b; if (a & b) return ++ r; return r; }
we generate: foo: and w0, w0, w1 cmp w0, wzr csinc w0, wzr, w0, eq retIf we relax the csinc and similar patterns to accept the CC_Z and CC_NZ codes we can improve this to:
foo: ands w0, w0, w1 csinc w0, wzr, w0, eq ret Bootstrapped and tested on aarch64-linux Ok for trunk? 2014-08-15 Kyrylo Tkachov <kyrylo.tkac...@arm.com> * config/aarch64/iterators.md (CC_ZERO): New iterator. * config/aarch64/aarch64.md (*csinc2<mode>_insn): Use CC_ZERO iterator on operand 3. Rename to... (*csinc2<mode>_<CC_ZERO:mode>_insn): ...This. (csinc3<mode>_insn): Use CC_ZERO iterator on operand 2. Rename to... (csinc3<GPI:mode>_<CC_ZERO:mode>_insn): ...This. (*csinv3<mode>_insn): Use CC_ZERO iterator on operand 2. Rename to... (*csinv3<GPI:mode>_<CC_ZERO:mode>_insn): ... This. (*csneg3<mode>_insn): Use CC_ZERO iterator on operand 2. Rename to... (*csneg3<GPI:mode>_<CC_ZERO:mode>_insn): ... This. (ffs<mode>2): Update gen_csinc3<mode>_cc_insn callsite.
commit 73e76eff0f99eff8d2a6b40ac4ea662a98c7c45d Author: Kyrylo Tkachov <kyrylo.tkac...@arm.com> Date: Mon Aug 4 16:49:24 2014 +0100 [AArch64] Use CC_NZ in csinc pattern diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 3c51fd3..568059d 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2596,21 +2596,21 @@ (define_insn "aarch64_<crc_variant>" [(set_attr "type" "crc")] ) -(define_insn "*csinc2<mode>_insn" +(define_insn "*csinc2<mode>_<CC_ZERO:mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator" - [(match_operand:CC 3 "cc_register" "") (const_int 0)]) + [(match_operand:CC_ZERO 3 "cc_register" "") (const_int 0)]) (match_operand:GPI 1 "register_operand" "r")))] "" "csinc\\t%<w>0, %<w>1, %<w>1, %M2" [(set_attr "type" "csel")] ) -(define_insn "csinc3<mode>_insn" +(define_insn "csinc3<GPI:mode>_<CC_ZERO:mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (if_then_else:GPI (match_operator:GPI 1 "aarch64_comparison_operator" - [(match_operand:CC 2 "cc_register" "") (const_int 0)]) + [(match_operand:CC_ZERO 2 "cc_register" "") (const_int 0)]) (plus:GPI (match_operand:GPI 3 "register_operand" "r") (const_int 1)) (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))] @@ -2619,11 +2619,11 @@ (define_insn "csinc3<mode>_insn" [(set_attr "type" "csel")] ) -(define_insn "*csinv3<mode>_insn" +(define_insn "*csinv3<GPI:mode>_<CC_ZERO:mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (if_then_else:GPI (match_operator:GPI 1 "aarch64_comparison_operator" - [(match_operand:CC 2 "cc_register" "") (const_int 0)]) + [(match_operand:CC_ZERO 2 "cc_register" "") (const_int 0)]) (not:GPI (match_operand:GPI 3 "register_operand" "r")) (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))] "" @@ -2631,11 +2631,11 @@ (define_insn "*csinv3<mode>_insn" [(set_attr "type" "csel")] ) -(define_insn "*csneg3<mode>_insn" +(define_insn "*csneg3<GPI:mode>_<CC_ZERO:mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (if_then_else:GPI (match_operator:GPI 1 "aarch64_comparison_operator" - [(match_operand:CC 2 "cc_register" "") (const_int 0)]) + [(match_operand:CC_ZERO 2 "cc_register" "") (const_int 0)]) (neg:GPI (match_operand:GPI 3 "register_operand" "r")) (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))] "" @@ -2896,7 +2896,7 @@ (define_expand "ffs<mode>2" emit_insn (gen_rbit<mode>2 (operands[0], operands[1])); emit_insn (gen_clz<mode>2 (operands[0], operands[0])); - emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx)); + emit_insn (gen_csinc3<mode>_cc_insn (operands[0], x, ccreg, operands[0], const0_rtx)); DONE; } ) diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 3203c3d..fe39768 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -191,6 +191,9 @@ (define_mode_iterator VMUL [V4HI V8HI V2SI V4SI V2SF V4SF V2DF]) ;; Modes available for <f>mul lane operations changing lane count. (define_mode_iterator VMUL_CHANGE_NLANES [V4HI V8HI V2SI V4SI V2SF V4SF]) +;; Iterator over CC, CC_Z, CC_NZ +(define_mode_iterator CC_ZERO [CC CC_Z CC_NZ]) + ;; ------------------------------------------------------------------ ;; Unspec enumerations for Advance SIMD. These could well go into ;; aarch64.md but for their use in int_iterators here.