https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66933
Bug ID: 66933 Summary: [AVR] Shifted multiplication produces suboptimal asm Product: gcc Version: 5.2.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: a-gnu.org at 0au dot de Target Milestone: --- The function uint8_t test(uint8_t a, uint8_t b) { return (a*b) >> 7; } compiles into the following assembly, with e.g. avr-gcc -mmcu=atmega328 -S -O3 test.c (or any other optimization flag) test: mul r24,r22 movw r24,r0 clr __zero_reg__ lsl r24 mov r24,r25 rol r24 sbc r25,r25 ret This has two obvious possible enhancements: - It uses mul instead of fmul: fmul calculates (a*b)<<1, so the high byte is already the correct return value of the function - After calculating the return value (wih "rol r24"), there's an instruction "sbc r25, r25" that puts a completely unneeded value in r25, if I'm not mistaken it's 255 if (a*b) & 0x8000, else 0. A better version that uses 8 instead of 12 cycles would be test: fmul r24, r22 mov r24, r1 clr __zero_reg__ ret