[Bug tree-optimization/86884] aggressive loop optimization and effective type

2018-08-17 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86884

Richard Biener  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #2 from Richard Biener  ---
It's invalid in GIMPLE as well.  You are accessing the storage through p->c[n]
which constrains the accesses to the array size of c (it is not a trailing
array).

[Bug tree-optimization/86884] aggressive loop optimization and effective type

2018-08-11 Thread uecker at eecs dot berkeley.edu
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86884

Martin Uecker  changed:

   What|Removed |Added

 CC||uecker at eecs dot berkeley.edu

--- Comment #1 from Martin Uecker  ---
Here are some additional comments, which may help to analyze this (or not). 

The optimization also works without struct Y, the initialization, and the
memcpy in which case the example is not undefined by itself (see case 1 below).
From a C language point of view (I can't comment about GIMPLE), the
optimization seems legal as from the access p->c one can infer the effective
type. In case 3, one cannot infer the effective type and gcc also does not
optimize this case. Case 2 is interesting. I think using p->c to construct a
pointer to c implies that the storage at p must have correct effective type,
but I am not entirely sure. For strlen, case 1 and case 2 are optimized, but
not case 3. (tested with gcc from recent git). 

#include 
#include 
#include 

struct X { int i; char c[4]; int j;};

void f(struct X *p)
{
int n = 0;
#if 1
// case 1
while (p->c[n]) // uncond. abort
++n;
#else
#if 1
// case 2
char* pc = p->c; // no uncond. abort
#else
// case 3
char* pc = (char*)p + offsetof(struct X, c); // no uncond. abort
#endif
while (pc[n])
++n;
#endif
if (n < 7)
abort();
}

void g(struct X *p)
{
int n = 0;
#if 1
// case 1
n = strlen(p->c); // uncond. abort
#else
#if 1
// case 2
char* pc = p->c; // uncond. abort
#else
// case 3
char* pc = (char*)p + offsetof(struct X, c); // no uncond. abort
#endif
n = strlen(pc);
#endif
if (n < 7)
abort();
}