http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55481
--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> 2012-11-27 16:10:29 UTC --- The following even more reduced testcase is not fixed by the patch pending for PR35634. typedef signed char int8_t; #define SIZE 13 static inline int8_t do_shift() { return 31; } int main(int argc, char** argv) { int i; for(i = 0; i < 1000; ++i) { int8_t result = 0; int n; for (n = 0; n < SIZE; ++n) result += do_shift(); int8_t temp = (int8_t)((int8_t)SIZE * ((int8_t)(23) | (int8_t)(10))); if (result != temp) __builtin_abort (); } return 0; } With the C++ frontend we correctly do D.2194 = do_shift (); D.2207 = (int) result; D.2208 = (int) D.2194; D.2209 = D.2207 + D.2208; result = (int8_t) D.2209; anyway, but then IVOPTs comes around and changes it: <bb 4>: # result_17 = PHI <result_8(3), 0(7)> - # n_18 = PHI <n_9(3), 0(7)> - # ivtmp_12 = PHI <ivtmp_13(3), 13(7)> _6 = (int) result_17; _7 = _6 + 31; - result_8 = (int8_t) _7; - n_9 = n_18 + 1; - ivtmp_13 = ivtmp_12 - 1; - if (ivtmp_13 != 0) + _1 = result_17 + 31; + result_8 = _1; + if (result_8 != -109) goto <bb 3>; performing the computation in int8_t again which causes VRP to "miscompile" the test.