This patch adds an alternative to addhi3_zero_extend for the case where output operand and the 8-bit addend happen to reside the the same register. Without the patch this might lead to additional reloads to satisfy the constraints like
uint16_t func (uint8_t x, uint16_t y) { return x + y; } Without the new alternative the code will be func: movw r18,r22 ; 18 *movhi/1 [length = 1] add r18,r24 ; 13 *addhi3_zero_extend [length = 2] adc r19,__zero_reg__ movw r24,r18 ; 19 *movhi/1 [length = 1] /* epilogue start */ ret With the change the code reads func: add r24,r22 ; 13 *addhi3_zero_extend/2 [length = 3] mov r25,r23 adc r25,__zero_reg__ /* epilogue start */ ret which has smaller code size and register pressure. Ok for trunk? Johann * config/avr/avr.md (*addhi3_zero_extend): Add alternative where REGNO($0) == REGNO($1).
Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 244001) +++ config/avr/avr.md (working copy) @@ -1200,12 +1200,14 @@ (define_expand "add<mode>3" (define_insn "*addhi3_zero_extend" - [(set (match_operand:HI 0 "register_operand" "=r") - (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) - (match_operand:HI 2 "register_operand" "0")))] + [(set (match_operand:HI 0 "register_operand" "=r,*?r") + (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0")) + (match_operand:HI 2 "register_operand" "0 ,r")))] "" - "add %A0,%1\;adc %B0,__zero_reg__" - [(set_attr "length" "2") + "@ + add %A0,%1\;adc %B0,__zero_reg__ + add %A0,%A2\;mov %B0,%B2\;adc %B0,__zero_reg__" + [(set_attr "length" "2,3") (set_attr "cc" "set_n")]) (define_insn "*addhi3_zero_extend1"