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/65153


The attached patch is to fix PR target/65153 which is a 4.9.2
regression and latent on trunk.  The patch removes a problematic
peephole and sh.c:replace_n_hard_rtx of which that peephole is
the last user.  Oleg shows that the patch doesn't give any
significant differences with CSiBE tests.  See
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65153
for details.
Tested on sh4-unknwon-linux-gnu with no new failures.  Committed
on trunk.  I'll backport it to 4.9 branch later.

Regards,
	kaz
--
2015-02-23  Kaz Kojima  <kkojima@gcc.gnu.org>

	PR target/65153
	* config/sh/sh.md (movsicc_true+3): Remove peephole.
	* config/sh/sh-protos.h (replace_n_hard_rtx): Don't declare.
	* config/sh/sh.c (replace_n_hard_rtx): Remove.

diff --git a/config/sh/sh-protos.h b/config/sh/sh-protos.h
index 1d8ba1d..c706e74 100644
--- a/config/sh/sh-protos.h
+++ b/config/sh/sh-protos.h
@@ -384,7 +384,6 @@ extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree,
 				     signed int, machine_mode);
 extern rtx sh_dwarf_register_span (rtx);
 
-extern rtx replace_n_hard_rtx (rtx, rtx *, int , int);
 extern int shmedia_cleanup_truncate (rtx);
 
 extern bool sh_contains_memref_p (rtx);
diff --git a/config/sh/sh.c b/config/sh/sh.c
index 7c9d8e2..02c6176 100644
--- a/config/sh/sh.c
+++ b/config/sh/sh.c
@@ -13015,146 +13015,6 @@ sh_init_cumulative_args (CUMULATIVE_ARGS *  pcum,
     }
 }
 
-/* Replace any occurrence of FROM(n) in X with TO(n).  The function does
-   not enter into CONST_DOUBLE for the replace.
-
-   Note that copying is not done so X must not be shared unless all copies
-   are to be modified.
-
-   This is like replace_rtx, except that we operate on N_REPLACEMENTS
-   replacements simultaneously - FROM(n) is replacements[n*2] and to(n) is
-   replacements[n*2+1] - and that we take mode changes into account.
-
-   If a replacement is ambiguous, return NULL_RTX.
-
-   If MODIFY is zero, don't modify any rtl in place,
-   just return zero or nonzero for failure / success.  */
-rtx
-replace_n_hard_rtx (rtx x, rtx *replacements, int n_replacements, int modify)
-{
-  int i, j;
-  const char *fmt;
-
-  /* The following prevents loops occurrence when we change MEM in
-     CONST_DOUBLE onto the same CONST_DOUBLE.  */
-  if (x != NULL_RTX && GET_CODE (x) == CONST_DOUBLE)
-    return x;
-
-  for (i = n_replacements - 1; i >= 0 ; i--)
-  if (x == replacements[i*2] && GET_MODE (x) == GET_MODE (replacements[i*2+1]))
-    return replacements[i*2+1];
-
-  /* Allow this function to make replacements in EXPR_LISTs.  */
-  if (x == NULL_RTX)
-    return NULL_RTX;
-
-  if (GET_CODE (x) == SUBREG)
-    {
-      rtx new_rtx = replace_n_hard_rtx (SUBREG_REG (x), replacements,
-				    n_replacements, modify);
-
-      if (CONST_INT_P (new_rtx))
-	{
-	  x = simplify_subreg (GET_MODE (x), new_rtx,
-			       GET_MODE (SUBREG_REG (x)),
-			       SUBREG_BYTE (x));
-	  if (! x)
-	    abort ();
-	}
-      else if (modify)
-	SUBREG_REG (x) = new_rtx;
-
-      return x;
-    }
-  else if (REG_P (x))
-    {
-      unsigned regno = REGNO (x);
-      unsigned nregs = (regno < FIRST_PSEUDO_REGISTER
-			? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
-      rtx result = NULL_RTX;
-
-      for (i = n_replacements - 1; i >= 0; i--)
-	{
-	  rtx from = replacements[i*2];
-	  rtx to = replacements[i*2+1];
-	  unsigned from_regno, from_nregs, to_regno, new_regno;
-
-	  if (!REG_P (from))
-	    continue;
-	  from_regno = REGNO (from);
-	  from_nregs = (from_regno < FIRST_PSEUDO_REGISTER
-			? HARD_REGNO_NREGS (from_regno, GET_MODE (from)) : 1);
-	  if (regno < from_regno + from_nregs && regno + nregs > from_regno)
-	    {
-	      if (regno < from_regno
-		  || regno + nregs > from_regno + nregs
-		  || !REG_P (to)
-		  || result)
-		return NULL_RTX;
-	      to_regno = REGNO (to);
-	      if (to_regno < FIRST_PSEUDO_REGISTER)
-		{
-		  new_regno = regno + to_regno - from_regno;
-		  if ((unsigned) HARD_REGNO_NREGS (new_regno, GET_MODE (x))
-		      != nregs)
-		    return NULL_RTX;
-		  result = gen_rtx_REG (GET_MODE (x), new_regno);
-		}
-	      else if (GET_MODE (x) <= GET_MODE (to))
-		result = gen_lowpart_common (GET_MODE (x), to);
-	      else
-		result = gen_lowpart_SUBREG (GET_MODE (x), to);
-	    }
-	}
-      return result ? result : x;
-    }
-  else if (GET_CODE (x) == ZERO_EXTEND)
-    {
-      rtx new_rtx = replace_n_hard_rtx (XEXP (x, 0), replacements,
-				    n_replacements, modify);
-
-      if (CONST_INT_P (new_rtx))
-	{
-	  x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
-					new_rtx, GET_MODE (XEXP (x, 0)));
-	  if (! x)
-	    abort ();
-	}
-      else if (modify)
-	XEXP (x, 0) = new_rtx;
-
-      return x;
-    }
-
-  fmt = GET_RTX_FORMAT (GET_CODE (x));
-  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
-    {
-      rtx new_rtx;
-
-      if (fmt[i] == 'e')
-	{
-	  new_rtx = replace_n_hard_rtx (XEXP (x, i), replacements,
-				    n_replacements, modify);
-	  if (!new_rtx)
-	    return NULL_RTX;
-	  if (modify)
-	    XEXP (x, i) = new_rtx;
-	}
-      else if (fmt[i] == 'E')
-	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-	  {
-	    new_rtx = replace_n_hard_rtx (XVECEXP (x, i, j), replacements,
-				      n_replacements, modify);
-	  if (!new_rtx)
-	    return NULL_RTX;
-	    if (modify)
-	      XVECEXP (x, i, j) = new_rtx;
-	  }
-    }
-
-  return x;
-}
-
 rtx
 sh_gen_truncate (machine_mode mode, rtx x, int need_sign_ext)
 {
diff --git a/config/sh/sh.md b/config/sh/sh.md
index 94a01af..11b96d7 100644
--- a/config/sh/sh.md
+++ b/config/sh/sh.md
@@ -1706,76 +1706,6 @@
   replace_rtx (operands[4], operands[0], operands[1]);
 })
 
