https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55177
--- Comment #17 from David Woodhouse <dwmw2 at infradead dot org> --- Er, yes. Sorry, I originally tried it with uint16_t but it wasn't even using movbe for the pointer_abuse() function then, so I made it 32-bit instead. Badly. Come to think of it, the lack of movbe in the 16-bit pointer_abuse() case is potentially another bug worth fixing. Here's the corrected test case. /* gcc -march=atom -O2 -c load_be.c -Wstrict-aliasing -o- -S */ struct pkt { unsigned char data[10]; }; unsigned or(struct pkt *p) { return (p->data[0] << 24) | (p->data[1] << 16) | (p->data[2] << 8) | p->data[3]; } unsigned add(struct pkt *p) { return (p->data[0] << 24) + (p->data[1] << 16) + (p->data[2] << 8) + p->data[3]; } unsigned pointer_abuse(struct pkt *p) { return __builtin_bswap16(*(unsigned short *)p->data); }