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