public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/63359] New: aarch64: 32bit registers in inline asm
@ 2014-09-24 13:26 glisse at gcc dot gnu.org
  2014-09-24 13:55 ` [Bug target/63359] " james.molloy at arm dot com
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: glisse at gcc dot gnu.org @ 2014-09-24 13:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

            Bug ID: 63359
           Summary: aarch64: 32bit registers in inline asm
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: glisse at gcc dot gnu.org
            Target: aarch64-linux-gnu

int f(int i){
  asm("clz %0, %0":"+r"(i));
  return i;
}

produces:

    clz x0, x0

I need to write "clz %w0, %w0" to get the expected:

    clz w0, w0

What I would like:
1) on x86, the type of i is used to get the right register name. If this can't
be done on aarch64 (did ARM forbid it?), it may be useful to warn when I pass
the wrong type.
2) I need a documented way to get 32bit regs, and %w0 is not documented in the
gcc manual. Besides, clang rejects it, so please find a common syntax...


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug target/63359] aarch64: 32bit registers in inline asm
  2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
@ 2014-09-24 13:55 ` james.molloy at arm dot com
  2014-09-24 14:44 ` rearnsha at gcc dot gnu.org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: james.molloy at arm dot com @ 2014-09-24 13:55 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

James Molloy <james.molloy at arm dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |james.molloy at arm dot com

--- Comment #1 from James Molloy <james.molloy at arm dot com> ---
Hi,

> Besides, clang rejects it, so please find a common syntax...

It shouldn't. The "w" modifier should have been supported since clang 3.4, and
is certainly supported in clang 3.5.

Clang 3.5 has a warning about this:

"""
/tmp/test.c:2:27: warning: value size does not match register size specified by
the constraint and modifier [-Wasm-operand-widths]
    asm("clz %0, %0":"+r"(i));
                          ^
/tmp/test.c:2:14: note: use constraint modifier "w"
    asm("clz %0, %0":"+r"(i));
             ^~
             %w0
/tmp/test.c:2:27: warning: value size does not match register size specified by
the constraint and modifier [-Wasm-operand-widths]
    asm("clz %0, %0":"+r"(i));
                          ^
/tmp/test.c:2:18: note: use constraint modifier "w"
    asm("clz %0, %0":"+r"(i));
                 ^~
                 %w0
2 warnings generated.
"""


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug target/63359] aarch64: 32bit registers in inline asm
  2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
  2014-09-24 13:55 ` [Bug target/63359] " james.molloy at arm dot com
@ 2014-09-24 14:44 ` rearnsha at gcc dot gnu.org
  2014-09-24 14:47 ` james.molloy at arm dot com
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: rearnsha at gcc dot gnu.org @ 2014-09-24 14:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

Richard Earnshaw <rearnsha at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2014-09-24
     Ever confirmed|0                           |1

--- Comment #3 from Richard Earnshaw <rearnsha at gcc dot gnu.org> ---
Agree that this needs to be documented.  

I'm not so sure about a warning, however.  I could envisage cases where the
warning would be incorrect and avoiding it would lead to code pessimisation.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug target/63359] aarch64: 32bit registers in inline asm
  2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
  2014-09-24 13:55 ` [Bug target/63359] " james.molloy at arm dot com
  2014-09-24 14:44 ` rearnsha at gcc dot gnu.org
@ 2014-09-24 14:47 ` james.molloy at arm dot com
  2014-09-24 14:57 ` rearnsha at gcc dot gnu.org
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: james.molloy at arm dot com @ 2014-09-24 14:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

--- Comment #4 from James Molloy <james.molloy at arm dot com> ---
Hi Richard,

My two-pennyworth for what it's worth - we've had several people with broken
code tripped by this bug, and Apple have reported seeing the same thing with
their internal codebases. This one seems often to appear in real-world code.

Cheers,

James


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug target/63359] aarch64: 32bit registers in inline asm
  2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2014-09-24 14:47 ` james.molloy at arm dot com
@ 2014-09-24 14:57 ` rearnsha at gcc dot gnu.org
  2014-09-24 15:04 ` james.molloy at arm dot com
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: rearnsha at gcc dot gnu.org @ 2014-09-24 14:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

--- Comment #5 from Richard Earnshaw <rearnsha at gcc dot gnu.org> ---
So consider:

int f(int i){
  long x;
  asm("lsl %0, %1, 33" : "=r"(x) : "r"(i)); // lshift by more than sizeof(int)
  return x;
}

We really don't care about the top bits in i, so we don't want to extend the
value to 64 bits before we do the shift.  But we can't put "w" on the second
operand since it has to be a 64-bit register.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug target/63359] aarch64: 32bit registers in inline asm
  2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2014-09-24 14:57 ` rearnsha at gcc dot gnu.org
@ 2014-09-24 15:04 ` james.molloy at arm dot com
  2014-09-24 15:07 ` glisse at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: james.molloy at arm dot com @ 2014-09-24 15:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

--- Comment #6 from James Molloy <james.molloy at arm dot com> ---
Good example, although I might argue slightly pathological.

