https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115830
--- Comment #1 from Georg-Johann Lay <gjl at gcc dot gnu.org> --- Created attachment 58953 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58953&action=edit proposed patch: https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659422.html 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_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_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): Include it. (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. (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: New test.