http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49073
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-05-20 07:50:02 UTC --- I think the bug is fairly obviously in and_comparisons_1 (and also in or_comparisons_1), going through a PHI node needs to be done with lots of care. We have: <bb 3>: # i_1 = PHI <1(2), i_9(6)> # f_2 = PHI <0(2), f_10(6)> d_6 = a[i_1]; if (f_2 != 0) goto <bb 4>; else goto <bb 6>; <bb 4>: if (d_6 == 4) goto <bb 5>; else goto <bb 6>; <bb 5>: c.0_7 = c; c.1_8 = c.0_7 + 1; c = c.1_8; goto <bb 7>; <bb 6>: i_9 = i_1 + 1; f_10 = d_6 == 3; if (d_6 <= 6) goto <bb 3>; else goto <bb 7>; and_comparisons_1 is called here with f_2 != 0 and d_6 == 4, it sees that f_2 is a result of a PHI node, and performs as the comment says: /* If every argument to the PHI produces the same result when ANDed with the second comparison, we win. */ First PHI argument is 0, so it is 0 && d_6 == 4 then, and for the second case it mistakenly follows on the SSA_NAME argument of the PHI, so f_10 and d_6 == 4 and we recurse into and_comparisons_1 with d_6 == 3 and d_6 == 4, which is of course false. The bug is that each of the d_6's is from a different loop iteration. So I think we need to give up if PHI argument is an SSA_NAME which might be defined in a different iteration of a loop, probably some dominance checks between the bb the PHI is defined and bb where the SSA_NAME is defined.