http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49687
Summary: AVR: Missed optimization for widening MUL Product: gcc Version: 4.6.1 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: g...@gcc.gnu.org Target: avr With avr-gcc 4.6.1 and -Os -mmcu=atmega88 -S -dp int mul8_55 (char x) { return x * 55; } gets compiled to mul8_55: ldi r25,lo8(55) ; 7 *movqi/2 [length = 1] muls r24,r25 ; 8 mulqihi3 [length = 3] movw r24,r0 clr r1 ret ; 26 return [length = 1] which is fine. If the constant is 126, however, the result is bloated and might be related to PR36467, i.e. MUL* is better than shift. mul8_126: clr r25 ; 7 extendqihi2/1 [length = 3] sbrc r24,7 com r25 movw r18,r24 ; 28 *movhi/1 [length = 1] lsl r18 ; 33 *ashlhi3_const/2 [length = 2] rol r19 lsr r25 ; 34 *ashlhi3_const/5 [length = 5] mov r25,r24 clr r24 ror r25 ror r24 sub r24,r18 ; 12 subhi3/1 [length = 2] sbc r25,r19 ret ; 31 return [length = 1] If the constant is 155, a MUL is invented, but a widening MUL would be smarter: mul8_155: mov r20,r24 ; 6 extendqihi2/2 [length = 4] clr r21 sbrc r20,7 com r21 ldi r18,lo8(155) ; 7 *movhi/4 [length = 2] ldi r19,hi8(155) mul r20,r18 ; 8 *mulhi3_enh [length = 7] movw r24,r0 mul r20,r19 add r25,r0 mul r21,r18 add r25,r0 clr r1 ret ; 26 return [length = 1]