http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29560
Georg-Johann Lay <gjl at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |FIXED Known to fail|4.7.0 | --- Comment #11 from Georg-Johann Lay <gjl at gcc dot gnu.org> 2011-08-10 09:19:49 UTC --- Closed as FIXED for 4.7.0 trunk with patch from comment #10. The test case from attachment 24816 compiles with -Os -dp to: shift1: rjmp 2f ; 22 *ashlqi3/1 [length = 5] 1: lsl r24 2: dec r22 brpl 1b ret ; 27 return [length = 1] shift2: mov r25,r24 ; 19 *movqi/1 [length = 1] rjmp 2f ; 15 *ashlqi3/1 [length = 5] 1: lsl r25 2: dec r22 brpl 1b sts y,r25 ; 16 *movqi/3 [length = 2] ret ; 22 return [length = 1] setpin: in r25,44-0x20 ; 11 *movqi/4 [length = 1] ldi r18,lo8(1) ; 13 *movhi/4 [length = 2] ldi r19,hi8(1) mov r0,r24 ; 49 *ashlqi3/1 [length = 5] rjmp 2f 1: lsl r18 2: dec r0 brpl 1b cpi r22,lo8(1) ; 7 *cmpqi/3 [length = 1] brne .L4 ; 8 branch [length = 1] or r25,r18 ; 15 iorqi3/1 [length = 1] out 44-0x20,r25 ; 17 *movqi/3 [length = 1] ret ; 46 return [length = 1] .L4: com r18 ; 27 one_cmplqi2 [length = 1] and r18,r25 ; 28 andqi3/1 [length = 1] out 44-0x20,r18 ; 30 *movqi/3 [length = 1] ret ; 48 return [length = 1] Notice the *ashlqi3 insns. The fix uses combine patterns and an RTL peephole to transform 16-bit shift to 8-bit shift if applicable. There will be situations where optimization opportunities are not noticed, e.g. if a move occurs after the shift so that this move will get a REG_UNUSED note but not the shift loop itself. The fix just replaces 16-bit loop by 8-bit loop; there is no back-propagation of the information.