------- Comment #3 from jakub at gcc dot gnu dot org 2008-08-14 10:02 ------- Somewhat shorter: extern void abort (void);
unsigned int a, b = 1, c; void __attribute__ ((noinline)) foo (int x) { if (x != 5) abort (); } int main () { unsigned int d, e; for (d = 1; d < 5; d++) if (c) a = b; a = b; e = a << 1; if (e) e = (e << 1) ^ 1; foo (e); return 0; } At *.tailc looks sane to me. <bb 2>: pretmp.35_15 = c; b.1_5 = b; a_lsm.48_4 = a; if (pretmp.35_15 != 0) goto <bb 3>; else goto <bb 4>; <bb 3>: <bb 4>: # a_lsm.48_28 = PHI <b.1_5(3), a_lsm.48_4(2)> a = b.1_5; e_9 = b.1_5 << 1; if (e_9 != 0) goto <bb 5>; else goto <bb 6>; so a_lsm.48_28 is either b or a, depending on whether c != 0 or not, and a = b. Then copyrename4 decides to replace a = b.1_5; with a = a_lsm_48_5; and at *.uncprop we have: <bb 2>: pretmp.35_15 = c; a_lsm.48_5 = b; a_lsm.48_4 = a; if (pretmp.35_15 != 0) goto <bb 3>; else goto <bb 4>; <bb 3>: <bb 4>: # a_lsm.48_28 = PHI <a_lsm.48_5(3), a_lsm.48_4(2)> a = a_lsm.48_5; e_9 = a_lsm.48_5 << 1; if (e_9 != 0) goto <bb 5>; else goto <bb 6>; which looks correct too. But *.optimized is already wrong: <bb 2>: a_lsm.49 = b; a_lsm.48 = a; if (c != 0) goto <bb 3>; else goto <bb 7>; <bb 7>: a_lsm.49 = a_lsm.48; goto <bb 4>; <bb 3>: <bb 4>: a = a_lsm.49; e = a_lsm.49 << 1; if (e != 0) goto <bb 5>; else goto <bb 8>; While in *.uncprop a was set unconditionally to b, now it is sometimes b and sometimes a. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37102