This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Optimization breaks inline asm code w/ptrs

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 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
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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]