On Wed, Feb 26, 2014 at 12:10 PM, Andrew Haley <a...@redhat.com> wrote: > On 02/26/2014 10:51 AM, Richard Biener wrote: >> But yes, technically you write p[0] here but as "m" merely builds >> an address to the memory I'd say that we have to treat any "m" >> operand as possibly reading from / writing to / clobbering the >> whole object that can be refered to using that address. > > I think so too. > >> Anything else would need extra syntax to specify a memory >> range that is accessed. >> >> And yes, I probably should implement at least basic disambiguation >> against memory accessing asm()s ;) >> >> Summary: I consider your asm ok without changes. Does documentation >> tell you otherwise? Did you run into optimization issues? > > Yes. Here is my original test case that zeroes a block of memory: > > int main() { > > int arr[20]; > int *p = (int*)arr; > > int len = 20; > __asm__("\t0:\n" > "\tstr wzr, [%2, #4]!\n" > "\tsub %1, %1, #1\n" > "\tcbnz %1, 0b\n" > : "=m"(*p), "+r"(len) : "r"(p)); > > return p[5]; > } > > and here is the code GCC emits for main: > > main: > sub sp, sp, #80 > ldr w0, [sp,20] > add sp, sp, 80 > ret > > If I change "=m"(*p) to "=m"(p[5]) I get this: > > main: > sub sp, sp, #80 > mov x1, sp > mov w0, 20 > #APP > // 7 "t.c" 1 > 0: > str wzr, [x1, #4]! > sub x0, x0, #1 > cbnz x0, 0b > > // 0 "" 2 > #NO_APP > ldr w0, [sp,20] > add sp, sp, 80 > ret > > This has all come up because of questions on gcc-help and because I've been > looking at improving the documentation of inline asm. > > If my kludge involving a struct that contains a zero-length array is > supposed to work, we can document it.
It's RTL DSE that removes the asm and that is simply wrong. We should fix it. A zero-size struct get's you an unknown MEM_SIZE I suppose so DSE gives up. IMHO we shouldn't document the kludge but fix the bug. Similar issues may exist with asm uses and removing a regular store that then appears dead. But let's wait for others to comment. Btw, a better workaround (if the size really matters) would be int main() { int arr[20]; int *p = (int*)arr; int len = 20; __asm__("\t0:\n" "\tstr wzr, [%2, #4]!\n" "\tsub %1, %1, #1\n" "\tcbnz %1, 0b\n" : "=m"(*(int (*)[20])p), "+r"(len) : "r"(p)); return p[5]; that is, properly specify the whole object as output. Btw, you can also use "=m"(*(int (*)[len])p) or "=m"(*(char (*)[sizeof (arr)])p) An additional question that immediately pops up here is that of TBAA - may we use the alias-set of the memory reference to disambiguate other loads/stores against the asm? Richard. > Andrew. >