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?

Reply via email to