On Thu, Aug 17, 2017 at 04:27:12PM +0200, Michael Matz wrote: > Hi, > > On Mon, 14 Aug 2017, Alan Modra wrote: > > > I've opened https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81845 to track > > the lack of documentation. > > You mean like in this paragraph discussing memory clobbers and uses in > extended asms that we have since 2004? :
The paragraph you show below (from gcc-4 sources) disappeared with git commit 3aabc45f2. We currently have this: ------ Flushing registers to memory has performance implications and may be an issue for time-sensitive code. You can use a trick to avoid this if the size of the memory being accessed is known at compile time. For example, if accessing ten bytes of a string, use a memory input like: @code{@{"m"( (@{ struct @{ char x[10]; @} *p = (void *)ptr ; *p; @}) )@}}. ------ So, no example even of the simplest "m" (*y) type memory input. This lack was part of the reason I submitted https://gcc.gnu.org/ml/gcc-patches/2017-03/msg01562.html which died in the review process, mostly due to the example being rather large, and partly I fear, due to not being x86. I didn't push the patch for a number of reasons. Then later realized that the constraints I was using for arrays, while they work for OpenBLAS, were not strict enough. "m" (*y) for an array y only makes the asm depend on y[0]. I have a couple of documentation patches prepared, and have been poking around in the source to verify that what I'm proposing for indeterminate length arrays, "m" (*(const T (*)[]) ptr) and "=m" (*(T (*)[]) ptr) is reasonable. One obvious problem is that the cast expression isn't a proper lvalue, but I'm encouraged to find comments in the source complaining that such things need to be tolerated in asm. :) > > ---------------- > If your assembler instructions access memory in an unpredictable > fashion, add `memory' to the list of clobbered registers. This will > cause GCC to not keep memory values cached in registers across the > assembler instruction and not optimize stores or loads to that memory. > You will also want to add the `volatile' keyword if the memory affected > is not listed in the inputs or outputs of the `asm', as the `memory' > clobber does not count as a side-effect of the `asm'. If you know how > large the accessed memory is, you can add it as input or output but if > this is not known, you should add `memory'. As an example, if you > access ten bytes of a string, you can use a memory input like: > > {"m"( ({ struct { char x[10]; } *p = (void *)ptr ; *p; }) )}. > > Note that in the following example the memory input is necessary, > otherwise GCC might optimize the store to `x' away: > int foo () > { > int x = 42; > int *y = &x; > int result; > asm ("magic stuff accessing an 'int' pointed to by '%1'" > "=&d" (r) : "a" (y), "m" (*y)); > return result; > } > ---------------- > > > Ciao, > Michael. -- Alan Modra Australia Development Lab, IBM