diff mbox

[BACKPORT] Fix PR rtl-optimization/45593

Message ID 20110514181632.GA8346@hiauly1.hia.nrc.ca
State New
Headers show

Commit Message

John David Anglin May 14, 2011, 6:16 p.m. UTC
Trunk fails to build using gcc-4.3 and gcc-4.4 when -O1 is specified
in STAGE1_CFLAGS on hppa2.0w-hp-hpux11.11.  I have had anecdotal reports
of similar delay slot problems in glibc and the Linux kernel.

Investigation showed that this bug was a delay slot scheduling problem
and that the issue was fixed by Eric last September.  The fix was back
ported to the 4.5 branch but not to previous branches.  The identical
fix applies to the 4.4 and 4.3 branches.

Ok to backport?

Dave

Comments

Eric Botcazou May 14, 2011, 7:26 p.m. UTC | #1
> Investigation showed that this bug was a delay slot scheduling problem
> and that the issue was fixed by Eric last September.  The fix was back
> ported to the 4.5 branch but not to previous branches.  The identical
> fix applies to the 4.4 and 4.3 branches.
>
> Ok to backport?

OK, thanks.  Note that another delay slot bug was fixed around the same time:

2010-09-20  Eric Botcazou  <ebotcazou@adacore.com>

	PR rtl-optimization/42775
	* cfgrtl.c (rest_of_pass_free_cfg): Recompute notes if delay slot
	scheduling is enabled.

This one was installed on the 4.6/4.5/4.4 branches.
John David Anglin May 22, 2011, 8:55 p.m. UTC | #2
On Sat, 14 May 2011, John David Anglin wrote:

> > OK, thanks.  Note that another delay slot bug was fixed around the same time:
> > 
> > 2010-09-20  Eric Botcazou  <ebotcazou@adacore.com>
> > 
> > 	PR rtl-optimization/42775
> > 	* cfgrtl.c (rest_of_pass_free_cfg): Recompute notes if delay slot
> > 	scheduling is enabled.
> > 
> > This one was installed on the 4.6/4.5/4.4 branches.
> 
> Thanks for the note.  While 4.4 can now successfully bootstrap trunk
> with -O1, I still have a problem with 4.3.  I'll see if this helps.

This didn't help.

I opened a PR:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49007

Problem seems similar to PR rtl-optimization/40710.

Dave
diff mbox

Patch

Index: gcc/reorg.c
===================================================================
--- gcc/reorg.c	(revision 173596)
+++ gcc/reorg.c	(working copy)
@@ -3453,9 +3453,13 @@ 
 	     We do this by deleting the INSN containing the SEQUENCE, then
 	     re-emitting the insns separately, and then deleting the RETURN.
 	     This allows the count of the jump target to be properly
-	     decremented.  */
+	     decremented.
 
-	  /* Clear the from target bit, since these insns are no longer
+	     Note that we need to change the INSN_UID of the re-emitted insns
+	     since it is used to hash the insns for mark_target_live_regs and
+	     the re-emitted insns will no longer be wrapped up in a SEQUENCE.
+
+	     Clear the from target bit, since these insns are no longer
 	     in delay slots.  */
 	  for (i = 0; i < XVECLEN (pat, 0); i++)
 	    INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
@@ -3463,13 +3467,10 @@ 
 	  trial = PREV_INSN (insn);
 	  delete_related_insns (insn);
 	  gcc_assert (GET_CODE (pat) == SEQUENCE);
-	  after = trial;
-	  for (i = 0; i < XVECLEN (pat, 0); i++)
-	    {
-	      rtx this_insn = XVECEXP (pat, 0, i);
-	      add_insn_after (this_insn, after, NULL);
-	      after = this_insn;
-	    }
+	  add_insn_after (delay_insn, trial, NULL);
+	  after = delay_insn;
+	  for (i = 1; i < XVECLEN (pat, 0); i++)
+	    after = emit_copy_of_insn_after (XVECEXP (pat, 0, i), after);
 	  delete_scheduled_jump (delay_insn);
 	  continue;
 	}
@@ -3571,9 +3572,13 @@ 
 	     We do this by deleting the INSN containing the SEQUENCE, then
 	     re-emitting the insns separately, and then deleting the jump.
 	     This allows the count of the jump target to be properly
