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, rs6000] Fix PR target/42427


This patch fixes a latent bug exposed by Bernd's regrename patch (r154688).
The old code assumed that if the low order destination hardreg was used
in the address calculation, then the instruction could not possibly be
an auto-increment form instruction since the address is known to be
dead.  However, that is only true of reg+offset addresses.  If we have an
indexed form (eg, reg+reg) update instruction, then the address doesn't
die if the low ordered destination register is used as the offset register.
It cannot be used as the base reg, since that form is invalid so we'll
never see that case here.

Bootstrapped and tested on powerpc64-linux with -m32/-m64.

Ok for trunk?

Peter


2010-01-14  Peter Bergner  <bergner@vnet.ibm.com>

        PR target/42427
	* config/rs6000/rs6000.md: Add test for auto-increment forms.

	* gfortran.dg/pr42427.f: New test.


Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md	(revision 155844)
+++ config/rs6000/rs6000.md	(working copy)
@@ -9156,12 +9156,17 @@ (define_insn "*movdf_hardfloat32"
 		  || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC
 		  || GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY)))
 	{
-	  /* If the low-address word is used in the address, we must load
-	     it last.  Otherwise, load it first.  Note that we cannot have
-	     auto-increment in that case since the address register is
-	     known to be dead.  */
+	  /* If the low-address word is used in the address of a non
+	     auto-increment form instruction, then we must load it last.
+	     Otherwise, load it first.  Auto-increment form instructions
+	     are not a problem, since either the low-address word is not
+	     used in the address, or if it is, it must be used as the
+	     offset register of an indexed form instruction.  */
 	  if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
-				 operands[1], 0))
+				 operands[1], 0)
+	      && GET_CODE (XEXP (operands[1], 0)) != PRE_INC
+	      && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC
+	      && GET_CODE (XEXP (operands[1], 0)) != PRE_MODIFY)
 	    return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
 	  else
 	    return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
@@ -9257,12 +9262,17 @@ (define_insn "*movdf_softfloat32"
       else
 	return \"mr %0,%1\;mr %L0,%L1\";
     case 1:
-      /* If the low-address word is used in the address, we must load
-	 it last.  Otherwise, load it first.  Note that we cannot have
-	 auto-increment in that case since the address register is
-	 known to be dead.  */
+      /* If the low-address word is used in the address of a non
+	 auto-increment form instruction, then we must load it last.
+	 Otherwise, load it first.  Auto-increment form instructions
+	 are not a problem, since either the low-address word is not
+	 used in the address, or if it is, it must be used as the
+	 offset register of an indexed form instruction.  */
       if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
-			     operands[1], 0))
+			     operands[1], 0)
+	  && GET_CODE (XEXP (operands[1], 0)) != PRE_INC
+	  && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC
+	  && GET_CODE (XEXP (operands[1], 0)) != PRE_MODIFY)
 	return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
       else
 	return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
Index: gfortran.dg/pr42427.f
===================================================================
--- gfortran.dg/pr42427.f	(revision 0)
+++ gfortran.dg/pr42427.f	(revision 0)
@@ -0,0 +1,16 @@
+! { dg-do assemble }
+! { dg-options "-O2 -fexceptions -fnon-call-exceptions -fpeel-loops" }
+! { dg-require-effective-target ilp32 }
+
+      SUBROUTINE TEST(HELP,WM,NZ)
+      IMPLICIT REAL*8 (A-H, O-Z)
+      REAL*8 HELP(NZ)
+      COMPLEX*16 WM(NZ)
+
+      DO K=1,NZ
+         ZNEW=ABS(WM(K))
+         ZOLD=HELP(K)
+         HELP(K)=ZNEW
+      ENDDO
+      RETURN
+      END



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