This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[SH, 4.8] Fix PR 59343
- From: Oleg Endo <oleg dot endo at t-online dot de>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 06 Dec 2013 11:01:34 +0100
- Subject: [SH, 4.8] Fix PR 59343
- Authentication-results: sourceware.org; auth=none
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.
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)