http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53957
--- Comment #5 from rguenther at suse dot de <rguenther at suse dot de> 2012-07-18 13:18:13 UTC --- On Wed, 18 Jul 2012, burnus at gcc dot gnu.org wrote: > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53957 > > Tobias Burnus <burnus at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > CC| |burnus at gcc dot gnu.org > > --- Comment #4 from Tobias Burnus <burnus at gcc dot gnu.org> 2012-07-18 > 12:46:29 UTC --- > (In reply to comment #3) > > It would be better to have this similar to other loops I see, > > > > bool flag = end-value == i; > > i = i + 1; > > if (flag) goto loop_exit; > > That's not that simple as one might not reach the end value due to the step. > If > "step" is (plus or minus) unity and if one has integers (and not reals, added > in Fortran 77, deleted in Fortran 90), it is simple. > > But if abs(step) != 1 or if the loop variable is not an integer, one either > needs to calculate the number of trips beforehand, or has to use ">" or "<" > rather than "==". The problem with "<" / ">" is that one has to do another > comparison, unless the sign of "step" is known: > > if (step > 0 ? dovar > to : dovar < to) > goto exit_label; > > I don't see whether that version is better than the current version. > Suggestions or comments? > > > The current code is (comment from trans-stmt.c's gfc_trans_do): > > ------------<cut>----------------- > We translate a do loop from: > > DO dovar = from, to, step > body > END DO > > to: > > [evaluate loop bounds and step] > empty = (step > 0 ? to < from : to > from); > countm1 = (to - from) / step; > dovar = from; > if (empty) goto exit_label; > for (;;) > { > body; > cycle_label: > dovar += step > if (countm1 ==0) goto exit_label; > countm1--; > } > exit_label: > > countm1 is an unsigned integer. It is equal to the loop count minus one, > because the loop count itself can overflow. */ If you do > [evaluate loop bounds and step] > empty = (step > 0 ? to < from : to > from); > countm1 = (to - from) / step; > dovar = from; > if (empty) goto exit_label; > for (;;) > { > body; > cycle_label: > dovar += step exit = countm1 == 0; countm1--; > if (exit) goto exit_label; > } > exit_label: it would work for this case.