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 committed SH] Fix PR target/66591


I've committed the attached patch to fix PR target/66591 which is
an ice-on-valid-code with -mlra.
SH has only one register in INDEX_REGISTER_CLASS and if the index
term of a memory address is a subreg of DImode register, LRA can't
find appropriate hardware registers in the problematic situation.
It looks to be rare even on SH in the actual codes and seems that
pre-allocating R0 for that index term in sh.c:prepare_move_operands
is enough ATM.  The patch is tested on sh4-unknown-linux-gnu with
and without -mlra.  CSiBE shows no visible regression.

Regards,
	kaz
--
2015-06-19  Kaz Kojima  <kkojima@gcc.gnu.org>

	PR target/66591
	* config/sh/sh.c (prepare_move_operands): Replace subreg
	index term with R0 for base and index addressing.

diff --git a/config/sh/sh.c b/config/sh/sh.c
index 8fc8197..b338a6a 100644
--- a/config/sh/sh.c
+++ b/config/sh/sh.c
@@ -1777,10 +1777,14 @@ prepare_move_operands (rtx operands[], machine_mode mode)
 	 target/55212.
 	 We split possible load/store to two move insns via r0 so as to
 	 shorten R0 live range.  It will make some codes worse but will
-	 win on avarage for LRA.  */
+	 win on average for LRA.
+	 Also when base+index addressing is used and the index term is
+	 a subreg, LRA assumes that more hard registers can be available
+	 in some situation.  It isn't the case for SH in the problematic
+	 case.  We can pre-allocate R0 for that index term to avoid
+	 the issue.  See PR target/66591.  */
       else if (sh_lra_p ()
 	       && TARGET_SH1 && ! TARGET_SH2A
-	       && (mode == QImode || mode == HImode)
 	       && ((REG_P (operands[0]) && MEM_P (operands[1]))
 		   || (REG_P (operands[1]) && MEM_P (operands[0]))))
 	{
@@ -1788,7 +1792,8 @@ prepare_move_operands (rtx operands[], machine_mode mode)
 	  rtx reg = operands[load_p ? 0 : 1];
 	  rtx adr = XEXP (operands[load_p ? 1 : 0], 0);
 
-	  if (REGNO (reg) >= FIRST_PSEUDO_REGISTER
+	  if ((mode == QImode || mode == HImode)
+	      && REGNO (reg) >= FIRST_PSEUDO_REGISTER
 	      && GET_CODE (adr) == PLUS
 	      && REG_P (XEXP (adr, 0))
 	      && (REGNO (XEXP (adr, 0)) >= FIRST_PSEUDO_REGISTER)
@@ -1800,6 +1805,17 @@ prepare_move_operands (rtx operands[], machine_mode mode)
 	      emit_move_insn (r0_rtx, operands[1]);
 	      operands[1] = r0_rtx;
 	    }
+	  if (REGNO (reg) >= FIRST_PSEUDO_REGISTER
+	      && GET_CODE (adr) == PLUS
+	      && REG_P (XEXP (adr, 0))
+	      && (REGNO (XEXP (adr, 0)) >= FIRST_PSEUDO_REGISTER)
+	      && SUBREG_P (XEXP (adr, 1))
+	      && REG_P (SUBREG_REG (XEXP (adr, 1))))
+	    {
+	      rtx r0_rtx = gen_rtx_REG (GET_MODE (XEXP (adr, 1)), R0_REG);
+	      emit_move_insn (r0_rtx, XEXP (adr, 1));
+	      XEXP (adr, 1) = r0_rtx;
+	    }
 	}
     }
 


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