This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, rs6000] Fix PR target/42427
On Thu, 2010-01-21 at 10:13 -0500, David Edelsohn wrote:
> Testing for the existence of PRE_INC, PRE_DEC and PRE_MODIFY and then
> testing for their absence is overly confusing. The patch is adding
> another layer to the existing logic instead of cleaning it up. No one
> will be able to maintain the code when it next needs to be modified.
> If one needs to test the same RTL code multiple times, the code should
> be rearranged. I also am not confident that LO_SUM should have been
> omitted.
Here's a new patch with the auto-increment tests factored out from the
other tests. I checked and we do not want the LO_SUM code handled the
same as the PRE_* forms. This passed bootstrap and regtesting on
powerpc64-linux with -m32/-m64. Is this ok now?
Peter
PR target/42427
* config/rs6000/rs6000.md (*movdf_hardfloat32): Move auto-increment
code into its own "if" test.
(*movdf_softfloat32): Add test for auto-increment form instructions.
* gfortran.dg/pr42427.f: New test.
Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md (revision 155844)
+++ config/rs6000/rs6000.md (working copy)
@@ -9149,17 +9149,17 @@ (define_insn "*movdf_hardfloat32"
else
return \"mr %0,%1\;mr %L0,%L1\";
case 1:
- if (rs6000_offsettable_memref_p (operands[1])
- || (GET_CODE (operands[1]) == MEM
- && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM
- || GET_CODE (XEXP (operands[1], 0)) == PRE_INC
- || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC
- || GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY)))
+ if (GET_CODE (operands[1]) == MEM
+ && (GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY
+ || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC
+ || GET_CODE (XEXP (operands[1], 0)) == PRE_INC))
+ return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
+ else if (rs6000_offsettable_memref_p (operands[1])
+ || (GET_CODE (operands[1]) == MEM
+ && GET_CODE (XEXP (operands[1], 0)) == LO_SUM))
{
/* 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. */
+ it last. Otherwise, load it first. */
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
operands[1], 0))
return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
@@ -9257,15 +9257,21 @@ (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 (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
- else
+ /* 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 ((GET_CODE (operands[1]) == MEM
+ && (GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY
+ || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC
+ || GET_CODE (XEXP (operands[1], 0)) == PRE_INC))
+ || !refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands[1], 0))
return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
+ else
+ return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
case 2:
return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\";
case 3:
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