http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53986
Bug #: 53986 Summary: missing vrp on bit-mask test Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: vr...@gcc.gnu.org Consider the following test-case: ... /* { dg-do link } */ /* { dg-options "-O2" } */ /* Based on f3 from vrp63.c, but with switch instead of if-chain. */ extern void link_error (void); void f3 (int s) { if (s >> 3 == -2) /* s in range [ -16, -9]. */ ; else { /* s in range ~[-16, -9], so none of the case labels can be taken. */ switch (s) { case -16: case -12: case -9: link_error (); break; default: break; } } } int main () { return 0; } ... the switchconv dump shows that the switch is converted to a bit-test: ... ;; Function f3 (f3, funcdef_no=0, decl_uid=1710, cgraph_uid=0) beginning to process the following SWITCH statement (vrp72.c:18) : ------- switch (s_1(D)) <default: <L8>, case -16: <L2>, case -12: <L2>, case -9: <L2>> expanding as bit test is preferable Switch converted -------------------------------- f3 (int s) { _Bool D.1736; long unsigned int D.1735; long unsigned int D.1734; long unsigned int csui.1; _Bool D.1732; int D.1730; unsigned int D.1731; int D.1720; <bb 2>: D.1720_2 = s_1(D) >> 3; if (D.1720_2 == -2) goto <bb 5> (<L8>); else goto <bb 3>; <bb 3>: D.1730_6 = s_1(D) + 16; D.1731_7 = (unsigned int) D.1730_6; D.1732_8 = D.1731_7 > 7; if (D.1732_8 != 0) goto <bb 6> (<L9>); else goto <bb 7>; <bb 7>: D.1734_10 = (long unsigned int) D.1731_7; csui.1_9 = 1 << D.1734_10; D.1735_11 = csui.1_9 & 145; D.1736_12 = D.1735_11 != 0; if (D.1736_12 != 0) goto <bb 4> (<L2>); else goto <bb 8>; <bb 8>: <L9>: goto <bb 5> (<L8>); <L2>: link_error (); <L8>: return; } ... vrp doesn't manage to remove the path to function link_error. Test-case vrp63 uses 'if (s == -16 || s == -12 || s == -9)' instead of a switch. In that case, the path to link_error is removed. Btw, if the switch is not converted to a bit-test the path to link_error is also not removed by vrp, because it doesn't handle anti-ranges for switches.