https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99364
Bug ID: 99364 Summary: Regression: loops not optimized to count to 0/-1 Product: gcc Version: tree-ssa Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: stefan at franke dot ms Target Milestone: --- consider this simple loop: ``` void ArrayFill2(int *array, int len) { int i = 0; for(; i < len; ++i) array[i] = 50; } ``` gcc 2.93 was able to convert this into a loop counting to zero. gcc 6/7/8/9/10/11 can't do that. if you change the code above: ``` void ArrayFill2(int *array) { int i = 0; int len = 42; for(; i < len; ++i) array[i] = 50; } ``` then it works and you get this after ivcanon: ``` int i; unsigned int i.0_4; unsigned int _5; int * _7; unsigned int ivtmp_15; unsigned int ivtmp_16; <bb 2>: <bb 3>: # i_13 = PHI <i_9(4), 0(2)> # ivtmp_16 = PHI <ivtmp_15(4), 42(2)> i.0_4 = (unsigned int) i_13; _5 = i.0_4 * 4; _7 = array_6(D) + _5; *_7 = 50; i_9 = i_13 + 1; ivtmp_15 = ivtmp_16 - 1; if (ivtmp_15 != 0) goto <bb 4>; else goto <bb 5>; <bb 4>: goto <bb 3>; <bb 5>: return; ``` so the expected result for the version above, with len as parameter would be something like this where the constant loop count is replaced by len-1: ``` int i; unsigned int i.0_4; unsigned int _5; int * _7; int ivtmp_14 unsigned int ivtmp_15; unsigned int ivtmp_16; <bb 2>: ivtmp_14 = len_4(D) - 1; <bb 3>: # i_13 = PHI <i_9(4), 0(2)> # ivtmp_16 = PHI <ivtmp_15(4), ivtmp_14(2)> i.0_4 = (unsigned int) i_13; _5 = i.0_4 * 4; _7 = array_6(D) + _5; *_7 = 50; i_9 = i_13 + 1; ivtmp_15 = ivtmp_16 - 1; if (ivtmp_15 != 0) goto <bb 4>; else goto <bb 5>; <bb 4>: goto <bb 3>; <bb 5>: return; ``` To handle this tree-ssa-loop-ivcanon must be able to handle no only const_int loop limits but also a const loop limit provided in a variable.