http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53342
--- Comment #7 from Michael Matz <matz at gcc dot gnu.org> 2013-01-14 15:55:51 UTC --- The patch should lead to wrong code at some places (when peeling for alignment actually does something). The problem is, you calculate base and step before peeling and cache that. Caching the step is fine, but caching the base is not, as the peeling specifically changes the initial value of the accessed pointer. For instance in the testcase of pr53185.c we have this loop after peeling: bb_6 (preds = {bb_8 bb_26 }, succs = {bb_8 bb_23 }) { # .MEM_27 = PHI <.MEM_21(8), .MEM_51(26)> # e.1_29 = PHI <e.4_22(8), e.1_52(26)> _10 = (long unsigned int) e.1_29; _11 = _10 * 4; _12 = f_5(D) + _11; _14 = (int) e.1_29; _16 = _14 * pretmp_38; _17 = (long unsigned int) _16; _18 = _17 * 4; _19 = pretmp_35 + _18; # VUSE <.MEM_27> _20 = *_19; # .MEM_21 = VDEF <.MEM_27> *_12 = _20; e.4_22 = e.1_29 + 1; if (e.4_22 < a.5_26) goto <bb 8>; else goto <bb 23>; } Note the initial value of e.1_52 for e.1_29. But your cached information sets iv.base = pretmp_35 iv.step = (long unsigned int) pretmp_38 * 4 It actually should be iv.base = pretmp_35 + 4 * ((long unsigned int) (pretmp_38 * (int) e.1_52)) The casts here are actually the cause for simple_iv not working in this case. This expression would have to be calculated outside the loop and used as stride_base. I don't see where this could easily be done from existing places (like where the peeling loop is generated).