http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57503
Georg-Johann Lay <gjl at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |NEW --- Comment #8 from Georg-Johann Lay <gjl at gcc dot gnu.org> --- (In reply to Richard Biener from comment #7) > Can you please investigate the behavior on current trunk and the top of the > 4.8 branch? Using the code from comment #7 the problem persists $ avr-gcc -S -Os pr57503.c -mmcu=atmega8 -dP long func1 (unsigned char a, unsigned char b, int c) { unsigned ab = a * b; return (long) ab * c; } The code is a bit different but still wrong: func1: ; (insn 10 5 25 (set (reg:HI 18 r18 [orig:44 D.1450 ] [44]) ; (mult:HI (zero_extend:HI (reg:QI 24 r24 [ a ])) ; (zero_extend:HI (reg/v:QI 22 r22 [orig:50 b ] [50])))) pr57503.c:4 168 {umulqihi3} ; (expr_list:REG_DEAD (reg:QI 24 r24 [ a ]) ; (expr_list:REG_DEAD (reg/v:QI 22 r22 [orig:50 b ] [50]) ; (nil)))) mul r24,r22 ; 10 umulqihi3 [length = 3] movw r18,r0 clr __zero_reg__ ; (insn 25 10 26 (set (reg:HI 26 r26) ; (reg/v:HI 20 r20 [orig:51 c ] [51])) pr57503.c:5 82 {*movhi} ; (expr_list:REG_DEAD (reg/v:HI 20 r20 [orig:51 c ] [51]) ; (nil))) movw r26,r20 ; 25 *movhi/1 [length = 1] ; (insn 26 25 21 (set (reg:SI 22 r22) ; (mult:SI (sign_extend:SI (reg:HI 18 r18)) ; (sign_extend:SI (reg:HI 26 r26)))) pr57503.c:5 231 {*mulhisi3_call} ; (expr_list:REG_DEAD (reg:HI 26 r26) ; (expr_list:REG_DEAD (reg:HI 18 r18) ; (nil)))) rcall __mulhisi3 ; 26 *mulhisi3_call [length = 1] ; (jump_insn 31 21 30 (return) pr57503.c:6 451 {return} ; (nil) ; -> return) ret ; 31 return [length = 1] Insn 26 sign-extends both inputs but R18 (unsigned ab) should be zero-extended. Tested with SVN 203240 gcc version 4.9.0 20131007 (experimental) (GCC)