This is the mail archive of the
mailing list for the GCC project.
Register conflicts between output memory address and output register
- From: Matthew Fortune <Matthew dot Fortune at mips dot com>
- To: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>, Vladimir Makarov <vmakarov at redhat dot com>
- Date: Tue, 17 Apr 2018 10:39:20 +0000
- Subject: Register conflicts between output memory address and output register
I've been investigating some quirks of register allocation when handling
some inline asm. The behaviour is non-intuitive but I am not sure if it
is a bug or not. This is back on GCC 6 so I'm still reviewing to see if
anything changed in this area since then.
The inline asm in question is:
asm volatile ("%0, %1, %2" : "=m"(my_mem), "=r"(bar)
What I see is that if the address of my_mem is lowered prior to IRA then
there is a pseudo register for the output memory address (and perhaps an
offset) and a pseudo register for the output register. These two registers
are seen as a conflict in IRA so get different registers allocated. This is
If however the address of my_mem is lowered after IRA i.e. when validating
constraints in LRA then IRA has nothing to do as the address is just a
symbol_ref. When LRA resolves the constraint for the address it introduces
a register for the output memory address but does not seem to acknowledge
any conflict with the output register (bar) it can therefore end up
using the same register for the output memory address as the output register.
This leads to the obvious problem if the ASM updates %1 before %0 as it will
corrupt the address.
This can of course be worked around by making (bar) an early clobber or an
in/out but this does seem unnecessary.
The question is... Should LRA recognise a conflict between the registers
involved in the address portion of an output memory operand and any output
register operands or is this a case where you strictly have to use early
Any advice welcome!