This is the mail archive of the gcc@gcc.gnu.org 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: Memory outputs in inline asm


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


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