From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22446 invoked by alias); 7 Oct 2007 03:18:53 -0000 Received: (qmail 22413 invoked by alias); 7 Oct 2007 03:18:40 -0000 Date: Sun, 07 Oct 2007 03:18:00 -0000 Message-ID: <20071007031840.22412.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug rtl-optimization/33669] [4.3 Regression] Revision 128957 miscompiles 481.wrf In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "zadeck at naturalbridge dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2007-10/txt/msg00566.txt.bz2 ------- Comment #9 from zadeck at naturalbridge dot com 2007-10-07 03:18 ------- Subject: Re: [4.3 Regression] Revision 128957 miscompiles 481.wrf hj, here is a fix. I will most likely post the patch on monday after i get it really tested on a bunch of platforms. The fix is in the third stanza, the rest is better logging. The failure only happens if you have a block with 2 or more uses of a multiword pseudo register that is local to this block and has been allocated by local_alloc. The uses must be in a particular form: the last use was a subreg use that only used some of the hard registers and a previous non subreg use of the multiword register. When all of this happens, the code did not properly expand this to a whole multiregister when the second to last use is encounterd in the backwards scan. I.e. a lot of things have to happen to get this to fail. Thanks for the small test case, that really helped. Kenny Index: ra-conflict.c =================================================================== --- ra-conflict.c (revision 129036) +++ ra-conflict.c (working copy) @@ -76,7 +76,7 @@ record_one_conflict_between_regnos (enum enum machine_mode mode2, int r2) { if (dump_file) - fprintf (dump_file, " rocbr adding %d<=>%d\n", r1, r2); + fprintf (dump_file, " rocbr adding %d<=>%d\n", r1, r2); if (reg_allocno[r1] >= 0 && reg_allocno[r2] >= 0) { int tr1 = reg_allocno[r1]; @@ -293,9 +293,6 @@ set_conflicts_for_earlyclobber (rtx insn recog_data.operand[use + 1]); } } - - if (dump_file) - fprintf (dump_file, " finished early clobber conflicts.\n"); } @@ -876,7 +873,7 @@ global_conflicts (void) allocnum, renumber); } - else if (GET_ALLOCNO_LIVE (allocnos_live, allocnum) == 0) + else { if (dump_file) fprintf (dump_file, " dying pseudo\n"); @@ -963,6 +960,8 @@ global_conflicts (void) FIXME: We should consider either adding a new kind of clobber, or adding a flag to the clobber distinguish these two cases. */ + if (dump_file && VEC_length (df_ref_t, clobbers)) + fprintf (dump_file, " clobber conflicts\n"); for (k = VEC_length (df_ref_t, clobbers) - 1; k >= 0; k--) { struct df_ref *def = VEC_index (df_ref_t, clobbers, k); @@ -1024,6 +1023,8 @@ global_conflicts (void) if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn)) { int j; + if (dump_file) + fprintf (dump_file, " multiple sets\n"); for (j = VEC_length (df_ref_t, dying_regs) - 1; j >= 0; j--) { int used_in_output = 0; -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33669