On Mon, 8 Oct 2018, Michael Matz wrote:
> > Ok, but why is that not a bug?  The whole point of passing alignment to 
> > the movmem pattern is to let it generate code that takes advantage of 
> > the alignment.  So we get a missed optimization.
> 
> Only if you somewhere visibly add accesses to *i and *j.  Without them you 
> only have the "accesses" via memcpy, and as Richi says, those don't imply 
> any alignment requirements.  The i and j pointers might validly be char* 
> pointers in disguise and hence be in fact only 1-aligned.  I.e. there's 
> nothing in your small example program from which GCC can infer that those 
> two global pointers are in fact 2-aligned.

Well, it's not that simple. C11 6.3.2.3 p7 makes it undefined to form an
'int *' value that is not suitably aligned:

  A pointer to an object type may be converted to a pointer to a different
  object type. If the resulting pointer is not correctly aligned for the
  referenced type, the behavior is undefined.

So in addition to what you said, we should probably say that GCC decides
not to exploit this UB in order to allow code to round-trip pointer values
via arbitrary pointer types?


To put Michael's explanation in different words:

This is not obviously a bug, because static pointer type does not imply the
dynamic pointed-to type. The caller of 'f1' could look like

void call_f1(void)
{
  short ibuf[20] = {0}, jbuf[20] = {0};
  i = (void *) ibuf;
  j = (void *) jbuf;
  f1();
}

and it's valid to memcpy from jbuf to ibuf, memcpy does not "see" the
static pointer type, and works as if by dereferencing 'char *' pointers.
(although as mentioned above it's more subtly invalid when assigning to
i and j).

If 'f1' dereferences 'i', GCC may deduce that dynamic type of '*i' is 'int' and
therefore 'i' must be suitably aligned. But in absence of dereferences GCC
does not make assumptions about dynamic type and alignment.

Alexander

Reply via email to