So in this case currently, GCC doesn't even implicitly promote the argument,
just uses it as-is. It seems a very dangerous behaviour to have as default.
Could there not be a more sensible default and an explicit constraint modifier
to allow this instead?


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug target/63359] aarch64: 32bit registers in inline asm
  2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2014-09-24 15:04 ` james.molloy at arm dot com
@ 2014-09-24 15:07 ` glisse at gcc dot gnu.org
  2014-09-24 15:21 ` rearnsha at gcc dot gnu.org
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: glisse at gcc dot gnu.org @ 2014-09-24 15:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

--- Comment #7 from Marc Glisse <glisse at gcc dot gnu.org> ---
(In reply to Richard Earnshaw from comment #3)
> I'm not so sure about a warning, however.  I could envisage cases where the
> warning would be incorrect and avoiding it would lead to code pessimisation.

I don't insist on the warning, I might not have needed it with a proper doc
(that explains both that "r" is reserved to 64 bits (gcc won't adapt to the
type of the argument) and that there is a 'w' modifier to get 32 bits).


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug target/63359] aarch64: 32bit registers in inline asm
  2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2014-09-24 15:07 ` glisse at gcc dot gnu.org
@ 2014-09-24 15:21 ` rearnsha at gcc dot gnu.org
  2014-09-24 15:27 ` james.molloy at arm dot com
  2020-06-15 11:07 ` andysem at mail dot ru
  8 siblings, 0 replies; 10+ messages in thread
From: rearnsha at gcc dot gnu.org @ 2014-09-24 15:21 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

--- Comment #8 from Richard Earnshaw <rearnsha at gcc dot gnu.org> ---
(In reply to James Molloy from comment #6)
> Good example, although I might argue slightly pathological.
> 

Agreed, this is somewhat pathological, but I only need to find one valid
counter-example :-)

Furthermore, something similar will be quite common on results.  Eg:

int i, j;
unsigned long r;
asm("add %w0, %w1, %w2" : "=r"(r) : "r"(i), "r"(j));  // zero-extend result.

here we *want* the 64-bit result from the implicit zero-extend of writing the
lower 32 bits.

> So in this case currently, GCC doesn't even implicitly promote the argument,
> just uses it as-is. It seems a very dangerous behaviour to have as default.
> Could there not be a more sensible default and an explicit constraint
> modifier to allow this instead?

One of the things I dislike so much about GCC's inline assembly is that it's
just an exposure to users of an internal API in the compiler.  That makes it
very difficult to say precisely what will happen in all cases and *very* hard
to fix problems with it when it exposes bugs.

I'm not saying I'll never accept a warning for this sort of code; but I'd need
convincing that it won't unduly pessimize real code with no acceptable
work-arounds.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug target/63359] aarch64: 32bit registers in inline asm
  2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2014-09-24 15:21 ` rearnsha at gcc dot gnu.org
@ 2014-09-24 15:27 ` james.molloy at arm dot com
  2020-06-15 11:07 ` andysem at mail dot ru
  8 siblings, 0 replies; 10+ messages in thread
From: james.molloy at arm dot com @ 2014-09-24 15:27 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

--- Comment #9 from James Molloy <james.molloy at arm dot com> ---
OK, given your second example I agree that the usecase isn't quite as
pathological as I thought.

> I'm not saying I'll never accept a warning for this sort of code; but I'd need
convincing that it won't unduly pessimize real code with no acceptable
work-arounds.

Clang is committed to this warning as our community feels the error detection
rate makes up for the lack of raw power. So unless we actively do something the
two compilers will always differ in approach which probably isn't best for our
users.

Would you be opposed to discussing a constraint modifier to mean "implicitly
extend to 64-bits"?


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug target/63359] aarch64: 32bit registers in inline asm
  2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
                   ` (7 preceding siblings ...)
  2014-09-24 15:27 ` james.molloy at arm dot com
@ 2020-06-15 11:07 ` andysem at mail dot ru
  8 siblings, 0 replies; 10+ messages in thread
From: andysem at mail dot ru @ 2020-06-15 11:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63359

andysem at mail dot ru changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andysem at mail dot ru

--- Comment #14 from andysem at mail dot ru ---
I've been hit by this issue recently.

(In reply to Richard Earnshaw from comment #12)
> We considered that, but it won't work.  For example, in ILP32 address
> registers need to use the X form, but are still 32-bits in size.  There are
> other cases as well where a W or X form is required but that is not the
> natural size of the object.

For the cases where the size needs to be specified explicitly, you can leave
%w1/%x1 syntax. But the default register size, I think, should be chosen based
on the asm argument size.

There is one case where I don't feel like %w1/%x1 syntax is correct, even if
currently accepted. It's when the argument allows an alternative of an
immediate constant:

asm("add %w0, %w1, %w2" : "=r"(r) : "r"(i), "Ir"(j));

Note the last argument. When it is a constant, it doesn't need the "w" prefix,
but it needs one if it is a runtime value.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-06-15 11:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-24 13:26 [Bug target/63359] New: aarch64: 32bit registers in inline asm glisse at gcc dot gnu.org
2014-09-24 13:55 ` [Bug target/63359] " james.molloy at arm dot com
2014-09-24 14:44 ` rearnsha at gcc dot gnu.org
2014-09-24 14:47 ` james.molloy at arm dot com
2014-09-24 14:57 ` rearnsha at gcc dot gnu.org
2014-09-24 15:04 ` james.molloy at arm dot com
2014-09-24 15:07 ` glisse at gcc dot gnu.org
2014-09-24 15:21 ` rearnsha at gcc dot gnu.org
2014-09-24 15:27 ` james.molloy at arm dot com
2020-06-15 11:07 ` andysem at mail dot ru

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).