http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59999
--- Comment #16 from Paulo J. Matos <pa...@matos-sorge.com> --- (In reply to rguent...@suse.de from comment #15) > Exactly the same problem. C integral type promotion rules make > that i = (short)((int)i + 1) again. Note that (int)i + 1 > does not overflow, (short) ((int)i + 1) invokes implementation-defined > behavior which in our case is modulo-2 reduction. > > Nothing guarantees that (short)i + 1 does not overflow. OK, that makes sense. But in GCC 4.8 that doesn't seem to be what happens. It seems to be i = (short) ((unsigned short) i + 1) Later i is cast to int for comparison. Before ivopts this is the end of the loop body: i.7_19 = (unsigned short) i_26; _20 = i.7_19 + 1; i_21 = (short intD.8) _20; _10 = (intD.1) i_21; if (_10 < _25) goto <bb 7>; else goto <bb 6>; i is initially a short, then moved to unsigned short. The addition is performed and returned to short. Then cast to int for the comparison. For GCC 4.5.4 the end of loop body is: iD.2767_18 = iD.2767_26 + 1; D.5046_9 = (intD.0) iD.2767_18; if (D.5046_9 < D.5047_25) goto <bb 5>; else goto <bb 6>; Here the addition is made in short int and then there's only one cast to int.