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

Jeffrey A. Law <law at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2015-01-21
                 CC|                            |law at redhat dot com
     Ever confirmed|0                           |1

--- Comment #11 from Jeffrey A. Law <law at redhat dot com> ---
Carlos,

In general, you want to avoid using a register that is in a singleton class in
an asm explicitly in an asm.  While it works a hell of a lot better now than it
has in the past, there's still cases where you can put the compiler into a
situation where it can't figure out what to do.  Typically that happens when
you explicit clobber every register that GCC could potentially use to resolve a
reload.  And that's much more likely if you happen to clobber a register that
is a singleton in a class.

For the PA, %r1 is not fixed, but it is in a singleton class because it is the
only register that can be set by addil.  And ldil;add is not equivalent to
addil because of some *insanely* gross stuff done by the HP linker where it
will change addil <whatever>,r27 into addil <whatever>,r0, depending on what
subsection <whatever> is in.  THe linker isn't smart enough to do the same
transformation on an ldil/add sequence which should otherwise be equivalent.

Thus GCC has to put %r1 into its own class as a singleton.

%r1 will often be needed as a reload scratch register as well as an
intermediate for secondary reloads, most of the time to handle references to
data in static storage, but also to handle constants that may be shoved into
static storage.  Registers with this kind of need are handled specially by
reload and their "lifetime" essentially is the entire insn that triggered the
reload.  In this particular case, the lifetime is essentially the entire asm
statement.

So in this case, you have &lock being passed to lll_mutex_lock.  That's a
reference to static storage and thus *may* %r1 as a reload scratch register. 
That use as a reload scratch is seen as interfering with the %r1 in the clobber
list.

>From looking at the ASM you're trying to clobber all the call-clobbered
registers, presumably due to the hidden "call" in the asm (the
branch-and-link-external).  Note that you should probably be including %r2 in
that list.

My asm and PA-fu are a bit rusty, so it's not immediately clear how to do what
you want.  You could try changing r1 so that you're clobbering a register that
has to go into class "a".  At least in that case you might be able to use a
simple clobber ("=a") rather than an earlyclobber ("=&a") for the constraint. 
That gives GCC a bit more leeway in building the conflicts, but may still not
be enough.

Or get lock out of static memory or otherwise hide the fact that its in static
memory so that GCC won't try to create a direct reference to it in the asm.  I
think that's what David's workaround was in effect suggesting.  If by a level
of indirection you can prevent GCC from discovering that futex is in static
memory, then this problem should go away (its address will just be sitting in a
register and can be used directly). 

These are just potential workarounds for a reload issue that is highly unlikely
to ever get fixed.  If your asm clobber the entire set of call-clobbered
registers, you really don't leave reload enough leeway to handle reloads. 
Similarly if it clobbers everything in a particular class, then you run into
the same problem if there's an operand that requires a reload register of that
class.

This is probably a WONTFIX.

Reply via email to