This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, rs6000] Fix PR target/42427
- From: Peter Bergner <bergner at vnet dot ibm dot com>
- To: David Edelsohn <dje dot gcc at gmail dot com>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 14 Jan 2010 13:52:28 -0600
- Subject: [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