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.

Reply via email to