http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54810
Bug #: 54810
Summary: VRP doesn't handle comparison of narrowing cast like
comparison of BIT_AND_EXPR
Classification: Unclassified
Product: gcc
Version: 4.8.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: tree-optimization
AssignedTo: [email protected]
ReportedBy: [email protected]
struct S
{
unsigned long w;
void (*u) (void *, unsigned int, unsigned int);
};
struct T;
typedef void (*a_t) (struct T *);
typedef void (*b_t) (struct T *);
struct T
{
a_t a;
b_t b;
struct S c;
int d, e, f;
};
_Bool fn1 (struct T *, unsigned int);
int fn2 (struct T *, unsigned int, void *, unsigned long);
int fn3 (struct T *, unsigned int, unsigned int *);
static _Bool
foo (struct T *x, unsigned int y, unsigned int z)
{
unsigned int i;
for (i = 0; i < z; i++)
if (!fn1 (x, y + i))
return 0;
return 1;
}
int
bar (struct T *x, unsigned int y, void *z, unsigned long s)
{
unsigned long w = x->c.w;
unsigned long q = s / w;
unsigned int v;
int r, i;
if (s % x->c.w)
return -22;
if (y % x->d)
return -22;
x->a (x);
if (foo (x, y, q) || x->f || x->e == 0)
r = fn2 (x, y, z, s);
else
for (i = 0; i < q; i++)
{
r = fn3 (x, y + (i * x->d), &v);
if (r != 0)
break;
x->c.u (z + (i * w), v, 0);
}
x->b (x);
return r;
}
reports at -O2 -Wall maybe uninitialized warning. While generally it is IMHO
an acceptable false positive, especially if foo doesn't get inlined, this
testcase lead to me find out that while we handle
_7 = _4 & 0xffff;
if (_7 == 0)
goto bbX;
by adding ASSERT_EXPRs for _4 (in the _7 != 0 code _4 is known to be non-zero,
in the _7 == 0 code it can e.g. have [0, 0xffff0000] range), we don't handle
_7 = (unsigned short) _4;
if (_7 == 0)
goto bbX;
the same way.