This is the mail archive of the gcc-patches@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]

[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;


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