This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Memory outputs in inline asm
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Andrew Haley <aph at redhat dot com>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Wed, 26 Feb 2014 13:24:39 +0100
- Subject: Re: Memory outputs in inline asm
- Authentication-results: sourceware.org; auth=none
- References: <530DC2D3 dot 9030301 at redhat dot com> <CAFiYyc1yLSCMpKYtfXOdskBfNNpSeRS953BEmQt=6EhtDGggQg at mail dot gmail dot com> <530DCBA3 dot 6090805 at redhat dot com>
On Wed, Feb 26, 2014 at 12:10 PM, Andrew Haley <aph@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.
>