https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115830
--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Georg-Johann Lay <g...@gcc.gnu.org>: https://gcc.gnu.org/g:07e5e054a1c579dec3e1ed2192992b2fea14ad40 commit r15-3286-g07e5e054a1c579dec3e1ed2192992b2fea14ad40 Author: Georg-Johann Lay <a...@gjlay.de> Date: Sun Aug 4 19:46:43 2024 +0200 AVR: target/115830 - Make better use of SREG.N and SREG.Z. This patch adds new CC modes CCN and CCZN for operations that set SREG.N, resp. SREG.Z and SREG.N. Add peephole2 patterns to generate new compute + branch insns that make use of the Z and N flags. Most of these patterns need their own asm output routines that don't do all the micro-optimizations that the ordinary outputs may perform, as the latter have no requirement to set CC in a usable way. We don't use cmpelim because it cannot provide scratch regs (which peephole2 can), and some of the patterns require a scratch reg, whereas the same operations that don't set REG_CC don't require a scratch. See the comments in avr.md for details. The existing add.for.cc* patterns are simplified as they no more cover QImode, which is handled in a separate QImode case. Apart from that, it adds 3 patterns for subtractions and one pattern for shift left, all for multi-byte cases (HI, PSI, SI). The add.for.cc* patterns now use CC[Z]Nmode, instead of the formerly abuse of CCmode. PR target/115830 gcc/ * config/avr/avr-modes.def (CCN, CCZN): New CC_MODEs. * config/avr/avr-protos.h (avr_cond_branch): New from ret_cond_branch. (avr_out_plus_set_N, avr_op8_ZN_operator, avr_cmp0_code) (avr_out_op8_set_ZN, avr_len_op8_set_ZN): New protos. (ccn_reg_rtx, cczn_reg_rtx): New declarations. * config/avr/avr.cc (avr_cond_branch): New from ret_cond_branch. (avr_cond_string): Add bool cc_overflow_unusable argument. (avr_print_operand) ['L']: Like 'j' but overflow unusable. ['K']: Like 'k' but overflow unusable. (avr_out_plus_set_ZN): Remove handling of QImode. (avr_out_plus_set_N, avr_op8_ZN_operator, avr_cmp0_code) (avr_out_op8_set_ZN, avr_len_op8_set_ZN): New functions. (avr_adjust_insn_length) [ADJUST_LEN_ADD_SET_N]: Hande case. (avr_class_max_nregs): All MODE_CCs occupy one hard reg. (avr_hard_regno_nregs): Same. (avr_hard_regno_mode_ok) [REG_CC]: Allow all MODE_CC. (pass_manager.h, context.h, tree-pass.h): Include them. (ccn_reg_rtx, cczn_reg_rtx): New GTY variables. (avr_init_expanders): Initialize them. (avr_option_override): Run peephole2 a second time. * config/avr/avr.md (adjust_len) [add_set_N]: New attr value. (ALLCC, HI_SI): New mode iterators. (CCname): New mode attribute. (eqnegtle, cmp_signed, op8_ZN): New code iterators. (swap, SWAP): New code attributes. (branch): Handle CCNmode and CCZNmode. Assimilate... (difficult_branch): ...this insn. (p1m1): Remove. (gen_add_for_<code>_<mode>): Adjust to CCNmode and CCZNmode. Use HISI as mode iterator. Extend peephole2s that produce them. (*add.for.eqne.<mode>): Extend to *add.for.cc[z]n.<mode>. (*ashift.for.ccn.<mode>): New insn and peephole2 to make them. (*sub.for.cczn.<mode>, *sub-extend<mode>.for.cczn.<mode>): New insns and peephole2s to make them. (*op8.for.cczn.<code>): New insn and peephole2 to make them. * config/avr/predicates.md (const_1_to_3_operand) (abs1_abs2_operand, signed_comparison_operator) (op8_ZN_operator): New predicates. gcc/testsuite/ * gcc.target/avr/pr115830-add.c: New test. * gcc.target/avr/pr115830-add-c.c: New test. * gcc.target/avr/pr115830-add-i.c: New test. * gcc.target/avr/pr115830-and.c: New test. * gcc.target/avr/pr115830-asl.c: New test. * gcc.target/avr/pr115830-asr.c: New test. * gcc.target/avr/pr115830-ior.c: New test. * gcc.target/avr/pr115830-lsr.c: New test. * gcc.target/avr/pr115830-asl32.c: New test. * gcc.target/avr/pr115830-sub.c: New test. * gcc.target/avr/pr115830-sub-ext.c: New test.