-(define_peephole2
-  [(set (match_operand 0 "any_register_operand" "")
-	(match_operand 1 "any_register_operand" ""))
-   (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
-   (set (match_operand 4 "" "") (match_operand 5 "" ""))]
-  "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
-    <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
-   && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
-   && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
-   && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
-   && ! reg_overlap_mentioned_p (operands[0], operands[3])
-   && ! reg_overlap_mentioned_p (operands[2], operands[0])
-   && ! reg_overlap_mentioned_p (operands[0], operands[1])
-   && (REGNO_REG_CLASS (REGNO (operands[0]))
-       == REGNO_REG_CLASS (REGNO (operands[2])))
-   && (REGNO_REG_CLASS (REGNO (operands[1]))
-       == REGNO_REG_CLASS (REGNO (operands[0])))"
-  [(set (match_dup 0) (match_dup 3))
-   (set (match_dup 4) (match_dup 5))]
-{
-  rtx set1, set2;
-  rtx_insn *insn1, *insn2;
-  rtx replacements[4];
-
-  /* We want to replace occurrences of operands[0] with operands[1] and
-     operands[2] with operands[0] in operands[4]/operands[5].
-     Doing just two replace_rtx calls naively would result in the second
-     replacement undoing all that the first did if operands[1] and operands[2]
-     are identical, so we must do this simultaneously.  */
-  replacements[0] = operands[0];
-  replacements[1] = operands[1];
-  replacements[2] = operands[2];
-  replacements[3] = operands[0];
-  if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
-      || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
-      || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
-    FAIL;
-
-  operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
-  replace_n_hard_rtx (operands[4], replacements, 2, 1);
-  operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
-  /* The operands array is aliased to recog_data.operand, which gets
-     clobbered by extract_insn, so finish with it now.  */
-  set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
-  set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
-  /* ??? The last insn might be a jump insn, but the generic peephole2 code
-     always uses emit_insn.  */
-  /* Check that we don't violate matching constraints or earlyclobbers.  */
-  basic_block bb = BLOCK_FOR_INSN (peep2_next_insn (2));
-  insn1 = emit_insn (set1);
-  extract_insn (insn1);
-  if (! constrain_operands (1, get_preferred_alternatives (insn1, bb)))
-    goto failure;
-  insn2 = emit (set2);
-  if (GET_CODE (insn2) == BARRIER)
-    goto failure;
-  extract_insn (insn2);
-  if (! constrain_operands (1, get_preferred_alternatives (insn2, bb)))
-    {
-    failure:
-      std::swap (replacements[0], replacements[1]);
-      std::swap (replacements[2], replacements[3]);
-      replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
-      replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
-      replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
-      FAIL;
-    }
-  DONE;
-})
-
 ;; The register allocator is rather clumsy in handling multi-way conditional
 ;; moves, so allow the combiner to make them, and we split them up after
 ;; reload.  */


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