[patch committed SH] Fix PR target/65249

2015-07-15 Thread Kaz Kojima
I've committed the attached patch to fix PR target/65249.  The patch
reduces R0-register pressure for the problematic situation and fixes
the ICE reported in PR65249 with -mno-lra.  It gives a bit better code
for the test case of that PR with -mlra too.
Tested with sh4-unknown-linux-gnu.  I'll backport it to 4.9 later and
to 5 when it reopens.

Regards,
kaz
--
2015-07-16  Kaz Kojima  

PR target/65249
* config/sh/sh.md (movdi): Split simple reg move to two movsi
when the destination is R0.

diff --git a/config/sh/sh.md b/config/sh/sh.md
index f0cb3cf..61f6637 100644
--- a/config/sh/sh.md
+++ b/config/sh/sh.md
@@ -7892,6 +7892,24 @@ label:
   ""
 {
   prepare_move_operands (operands, DImode);
+  if (TARGET_SH1)
+{
+  /* When the dest operand is (R0, R1) register pair, split it to
+two movsi of which dest is R1 and R0 so as to lower R0-register
+pressure on the first movsi.  Apply only for simple source not
+to make complex rtl here.  */
+  if (REG_P (operands[0])
+ && REGNO (operands[0]) == R0_REG
+ && REG_P (operands[1])
+ && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
+   {
+ emit_insn (gen_movsi (gen_rtx_REG (SImode, R1_REG),
+   gen_rtx_SUBREG (SImode, operands[1], 4)));
+ emit_insn (gen_movsi (gen_rtx_REG (SImode, R0_REG),
+   gen_rtx_SUBREG (SImode, operands[1], 0)));
+ DONE;
+   }
+}
 })
 
 (define_insn "movdf_media"


[patch committed SH] Fix PR target/65249

2015-03-03 Thread Kaz Kojima
The attached patches are to fix PR target/65249 which is a 4.9/5
regression.  It avoids yet another R0_REGS spill failure with
pre-allocating R0 reg in symGOT_load when the loading symbol is
__stack_chk_guard.  Although the problem went away with -mlra
and LRA would be the real fix for this issue, SH is still in
transition to LRA and we have no chance for 4.9.
Tested with sh4-unknown-linux-gnu on trunk and 4.9 branch.
Committed on trunk and 4.9.

Regards,
kaz
--
2015-03-03  Kaz Kojima  

PR target/65249
* config/sh/sh.md (symGOT_load): Use R0 reg for operands[2] when
called for __stack_chk_guard symbol.

[trunk/gcc]
diff --git a/config/sh/sh.md b/config/sh/sh.md
index 2435ec9..24ddc9e 100644
--- a/config/sh/sh.md
+++ b/config/sh/sh.md
@@ -10690,10 +10690,26 @@ label:
   ""
 {
   rtx mem;
+  bool stack_chk_guard_p = false;
 
   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
 
+  if (!TARGET_SHMEDIA
+  && flag_stack_protect
+  && GET_CODE (operands[1]) == CONST
+  && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
+  && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
+  && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
+"__stack_chk_guard") == 0)
+stack_chk_guard_p = true;
+
+  /* Use R0 to avoid long R0 liveness which stack-protector tends to
+ produce.  */
+  if (! sh_lra_flag
+  && stack_chk_guard_p && ! reload_in_progress && ! reload_completed)
+operands[2] = gen_rtx_REG (Pmode, R0_REG);
+
   if (TARGET_SHMEDIA)
 {
   rtx reg = operands[2];
@@ -10721,13 +10737,7 @@ label:
  insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
  when rX is a GOT address for the guard symbol.  Ugly but doesn't
  matter because this is a rare situation.  */
-  if (!TARGET_SHMEDIA
-  && flag_stack_protect
-  && GET_CODE (operands[1]) == CONST
-  && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
-  && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
-  && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
-"__stack_chk_guard") == 0)
+  if (stack_chk_guard_p)
 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
   else
 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
[gcc-4_9-branch/gcc]
diff --git a/config/sh/sh.md b/config/sh/sh.md
index 00bbf3e..f75f5a2 100644
--- a/config/sh/sh.md
+++ b/config/sh/sh.md
@@ -10164,10 +10164,25 @@ label:
   ""
 {
   rtx mem;
+  bool stack_chk_guard_p = false;
 
   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
 
+  if (!TARGET_SHMEDIA
+  && flag_stack_protect
+  && GET_CODE (operands[1]) == CONST
+  && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
+  && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
+  && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
+"__stack_chk_guard") == 0)
+stack_chk_guard_p = true;
+
+  /* Use R0 to avoid long R0 liveness which stack-protector tends to
+ produce.  */
+  if (stack_chk_guard_p && ! reload_in_progress && ! reload_completed)
+operands[2] = gen_rtx_REG (Pmode, R0_REG);
+
   if (TARGET_SHMEDIA)
 {
   rtx reg = operands[2];
@@ -10195,13 +10210,7 @@ label:
  insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
  when rX is a GOT address for the guard symbol.  Ugly but doesn't
  matter because this is a rare situation.  */
-  if (!TARGET_SHMEDIA
-  && flag_stack_protect
-  && GET_CODE (operands[1]) == CONST
-  && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
-  && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
-  && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
-"__stack_chk_guard") == 0)
+  if (stack_chk_guard_p)
 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
   else
 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],