aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2014-01-08 22:16:49 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2014-01-08 22:16:49 +0000
commitdf6c88082dc25c4b511b0fc5ba98dd2acfff0a04 (patch)
tree8a0b3aaea6b10e0c6b5e5cfbfe7850a9bb8c8817 /gcc
parentace295afeb0a126d960339d0e04e3b8b26e96670 (diff)
downloadgcc-df6c88082dc25c4b511b0fc5ba98dd2acfff0a04.zip
gcc-df6c88082dc25c4b511b0fc5ba98dd2acfff0a04.tar.gz
gcc-df6c88082dc25c4b511b0fc5ba98dd2acfff0a04.tar.bz2
re PR rtl-optimization/59137 (Miscompilation at -O1 on mips/mipsel)
gcc/ PR rtl-optimization/59137 * reorg.c (steal_delay_list_from_target): Call update_block for elided insns. (steal_delay_list_from_fallthrough, relax_delay_slots): Likewise. gcc/testsuite/ PR rtl-optimization/59137 * gcc.target/mips/pr59137.c: New test. From-SVN: r206445
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/reorg.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/mips/pr59137.c34
4 files changed, 59 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8d61a49..2826bca 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2014-01-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR rtl-optimization/59137
+ * reorg.c (steal_delay_list_from_target): Call update_block for
+ elided insns.
+ (steal_delay_list_from_fallthrough, relax_delay_slots): Likewise.
+
2014-01-08 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Remove
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 740da4a..de33232 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -1093,6 +1093,7 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
int used_annul = 0;
int i;
struct resources cc_set;
+ bool *redundant;
/* We can't do anything if there are more delay slots in SEQ than we
can handle, or if we don't know that it will be a taken branch.
@@ -1133,6 +1134,7 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
return delay_list;
#endif
+ redundant = XALLOCAVEC (bool, XVECLEN (seq, 0));
for (i = 1; i < XVECLEN (seq, 0); i++)
{
rtx trial = XVECEXP (seq, 0, i);
@@ -1154,7 +1156,8 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
/* If this insn was already done (usually in a previous delay slot),
pretend we put it in our delay slot. */
- if (redundant_insn (trial, insn, new_delay_list))
+ redundant[i] = redundant_insn (trial, insn, new_delay_list);
+ if (redundant[i])
continue;
/* We will end up re-vectoring this branch, so compute flags
@@ -1187,6 +1190,12 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
return delay_list;
}
+ /* Record the effect of the instructions that were redundant and which
+ we therefore decided not to copy. */
+ for (i = 1; i < XVECLEN (seq, 0); i++)
+ if (redundant[i])
+ update_block (XVECEXP (seq, 0, i), insn);
+
/* Show the place to which we will be branching. */
*pnew_thread = first_active_target_insn (JUMP_LABEL (XVECEXP (seq, 0, 0)));
@@ -1250,6 +1259,7 @@ steal_delay_list_from_fallthrough (rtx insn, rtx condition, rtx seq,
/* If this insn was already done, we don't need it. */
if (redundant_insn (trial, insn, delay_list))
{
+ update_block (trial, insn);
delete_from_delay_slot (trial);
continue;
}
@@ -3236,6 +3246,7 @@ relax_delay_slots (rtx first)
to reprocess this insn. */
if (redundant_insn (XVECEXP (pat, 0, 1), delay_insn, 0))
{
+ update_block (XVECEXP (pat, 0, 1), insn);
delete_from_delay_slot (XVECEXP (pat, 0, 1));
next = prev_active_insn (next);
continue;
@@ -3355,6 +3366,7 @@ relax_delay_slots (rtx first)
&& redirect_with_delay_slots_safe_p (delay_insn, target_label,
insn))
{
+ update_block (XVECEXP (PATTERN (trial), 0, 1), insn);
reorg_redirect_jump (delay_insn, target_label);
next = insn;
continue;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 13334a4..3319675 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-01-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR rtl-optimization/59137
+ * gcc.target/mips/pr59137.c: New test.
+
2014-01-08 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/asm-1.c (dg-options): Remove -m32.
diff --git a/gcc/testsuite/gcc.target/mips/pr59137.c b/gcc/testsuite/gcc.target/mips/pr59137.c
new file mode 100644
index 0000000..8986506
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr59137.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-mno-plt" } */
+
+extern void abort (void);
+
+struct lispstruct
+{
+ int e;
+ int t;
+};
+
+struct lispstruct Cnil_body;
+struct lispstruct Ct_body;
+int nvalues;
+
+struct lispstruct * __attribute__ ((noinline))
+fLlistp (struct lispstruct *x0)
+{
+ if (x0 == &Cnil_body
+ || (((unsigned long) x0 >= 0x80000000) ? 0
+ : (!x0->e ? (x0 != &Cnil_body) : x0->t)))
+ x0 = &Ct_body;
+ else
+ x0 = &Cnil_body;
+ nvalues = 1;
+ return x0;
+}
+
+int main ()
+{
+ if (fLlistp ((struct lispstruct *) 0xa0000001) != &Cnil_body)
+ abort ();
+ return 0;
+}