https://gcc.gnu.org/g:3e4c47d1088417db599a0793a6d93707228e4f70
commit r15-2475-g3e4c47d1088417db599a0793a6d93707228e4f70 Author: Georg-Johann Lay <a...@gjlay.de> Date: Thu Aug 1 10:21:53 2024 +0200 AVR: Tweak unsigned comparisons against 256 resp. 65536. u16 >= 256 can be performed by testing the hi8 part against 0. u32 >= 65536 can be performed by testing the high word against 0. The optimization is performed in split2 after register allocation because the register allocator likely spills for subregs. gcc/ * config/avr/avr.md (cbranch<mode>4_insn): Split to a test of the high part against 0 if possible. Diff: --- gcc/config/avr/avr.md | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 02d0a4156513..fce5349bbe5f 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -6742,7 +6742,23 @@ (if_then_else (match_op_dup 0 [(reg:CC REG_CC) (const_int 0)]) (label_ref (match_dup 3)) - (pc)))]) + (pc)))] + { + // Unsigned >= 65536 and < 65536 can be performed by testing the + // high word against 0. + if ((GET_CODE (operands[0]) == LTU + || GET_CODE (operands[0]) == GEU) + && const_operand (operands[2], <MODE>mode) + && INTVAL (avr_to_int_mode (operands[2])) == 65536) + { + // "cmphi3" of the high word against 0. + operands[0] = copy_rtx (operands[0]); + PUT_CODE (operands[0], GET_CODE (operands[0]) == GEU ? NE : EQ); + operands[1] = simplify_gen_subreg (HImode, operands[1], <MODE>mode, 2); + operands[2] = const0_rtx; + operands[4] = gen_rtx_SCRATCH (QImode); + } + }) ;; "cbranchpsi4_insn" (define_insn_and_split "cbranchpsi4_insn" @@ -6787,7 +6803,23 @@ (if_then_else (match_op_dup 0 [(reg:CC REG_CC) (const_int 0)]) (label_ref (match_dup 3)) - (pc)))]) + (pc)))] + { + // Unsigned >= 256 and < 256 can be performed by testing the + // high byte against 0. + if ((GET_CODE (operands[0]) == LTU + || GET_CODE (operands[0]) == GEU) + && const_operand (operands[2], <MODE>mode) + && INTVAL (avr_to_int_mode (operands[2])) == 256) + { + rtx_code code = GET_CODE (operands[0]) == GEU ? NE : EQ; + rtx hi8 = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 1); + rtx cmp = gen_rtx_fmt_ee (code, VOIDmode, cc_reg_rtx, const0_rtx); + emit (gen_cmpqi3 (hi8, const0_rtx)); + emit (gen_branch (operands[3], cmp)); + DONE; + } + }) ;; Combiner pattern to compare sign- or zero-extended register against ;; a wider register, like comparing uint8_t against uint16_t.