https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102546
Aldy Hernandez <aldyh at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |aldyh at gcc dot gnu.org, | |amacleod at redhat dot com --- Comment #2 from Aldy Hernandez <aldyh at gcc dot gnu.org> --- By VRP1 we seem to be calculating the following: (f_8 << f_8) && (f_8 == 0) This would fold to false, which would elide the foo(): <bb 7> [local count: 59055800]: b = 0; _3 = f_8 << f_8; _4 = (char) _3; _5 = (int) _4; if (_4 > 0) goto <bb 8>; [64.06%] else goto <bb 10>; [35.94%] <bb 8> [local count: 34842922]: if (f_8 == 0) goto <bb 9>; [71.10%] else goto <bb 10>; [28.90%] <bb 9> [local count: 12809203]: foo (); So from the outset, it seems like this is a missing relation in range-ops. That is if we know f_8 << f_8 is non-zero, then we know f_8 cannot be 0. This looks like an easy fix, however... What I fail to see is how "a" got removed entirely from the IL, making this scenario possible: if (!(a >= d || f)) foo(); Am I missing something obvious here?