https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63900
--- Comment #9 from Christopher Head <headch at gmail dot com> --- I had to use slightly different code because I only have an ARM cross-compiler version 8.2.0 installed, so I used this: void g(unsigned char x); struct MyStruct { char foo[8]; }; unsigned char buffer[100], buffer2[100]; void f(void) { buffer2[5] = 'X'; struct MyStruct *p = (void *) buffer; asm volatile("nop" : "=m" (*p)); g(buffer2[5]); } No matter what I changed the size of the foo array in MyStruct to (I tried 8, 15, 13, and 257), this was always the disassembly: 00000000 <f>: 0: 4a03 ldr r2, [pc, #12] ; (10 <f+0x10>) 2: 2058 movs r0, #88 ; 0x58 4: 4b03 ldr r3, [pc, #12] ; (14 <f+0x14>) 6: 7150 strb r0, [r2, #5] 8: bf00 nop a: f7ff bffe b.w 0 <g> a: R_ARM_THM_JUMP24 g e: bf00 nop Notice that r0 is loaded at offset 2, then passed into g at offset a, and is not reloaded from the array. If I change the asm to have a full memory clobber, an ldrb is inserted between the nop and the b.w, as expected, since then buffer2 is also clobbered. So, doesn’t this mean that it *is* properly clobbering only buffer, not buffer2, regardless of the size of foo?