-	     decremented.  */
+	     decremented.
 
-	  /* Clear the from target bit, since these insns are no longer
+	     Note that we need to change the INSN_UID of the re-emitted insns
+	     since it is used to hash the insns for mark_target_live_regs and
+	     the re-emitted insns will no longer be wrapped up in a SEQUENCE.
+
+	     Clear the from target bit, since these insns are no longer
 	     in delay slots.  */
 	  for (i = 0; i < XVECLEN (pat, 0); i++)
 	    INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
@@ -3581,13 +3586,10 @@ 
 	  trial = PREV_INSN (insn);
 	  delete_related_insns (insn);
 	  gcc_assert (GET_CODE (pat) == SEQUENCE);
-	  after = trial;
-	  for (i = 0; i < XVECLEN (pat, 0); i++)
-	    {
-	      rtx this_insn = XVECEXP (pat, 0, i);
-	      add_insn_after (this_insn, after, NULL);
-	      after = this_insn;
-	    }
+	  add_insn_after (delay_insn, trial, NULL);
+	  after = delay_insn;
+	  for (i = 1; i < XVECLEN (pat, 0); i++)
+	    after = emit_copy_of_insn_after (XVECEXP (pat, 0, i), after);
 	  delete_scheduled_jump (delay_insn);
 	  continue;
 	}
--- /dev/null	Sat May 14 08:48:19 2011
+++ gcc/testsuite/gcc.c-torture/compile/20100915-1.c	Mon May  9 18:17:54 2011
@@ -0,0 +1,82 @@ 
+/* PR rtl-optimization/45593 */
+/* Testcase by Arnaud Lacombe <lacombar@gmail.com> */
+
+typedef unsigned int __u32;
+typedef __u32 __be32;
+static inline __attribute__((always_inline)) int __attribute__((__cold__)) printk(const char *s, ...) { return 0; }
+typedef struct journal_s journal_t;
+typedef struct journal_header_s
+{
+ __be32 h_magic;
+ __be32 h_blocktype;
+ __be32 h_sequence;
+} journal_header_t;
+typedef struct journal_superblock_s
+{
+ journal_header_t s_header;
+ __be32 s_blocksize;
+ __be32 s_maxlen;
+} journal_superblock_t;
+struct journal_s
+{
+ struct buffer_head *j_sb_buffer;
+ journal_superblock_t *j_superblock;
+ int j_format_version;
+ int j_blocksize;
+ unsigned int j_maxlen;
+};
+static void journal_fail_superblock (journal_t *journal)
+{
+ journal->j_sb_buffer = ((void *)0);
+}
+static int journal_get_superblock(journal_t *journal)
+{
+ struct buffer_head *bh;
+ journal_superblock_t *sb;
+ int err = -100;
+ bh = journal->j_sb_buffer;
+ if (!buffer_uptodate(bh)) {
+  if (!buffer_uptodate(bh)) {
+   printk ("JBD: IO error reading journal superblock\n");
+   goto out;
+  }
+ }
+ err = -101;
+ if (sb->s_header.h_magic != (( __be32)(__u32)(0)) ||
+     sb->s_blocksize != (( __be32)(__u32)(journal->j_blocksize))) {
+  printk("JBD: no valid journal superblock found\n");
+  goto out;
+ }
+ switch((( __u32)(__be32)(sb->s_header.h_blocktype))) {
+ case 0:
+ case 1:
+  break;
+ default:
+  goto out;
+ }
+ if ((( __u32)(__be32)(sb->s_maxlen)) < journal->j_maxlen)
+  journal->j_maxlen = (( __u32)(__be32)(sb->s_maxlen));
+ else if ((( __u32)(__be32)(sb->s_maxlen)) > journal->j_maxlen) {
+  printk ("JBD: journal file too short\n");
+  goto out;
+ }
+ return 0;
+out:
+ journal_fail_superblock(journal);
+ return err;
+}
+static int load_superblock(journal_t *journal)
+{
+ journal_get_superblock(journal);
+ return 0;
+}
+int jbd2_journal_update_format (journal_t *journal)
+{
+ journal_get_superblock(journal);
+ return 0;
+}
+int jbd2_journal_wipe(journal_t *journal, int write)
+{
+ load_superblock(journal);
+ return 0;
+}