This is a minor tweak to do eq/ne comparisons one instruction shorter in the case where the compare target is unused after the comparison:
For 1: DEC R0 OR R0,R1 OR R0,R2 OR R0,R3 For -1: AND R0,R3 AND R0,R2 AND R0,R1 COM R0 The text peephole casesi+2 used 0xffff where -1 is the right canonical representation, e.g. the following source char c; unsigned int cmp_p (unsigned int x) { if (--x == 65535) c = 0; return x; } compiles with -S -Os -dP -fno-peephole to ; (insn 7 6 8 (parallel [ ; (set (cc0) ; (compare (reg/v:HI 24 r24 [orig:42 x ] [42]) ; (const_int -1 [0xffffffff]))) ; (clobber (reg:QI 18 r18)) ; ]) cmp.c:6 184 {*cmphi} ; (expr_list:REG_UNUSED (reg:QI 18 r18) ; (nil))) Fixed that, too. Test suite passes fine. Ok? Johann * config/avr/avr.md (peephole casesi+2): Use -1 instead of 65535. * config/avr/avr.c (avr_out_compare): Print shorter sequence for EQ/NE comparisons against +/-1 in the case of unused-after, non-ld-regs target.
Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 179191) +++ config/avr/avr.md (working copy) @@ -4119,7 +4119,7 @@ (define_peephole (parallel [(set (cc0) (compare (match_dup 0) - (const_int 65535))) + (const_int -1))) (clobber (match_operand:QI 1 "d_register_operand" ""))]) (set (pc) (if_then_else (ne (cc0) (const_int 0)) Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 179191) +++ config/avr/avr.c (working copy) @@ -3048,6 +3048,37 @@ avr_out_compare (rtx insn, rtx *xop, int if (plen) *plen = 0; + /* Comparisons == +/-1 and != +/-1 can be done similar to camparing + against 0 by ORing the bytes. This is one instruction shorter. */ + + if (!test_hard_reg_class (LD_REGS, xreg) + && compare_eq_p (insn) + && reg_unused_after (insn, xreg)) + { + if (xval == const1_rtx) + { + avr_asm_len ("dec %A0" CR_TAB + "or %A0,%B0", xop, plen, 2); + + if (n_bytes == 4) + avr_asm_len ("or %A0,%C0" CR_TAB + "or %A0,%D0", xop, plen, 2); + + return ""; + } + else if (xval == constm1_rtx) + { + if (n_bytes == 4) + avr_asm_len ("and %A0,%D0" CR_TAB + "and %A0,%C0", xop, plen, 2); + + avr_asm_len ("and %A0,%B0" CR_TAB + "com %A0", xop, plen, 2); + + return ""; + } + } + for (i = 0; i < n_bytes; i++) { /* We compare byte-wise. */