diff mbox

[SH,4.8] Fix PR 59343

Message ID 1386324094.14008.79.camel@yam-132-YW-E178-FTW
State New
Headers show

Commit Message

Oleg Endo Dec. 6, 2013, 10:01 a.m. UTC
Hello,

This fixes a bug on the 4.8 branch which was initially described in PR
51244 comment 59 and also reported as a separate PR 59343.
Tested with
make -k check RUNTESTFLAGS="--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"

and no new failures.
OK for 4.8?

Cheers,
Oleg

gcc/ChangeLog:
	PR target/51244
	PR target/59343
	* config/sh/sh.md (*cbranch_t): Check that there are no labels 
	between the s1 insn and the testing insn.  Remove REG_DEAD note 
	from s1 insn.

testsuite/ChangeLog:
	PR target/51244
	PR target/59343
	* gcc.target/sh/pr51244-19.c: Adjust test case.

Comments

Kaz Kojima Dec. 6, 2013, 10:40 a.m. UTC | #1
Oleg Endo <oleg.endo@t-online.de> wrote:
> This fixes a bug on the 4.8 branch which was initially described in PR
> 51244 comment 59 and also reported as a separate PR 59343.
> Tested with
> make -k check RUNTESTFLAGS="--target_board=sh-sim
> \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"
> 
> and no new failures.
> OK for 4.8?

OK.

Regards,
	kaz
diff mbox

Patch

Index: gcc/testsuite/gcc.target/sh/pr51244-19.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr51244-19.c	(revision 205675)
+++ gcc/testsuite/gcc.target/sh/pr51244-19.c	(working copy)
@@ -22,11 +22,16 @@ 
    unwanted sequences.  Thus, if we see any movt insns, something is not
    working as expected.  This test requires -O2 because the T bit stores
    in question will be eliminated in additional insn split passes after
-   reload.  */
+   reload.
+
+   Notice: When this test case was initially added, the T bit optimization
+           was buggy and this test case resulted in wrong code.  The movt
+           instructions actually have to be present in this case to get
+           correct code.  */
 /* { dg-do compile { target "sh*-*-*" } } */
 /* { dg-options "-O2" } */
 /* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
-/* { dg-final { scan-assembler-not "movt" } } */
+/* { dg-final { scan-assembler "movt" } } */
 
 struct request
 {
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 205675)
+++ gcc/config/sh/sh.md	(working copy)
@@ -8427,11 +8427,9 @@ 
 
   while (true)
     {
-      /* It's not safe to go beyond the current basic block after reload.  */
       set_of_reg s1 = sh_find_set_of_reg (tested_reg, s0.insn,
-					  reload_completed
-					  ? prev_nonnote_insn_bb
-					  : prev_nonnote_insn);
+					  prev_nonnote_insn);
+
       if (s1.set_src == NULL_RTX)
 	break;
 
@@ -8449,15 +8447,25 @@ 
 	  continue;
 	}
 
-	/* It's only safe to remove the testing insn if the T bit is not
-	   modified between the testing insn and the insn that stores the
-	   T bit.  Notice that some T bit stores such as negc also modify
-	   the T bit.  */
-	if (modified_between_p (get_t_reg_rtx (), s1.insn, testing_insn)
-	    || modified_in_p (get_t_reg_rtx (), s1.insn))
-	  operands[2] = NULL_RTX;
+      /* It's only safe to remove the testing insn if the T bit is not
+	 modified between the testing insn and the insn that stores the
+	 T bit.  Notice that some T bit stores such as negc also modify
+	 the T bit.  */
+      if (modified_between_p (get_t_reg_rtx (), s1.insn, testing_insn)
+	  || modified_in_p (get_t_reg_rtx (), s1.insn)
+	  || !no_labels_between_p (s1.insn, testing_insn))
+	operands[2] = NULL_RTX;
+      else
+	{
+	  /* If the insn that sets the tested reg has a REG_DEAD note on
+	     the T bit remove that note since we're extending the usage
+	     of the T bit.  */
+	  rtx n = find_regno_note (s1.insn, REG_DEAD, T_REG);
+	  if (n != NULL_RTX)
+	    remove_note (s1.insn, n);
+	}
 
-	break;
+      break;
     }
 
   if (operands[2] == NULL_RTX)