http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59387
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Seems it is SCCP that breaks this. We have a loop like: <bb 4>: c.2_10 = (unsigned char) c_lsm.11_20; _11 = c.2_10 + 255; c.3_12 = (char) _11; _14 = b_f1_lsm.12_7 + 1; <bb 5>: # c_lsm.11_20 = PHI <c_lsm.11_15(3), c.3_12(4)> # b_f1_lsm.12_7 = PHI <0(3), _14(4)> if (b_f1_lsm.12_7 <= 23) goto <bb 4>; else goto <bb 6>; <bb 6>: # b_f1_lsm.12_36 = PHI <b_f1_lsm.12_7(5)> # c_lsm.11_40 = PHI <c_lsm.11_20(5)> where c.2/c.3/c_lsm.11 is signed char. Note the c decrement done carefully in unsigned char type. But then comes sccp and does: final value replacement: c_lsm.11_40 = PHI <c_lsm.11_20(5)> with c_lsm.11_40 = c_lsm.11_15 + -24; which is invalid, because it is subtracted in signed type instead of the unsigned type originally. Dunno if scev remembers somewhere what type the arithmetics has been actually performed in. Richard, can you please have a look?