https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67213
--- Comment #5 from Fredrik Hederstierna <fredrik.hederstie...@securitas-direct.com> --- Still same in GCC-7.1.0. I analyzed using -fdump-tree-cunroll-details void test_iter_6(void) { int i; for (i = 0; i < 6; i++) { data[i] = i; } } The function was generated "test_iter_6": 0000001c <test_iter_6>: 1c: e59f3030 ldr r3, [pc, #48] ; 54 <test_iter_6+0x38> 20: e3a02000 mov r2, #0 24: e5c32000 strb r2, [r3] 28: e3a02001 mov r2, #1 2c: e5c32001 strb r2, [r3, #1] 30: e3a02002 mov r2, #2 34: e5c32002 strb r2, [r3, #2] 38: e3a02003 mov r2, #3 3c: e5c32003 strb r2, [r3, #3] 40: e3a02004 mov r2, #4 44: e5c32004 strb r2, [r3, #4] 48: e3a02005 mov r2, #5 4c: e5c32005 strb r2, [r3, #5] 50: e12fff1e bx lr 54: 00000000 .word 0x00000000 With "--param max-completely-peel-times=4" (instead of default 5) it became 0000001c <test_iter_6>: 1c: e59f2014 ldr r2, [pc, #20] ; 38 <test_iter_6+0x1c> 20: e3a03000 mov r3, #0 24: e7c33002 strb r3, [r3, r2] 28: e2833001 add r3, r3, #1 2c: e3530006 cmp r3, #6 30: 1afffffb bne 24 <test_iter_6+0x8> 34: e12fff1e bx lr 38: 00000000 .word 0x00000000 It seems like "try_unroll_loop_completely()" in file "tree-ssa-loop-ivcanon.c" think it could fold counting variable, but maybe its not possible since its used as both index and as RHS value? ;; Function test_iter_6 (test_iter_6, funcdef_no=1, decl_uid=4067, cgraph_uid=1) Analyzing # of iterations of loop 1 exit condition [5, + , 4294967295] != 0 bounds on difference of bases: -5 ... -5 result: # of iterations 5, bounded by 5 Analyzing # of iterations of loop 1 exit condition [5, + , 4294967295] != 0 bounds on difference of bases: -5 ... -5 result: # of iterations 5, bounded by 5 Statement (exit)if (ivtmp_7 != 0) is executed at most 5 (bounded by 5) + 1 times in loop 1. Induction variable (int) 0 + 1 * iteration does not wrap in statement data[i_9] = _4; in loop 1. Statement data[i_9] = _4; is executed at most 9 (bounded by 9) + 1 times in loop 1. Induction variable (int) 1 + 1 * iteration does not wrap in statement i_6 = i_9 + 1; in loop 1. Statement i_6 = i_9 + 1; is executed at most 2147483646 (bounded by 2147483646) + 1 times in loop 1. Loop 1 iterates 5 times. Loop 1 iterates at most 5 times. Estimating sizes for loop 1 BB: 3, after_exit: 0 size: 0 _4 = (char) i_9; Induction variable computation will be folded away. size: 1 data[i_9] = _4; size: 1 i_6 = i_9 + 1; Induction variable computation will be folded away. size: 1 ivtmp_7 = ivtmp_1 - 1; Induction variable computation will be folded away. size: 2 if (ivtmp_7 != 0) Exit condition will be eliminated in peeled copies. BB: 4, after_exit: 1 size: 5-4, last_iteration: 5-2 Loop size: 5 Estimated size after unrolling: 5 Though produced code with peeling become test_iter_6 () { int i; char _4; unsigned int ivtmp_7; char _12; unsigned int ivtmp_15; char _19; unsigned int ivtmp_22; char _26; unsigned int ivtmp_29; char _33; unsigned int ivtmp_36; char _40; unsigned int ivtmp_43; <bb 2>: _12 = 0; data[0] = _12; i_14 = 1; ivtmp_15 = 5; _19 = (char) i_14; data[i_14] = _19; i_21 = i_14 + 1; ivtmp_22 = ivtmp_15 + 4294967295; _26 = (char) i_21; data[i_21] = _26; i_28 = i_21 + 1; ivtmp_29 = ivtmp_22 + 4294967295; _33 = (char) i_28; data[i_28] = _33; i_35 = i_28 + 1; ivtmp_36 = ivtmp_29 + 4294967295; _40 = (char) i_35; data[i_35] = _40; i_42 = i_35 + 1; ivtmp_43 = ivtmp_36 + 4294967295; _4 = (char) i_42; data[i_42] = _4; i_6 = i_42 + 1; ivtmp_7 = ivtmp_43 + 4294967295; return; } instead of original and shorter test_iter_6 () { int i; unsigned int ivtmp_1; char _4; unsigned int ivtmp_7; <bb 2>: <bb 3>: # i_9 = PHI <i_6(4), 0(2)> # ivtmp_1 = PHI <ivtmp_7(4), 6(2)> _4 = (char) i_9; data[i_9] = _4; i_6 = i_9 + 1; ivtmp_7 = ivtmp_1 - 1; if (ivtmp_7 != 0) goto <bb 4>; else goto <bb 5>; <bb 4>: goto <bb 3>; <bb 5>: return; } Could it be that somewhat since that index also is used as data that variable cannot be folded away like size: 1 i_6 = i_9 + 1; Induction variable computation will be folded away.