From patchwork Wed Mar 30 19:50:42 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 88956 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id B4AECB6EF0 for ; Thu, 31 Mar 2011 06:50:57 +1100 (EST) Received: (qmail 27809 invoked by alias); 30 Mar 2011 19:50:51 -0000 Received: (qmail 27774 invoked by uid 22791); 30 Mar 2011 19:50:49 -0000 X-SWARE-Spam-Status: No, hits=-6.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 30 Mar 2011 19:50:44 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p2UJoiR8017811 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 30 Mar 2011 15:50:44 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p2UJoh4n031002 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 30 Mar 2011 15:50:43 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (localhost.localdomain [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id p2UJog05014380; Wed, 30 Mar 2011 21:50:42 +0200 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id p2UJogom014379; Wed, 30 Mar 2011 21:50:42 +0200 Date: Wed, 30 Mar 2011 21:50:42 +0200 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Cc: Alexandre Oliva Subject: [PATCH] Fix VTA updating in the combiner (PR debug/48343) Message-ID: <20110330195042.GS18914@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi! We ICE on the attached testcase, because combiner changes mode of a pseudo (which was set just once and used once plus in debug insns) from SImode to QImode, but the uses in debug insns aren't adjusted. Combiner has code to adjust this too (propagate_for_debug), but only updates debug insns between i2 and i3 (resp. i3 and undobuf.other_insn). The problem on the testcase is that this is a retry, so first try_combine with a later i3 calls propagate_for_debug and changes debug insns before that later i3, then returns an earlier insn that should be retried and we stop adjusting debug insns at that earlier i3. Unfortunately as later debug insns have been already updated earlier, they need to be adjusted too. The following patch fixes that by always stopping on the latest i3 that has been successfully combined into in the current bb, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.6? 2011-03-30 Jakub Jelinek PR debug/48343 * combine.c (last_combined_insn): New variable. (combine_instructions): Clear it before processing each bb and after last bb. (try_combine): Set it to i3 if i3 is after it. Use it as the last argument to propagate_for_debug instead of i3. (distribute_notes): Assert SET_INSN_DELETE is not called on last_combined_insn. * gcc.dg/torture/pr48343.c: New test. Jakub --- gcc/combine.c.jj 2011-03-23 09:34:40.000000000 +0100 +++ gcc/combine.c 2011-03-30 17:39:09.000000000 +0200 @@ -337,6 +337,9 @@ static enum machine_mode nonzero_bits_mo static int nonzero_sign_valid; +/* Last insn on which try_combine has been called in the current BB. */ + +static rtx last_combined_insn; /* Record one modification to rtl structure to be undone by storing old_contents into *where. */ @@ -1168,6 +1171,7 @@ combine_instructions (rtx f, unsigned in || single_pred (this_basic_block) != last_bb) label_tick_ebb_start = label_tick; last_bb = this_basic_block; + last_combined_insn = NULL_RTX; rtl_profile_for_bb (this_basic_block); for (insn = BB_HEAD (this_basic_block); @@ -1379,6 +1383,7 @@ combine_instructions (rtx f, unsigned in } } + last_combined_insn = NULL_RTX; default_rtl_profile (); clear_log_links (); clear_bb_flags (); @@ -3830,6 +3835,10 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx return 0; } + if (last_combined_insn == NULL_RTX + || DF_INSN_LUID (last_combined_insn) < DF_INSN_LUID (i3)) + last_combined_insn = i3; + if (MAY_HAVE_DEBUG_INSNS) { struct undo *undo; @@ -3851,7 +3860,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i2src while its original mode is temporarily restored, and then clear i2scratch so that we don't do it again later. */ - propagate_for_debug (i2, i3, reg, i2src); + propagate_for_debug (i2, last_combined_insn, reg, i2src); i2scratch = false; /* Put back the new mode. */ adjust_reg_mode (reg, new_mode); @@ -3859,18 +3868,17 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx else { rtx tempreg = gen_raw_REG (old_mode, REGNO (reg)); - rtx first, last; + rtx first; if (reg == i2dest) - { - first = i2; - last = i3; - } + first = i2; else { first = i3; - last = undobuf.other_insn; - gcc_assert (last); + gcc_assert (undobuf.other_insn); + if (DF_INSN_LUID (undobuf.other_insn) + > DF_INSN_LUID (last_combined_insn)) + last_combined_insn = undobuf.other_insn; } /* We're dealing with a reg that changed mode but not @@ -3882,9 +3890,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx with this copy we have created; then, replace the copy with the SUBREG of the original shared reg, once again changed to the new mode. */ - propagate_for_debug (first, last, reg, tempreg); + propagate_for_debug (first, last_combined_insn, reg, tempreg); adjust_reg_mode (reg, new_mode); - propagate_for_debug (first, last, tempreg, + propagate_for_debug (first, last_combined_insn, tempreg, lowpart_subreg (old_mode, reg, new_mode)); } } @@ -4099,14 +4107,14 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx if (newi2pat) { if (MAY_HAVE_DEBUG_INSNS && i2scratch) - propagate_for_debug (i2, i3, i2dest, i2src); + propagate_for_debug (i2, last_combined_insn, i2dest, i2src); INSN_CODE (i2) = i2_code_number; PATTERN (i2) = newi2pat; } else { if (MAY_HAVE_DEBUG_INSNS && i2src) - propagate_for_debug (i2, i3, i2dest, i2src); + propagate_for_debug (i2, last_combined_insn, i2dest, i2src); SET_INSN_DELETED (i2); } @@ -4115,7 +4123,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx LOG_LINKS (i1) = 0; REG_NOTES (i1) = 0; if (MAY_HAVE_DEBUG_INSNS) - propagate_for_debug (i1, i3, i1dest, i1src); + propagate_for_debug (i1, last_combined_insn, i1dest, i1src); SET_INSN_DELETED (i1); } @@ -4124,7 +4132,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx LOG_LINKS (i0) = 0; REG_NOTES (i0) = 0; if (MAY_HAVE_DEBUG_INSNS) - propagate_for_debug (i0, i3, i0dest, i0src); + propagate_for_debug (i0, last_combined_insn, i0dest, i0src); SET_INSN_DELETED (i0); } @@ -13454,6 +13462,7 @@ distribute_notes (rtx notes, rtx from_in NULL_RTX, NULL_RTX, NULL_RTX); distribute_links (LOG_LINKS (tem)); + gcc_assert (tem != last_combined_insn); SET_INSN_DELETED (tem); if (tem == i2) i2 = NULL_RTX; @@ -13471,6 +13480,7 @@ distribute_notes (rtx notes, rtx from_in NULL_RTX, NULL_RTX, NULL_RTX); distribute_links (LOG_LINKS (cc0_setter)); + gcc_assert (cc0_setter != last_combined_insn); SET_INSN_DELETED (cc0_setter); if (cc0_setter == i2) i2 = NULL_RTX; --- gcc/testsuite/gcc.dg/torture/pr48343.c.jj 2011-03-30 17:41:51.000000000 +0200 +++ gcc/testsuite/gcc.dg/torture/pr48343.c 2011-03-30 17:41:32.000000000 +0200 @@ -0,0 +1,19 @@ +/* PR debug/48343 */ +/* { dg-do compile } */ +/* { dg-options "-fcompare-debug" } */ + +void foo (unsigned char *, unsigned char *); + +void +test (unsigned int x, int y) +{ + unsigned int i, j = 0, k; + unsigned char s[256], t[64]; + foo (s, t); + t[0] = y; + for (i = 0; i < 256; i++) + { + j = (j + s[i] + t[i % x]) & 0xff; + k = i; i = j; j = k; + } +}