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: [email protected]
ReportedBy: [email protected]
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.