This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] regmove: Problem with asm("x") variables in inline assemblies
- From: Andreas Krebbel <Andreas dot Krebbel at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 28 Mar 2007 10:27:22 +0200
- Subject: [PATCH] regmove: Problem with asm("x") variables in inline assemblies
Hi,
debugging a problem with a S/390 inline assembly I found a bug in regmove.
According to the GCC manual (extend.texi) GCC assures that a "register ... asm ("x") declared
variable is provided in the specified register when used as operand for an inline
assembly. Regmove was already patched due to this:
http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01808.html
For a DEST = SRC like insn optimize_reg_copy_1 tries to replace occurences of SRC with DEST.
The replacement is done using validate_replace_rtx. Afterwards it is checked whether the
resulting insn still mentions SRC and SRC is a hard reg. In that case the replacement is undone.
Unfortunately the undo operation is also performed when validate_replace_rtx fails at all. Thats
probably not what was intended:
! else if (validate_replace_rtx (src, dest, q)
! && (sregno >= FIRST_PSEUDO_REGISTER
! || ! reg_overlap_mentioned_p (src,
! PATTERN (q))))
! ;
! else
{
validate_replace_rtx (dest, src, q);
failed = 1;
With the attached patch regmove undoes the replacement only when the additional check fails not
when the first validate_replace_rtx operation returns a failure.
Boostrapped on i686, s390 and s390x.
No testsuite regressions.
OK for mainline?
Bye,
-Andreas-
2007-03-28 Andreas Krebbel <krebbel1@de.ibm.com>
* regmove.c (optimize_reg_copy_1): Don't perform DEST->SRC repair action if
SRC->DEST replacement failed anyway.
Index: gcc/regmove.c
===================================================================
*** gcc/regmove.c.orig 2007-03-27 11:04:26.000000000 +0200
--- gcc/regmove.c 2007-03-27 13:32:58.000000000 +0200
*************** optimize_reg_copy_1 (rtx insn, rtx dest,
*** 471,485 ****
if (sregno < FIRST_PSEUDO_REGISTER
&& reg_mentioned_p (dest, PATTERN (q)))
failed = 1;
! /* Replace all uses and make sure that the register
! isn't still present. */
! else if (validate_replace_rtx (src, dest, q)
! && (sregno >= FIRST_PSEUDO_REGISTER
! || ! reg_overlap_mentioned_p (src,
! PATTERN (q))))
! ;
! else
{
validate_replace_rtx (dest, src, q);
failed = 1;
--- 471,485 ----
if (sregno < FIRST_PSEUDO_REGISTER
&& reg_mentioned_p (dest, PATTERN (q)))
failed = 1;
+
+ /* Attempt to replace all uses. */
+ else if (!validate_replace_rtx (src, dest, q))
+ failed = 1;
! /* If this succeeded, but some part of the register
! is still present, undo the replacement. */
! else if (sregno < FIRST_PSEUDO_REGISTER
! && reg_overlap_mentioned_p (src, PATTERN (q)))
{
validate_replace_rtx (dest, src, q);
failed = 1;