http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46779
--- Comment #6 from Georg-Johann Lay <avr at gjlay dot de> 2011-02-23 15:51:11 UTC --- I can confirm the bug for gcc version 4.4.6 20110222 (prerelease) (GCC) In pass .168r.asmcons we have (insn 92 57 93 4 pr46779-1.c:17 (set (subreg:QI (reg/v:HI 85 [ w.30 ]) 1) (mem:QI (plus:HI (reg:HI 88 [ ivtmp.21 ]) (const_int 1 [0x1])) [0 S1 A8])) 4 {*movqi} (nil)) (insn 93 92 61 4 pr46779-1.c:17 (set (subreg:QI (reg/v:HI 85 [ w.30 ]) 0) (const_int 0 [0x0])) 4 {*movqi} (nil)) insn 93 invalidates insn 92. It accesses reg 85 as QI but doing so it invalidated the high part. This is due to subreg semantic. After IRA we have in .c.172r.ira: (insn 105 57 92 4 pr46779-1.c:17 (set (reg:HI 14 r14) (reg/v:HI 28 r28 [orig:85 w.30 ] [85])) 10 {*movhi} (nil)) (insn 92 105 107 4 pr46779-1.c:17 (set (reg:QI 22 r22) (mem:QI (plus:HI (reg:HI 26 r26 [orig:88 ivtmp.21 ] [88]) (const_int 1 [0x1])) [0 S1 A8])) 4 {*movqi} (nil)) (insn 107 92 106 4 pr46779-1.c:17 (set (reg:QI 15 r15 [+1 ]) (reg:QI 22 r22)) 4 {*movqi} (nil)) (insn 106 107 93 4 pr46779-1.c:17 (set (reg/v:HI 28 r28 [orig:85 w.30 ] [85]) (reg:HI 14 r14)) 10 {*movhi} (nil)) (insn 93 106 108 4 pr46779-1.c:17 (set (reg:QI 22 r22) (const_int 0 [0x0])) 4 {*movqi} (nil)) (insn 108 93 61 4 pr46779-1.c:17 (set (reg/v:HI 28 r28 [orig:85 w.30 ] [85]) (reg:HI 22 r22)) 10 {*movhi} (nil)) Now we see that insn 108 (from IRA/reload) overwrites the contents of reg 28. So in fact we see a bug similar to PR45291 which also originates in bad multiple subreg usage as Lvalue. The difference is that in 4.4 the bad subreg moves come from (define_insn_and_split "*rotlhi3_8" (define_insn_and_split "*rotlsi3_16" (define_insn_and_split "*rotlsi3_8" (define_insn_and_split "*rotlsi3_24" whereas in 4.5 and 4.6 they come from avr.c:avr_rotate_bytes()