https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63900
Bug ID: 63900 Summary: memory constrains needlessly doing memory clobber Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: inline-asm Assignee: unassigned at gcc dot gnu.org Reporter: gccbugzilla at limegreensocks dot com Using a constraint like this: "=m" ( *(struct { char __x[BUFSIZE]; } *)b) only works for very specific sizes of BUFSIZE (1, 2, 4, 8, 16). All other sizes (3, 12, 1000, etc) cause gcc to (silently) fall back to doing a full memory clobber. --------------------- #include <stdio.h> #define MYSIZE 8 inline void __stosb(unsigned char *Dest, unsigned char Data, size_t Count) { struct _reallybigstruct { char x[MYSIZE]; } *p = (struct _reallybigstruct *)Dest; __asm__ __volatile__ ("rep stosb" : "+D" (Dest), "+c" (Count), "=m" (*p) : [Data] "a" (Data) //: "memory" ); } int main() { unsigned char buff[100], buff2[100]; buff[5] = 'A'; buff2[5] = 'M'; asm("#" : : "r" (buff2)); __stosb(buff, 'B', sizeof(buff)); printf("%c %c\n", buff[5], buff2[5]); } --------------------- Compile this (4.9.0 x86_64-win32-seh-rev2, using -m64 -O2) with MYSIZE 8 and look at the -S output. If this is NOT doing a full clobber, gcc should be able to just print buff2[5] by moving 77 into r8d before calling printf (which it does). Change MYSIZE to 3 (or 12, 1000, 0xfffffff, etc) we see the value getting read from memory before calling printf, indicating the asm performed a full clobber (affecting buff2) instead of just clobbering buff as was intended.