This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
patch to fix a wrong code generation with LRA when SDmode is used on ppc.
- From: Vladimir Makarov <vmakarov at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, Michael Meissner <meissner at linux dot vnet dot ibm dot com>, David Edelsohn <dje dot gcc at gmail dot com>
- Date: Thu, 07 Aug 2014 17:11:08 -0400
- Subject: patch to fix a wrong code generation with LRA when SDmode is used on ppc.
- Authentication-results: sourceware.org; auth=none
Hi, Mike.
Here is the patch which solves LRA SDmode problem which we discussed on
IRC on Friday.
The patch was successfully tested and bootstrapped on ppc64 with -mlra
switched on.
David, is it ok to commit it to the trunk?
2014-08-07 Vladimir Makarov <vmakarov@redhat.com>
* config/rs6000/rs6000.c (rs6000_emit_move): Use SDmode to
load/store from/to non-floating class pseudo.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 213506)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -8271,6 +8271,30 @@ rs6000_emit_move (rtx dest, rtx source,
eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
+ /* Transform (p0:DD, (SUBREG:DD p1:SD)) to ((SUBREG:SD p0:DD),
+ p1:SD) if p1 is not of floating point class and p0 is spilled as
+ we can have no analogous movsd_store for this. */
+ if (lra_in_progress && mode == DDmode
+ && REG_P (operands[0]) && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER
+ && reg_preferred_class (REGNO (operands[0])) == NO_REGS
+ && GET_CODE (operands[1]) == SUBREG && REG_P (SUBREG_REG (operands[1]))
+ && GET_MODE (SUBREG_REG (operands[1])) == SDmode)
+ {
+ enum reg_class cl;
+ int regno = REGNO (SUBREG_REG (operands[1]));
+
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ cl = reg_preferred_class (regno);
+ regno = cl == NO_REGS ? -1 : ira_class_hard_regs[cl][1];
+ }
+ if (regno >= 0 && ! FP_REGNO_P (regno))
+ {
+ mode = SDmode;
+ operands[0] = gen_lowpart_SUBREG (SDmode, operands[0]);
+ operands[1] = SUBREG_REG (operands[1]);
+ }
+ }
if (lra_in_progress
&& mode == SDmode
&& REG_P (operands[0]) && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER
@@ -8301,6 +8325,30 @@ rs6000_emit_move (rtx dest, rtx source,
gcc_unreachable();
return;
}
+ /* Transform ((SUBREG:DD p0:SD), p1:DD) to (p0:SD, (SUBREG:SD
+ p:DD)) if p0 is not of floating point class and p1 is spilled as
+ we can have no analogous movsd_load for this. */
+ if (lra_in_progress && mode == DDmode
+ && GET_CODE (operands[0]) == SUBREG && REG_P (SUBREG_REG (operands[0]))
+ && GET_MODE (SUBREG_REG (operands[0])) == SDmode
+ && REG_P (operands[1]) && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
+ && reg_preferred_class (REGNO (operands[1])) == NO_REGS)
+ {
+ enum reg_class cl;
+ int regno = REGNO (SUBREG_REG (operands[0]));
+
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ cl = reg_preferred_class (regno);
+ regno = cl == NO_REGS ? -1 : ira_class_hard_regs[cl][0];
+ }
+ if (regno >= 0 && ! FP_REGNO_P (regno))
+ {
+ mode = SDmode;
+ operands[0] = SUBREG_REG (operands[0]);
+ operands[1] = gen_lowpart_SUBREG (SDmode, operands[1]);
+ }
+ }
if (lra_in_progress
&& mode == SDmode
&& (REG_P (operands[0])