------- Comment #3 from rguenth at gcc dot gnu dot org 2009-10-11 11:56 ------- The key is IMHO that the inner loop does not have its loop header copied. This confuses SCEV enough to think that a = (unsigned short)a is always executed. LIM is necessary to promote all the memory to SSA names, the interesting CHREC that gets wrong is
<bb 3>: .. a_lsm.6_18 = 0x0fffffff3; goto <bb 5>; <bb 4>: ... a.1_2 = a_lsm.6_15; D.2006_3 = (short unsigned int) a.1_2; a.2_4 = (unsigned int) D.2006_3; a_lsm.6_20 = a.2_4; <bb 5>: # a_lsm.6_15 = PHI <a_lsm.6_18(3), a_lsm.6_20(4)> ... a.1_1 = a_lsm.6_15; if (a.1_1 == 0) goto <bb 4>; else goto <bb 6>; <bb 6>: ... - # a_lsm.6_27 = PHI <a_lsm.6_15(5)> <bb 8>: - # a_lsm.6_28 = PHI <a_lsm.6_27(6)> - a = a_lsm.6_28; + a = 65523; where interestingly a_lsm.6_15 isn't computed wrong. Testcase, fails at -Os: extern void abort (void); unsigned int a; int b, c; void foo (void) { b = 0; do { for (a = -13; a == 0; a = (unsigned short)a) c = 1; b++; } while (b == 0); } int main () { foo (); if (a != -13) abort (); return 0; } -- rguenth at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |spop at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41497