https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85640
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P2 --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- Looking at trunk we have # RANGE [1, 5552] NONZERO 8191 # iftmp.2_14 = PHI <5552(6), len_29(5)> # prephitmp_53 = PHI <_52(6), 0(5)> _36 = (sizetype) iftmp.2_14; _37 = buf_11 + _36; <bb 8> [local count: 1073741824]: # buf_12 = PHI <buf_11(7), buf_21(11)> ... <bb 9> [local count: 118111601]: # _17 = PHI <_6(8)> # _59 = PHI <_8(8)> _46 = iftmp.2_14 + 4294967295; _45 = (sizetype) _46; _44 = _45 + 1; buf_47 = buf_11 + _44; where the final-value replacement failed to elide the +-1 dance because sizetype _45; unsigned int _46; IVOPTs is using tree-affine which performs some extra tricks such as using range-info to prove it can elide the casts. I think if we teach the same to SCEV we'd get it optimized again. I'm talking about /* If inner type has wrapping overflow behavior, fold conversion for below case: (T1)(X - CST) -> (T1)X - (T1)CST if X - CST doesn't overflow by range information. Also handle (T1)(X + CST) as (T1)(X - (-CST)). */ if (TYPE_UNSIGNED (itype) ... Note that the plan is to remove the unconditional final-value replacement and integrate it into passes that would benefit - first of all DCE which can trigger it if the IV (or the whole loop) can be eliminated.