GNU C version 4.0.0 20041205 (experimental) (avr) Loop variable gets widened to LONG instead of unsigned int (or perhaps even int). Seems we forgeot how big the target is?
Testcase: struct S19 { unsigned char i[19]; }; void init (struct S19 *p, int i) { int j; for (j = 0; j < 19; j++) p->i[j] = i + j; } tree dump: ;; Function init (init) init (p, i) { long unsigned int ivtmp.3; <bb 0>: ivtmp.3 = 0; <L0>:; ((unsigned char *) ivtmp.3 + &p->i[0])->i[0] = (unsigned char) ivtmp.3 + (unsigned char) (signed char) i; ivtmp.3 = ivtmp.3 + 1; if (ivtmp.3 != 19) goto <L0>; else goto <L2>; <L2>:; return; } Not surprisingly, backend code reflects long (SImode) decrement and compare : /* prologue: frame size=0 */ /* prologue end (size=0) */ movw r26,r24 ldi r18,lo8(0) ldi r19,hi8(0) ldi r20,hlo8(0) ldi r21,hhi8(0) .L2: movw r30,r26 add r30,r18 adc r31,r19 mov r24,r18 add r24,r22 st Z,r24 subi r18,lo8(-(1)) sbci r19,hi8(-(1)) sbci r20,hlo8(-(1)) sbci r21,hhi8(-(1)) cpi r18,lo8(19) cpc r19,__zero_reg__ cpc r20,__zero_reg__ cpc r21,__zero_reg__ brne .L2 /* epilogue: frame size=0 */ ret -- Summary: [AVR] Loop variable gets widened to LONG instead of int Product: gcc Version: 4.0.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: andrewhutchinson at cox dot net CC: gcc-bugs at gcc dot gnu dot org GCC host triplet: cygwin GCC target triplet: avr http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19835