From: Richard Sandiford Date: Wed, 8 Jan 2014 22:16:49 +0000 (+0000) Subject: re PR rtl-optimization/59137 (Miscompilation at -O1 on mips/mipsel) X-Git-Tag: releases/gcc-4.9.0~1770 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=df6c88082dc25c4b511b0fc5ba98dd2acfff0a04;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d61a49724fb..2826bca98bd2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-01-08 Richard Sandiford + + 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 * config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Remove diff --git a/gcc/reorg.c b/gcc/reorg.c index 740da4a83c6c..de332323ae1c 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 13334a4fb1bc..3319675a2105 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-01-08 Richard Sandiford + + PR rtl-optimization/59137 + * gcc.target/mips/pr59137.c: New test. + 2014-01-08 Uros Bizjak * 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 000000000000..898650656806 --- /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; +}