From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13874 invoked by alias); 19 Aug 2009 23:26:32 -0000 Received: (qmail 13864 invoked by uid 22791); 19 Aug 2009 23:26:31 -0000 X-SWARE-Spam-Status: No, hits=-0.0 required=5.0 tests=AWL,BAYES_00,BOTNET,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 19 Aug 2009 23:26:24 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n7JNQM3d017342 for ; Wed, 19 Aug 2009 19:26:22 -0400 Received: from omfg.slc.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n7JNQKDP006862 for ; Wed, 19 Aug 2009 19:26:21 -0400 Message-ID: <4A8C8A42.3020008@redhat.com> Date: Thu, 20 Aug 2009 00:01:00 -0000 From: Jeff Law User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.1) Gecko/20090814 Fedora/3.0-2.6.b3.fc11 Thunderbird/3.0b3 MIME-Version: 1.0 To: GCC Subject: Latent bug in update_equiv_regs? Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2009-08/txt/msg00348.txt.bz2 Somehow I can't help but think I'm missing something here... Given: (set (reg X) (mem Y)) (...) (set (mem Y) (reg Z)) (...) (use (reg X)) update_equiv_regs can set an equivalence between (reg X) and (mem Y) which is clearly wrong as (mem Y) is set to (reg Z). 99.99% of the time this doesn't cause us any problems. However, imagine if (reg X) is not assigned a hard register. Reload then gleefully replaces uses of (reg X) with its equivalent memory location. Given the RTL above that's clearly bad. It looks like this code is supposed to wipe the problematic equivalence: /* We only handle the case of a pseudo register being set once, or always to the same value. */ /* ??? The mn10200 port breaks if we add equivalences for values that need an ADDRESS_REGS register and set them equivalent to a MEM of a pseudo. The actual problem is in the over-conservative handling of INPADDR_ADDRESS / INPUT_ADDRESS / INPUT triples in calculate_needs, but we traditionally work around this problem here by rejecting equivalences when the destination is in a register that's likely spilled. This is fragile, of course, since the preferred class of a pseudo depends on all instructions that set or use it. */ if (!REG_P (dest) || (regno = REGNO (dest)) < FIRST_PSEUDO_REGISTER || reg_equiv[regno].init_insns == const0_rtx || (CLASS_LIKELY_SPILLED_P (reg_preferred_class (regno)) && MEM_P (src) && ! reg_equiv[regno].is_arg_equivalence)) { /* This might be setting a SUBREG of a pseudo, a pseudo that is also set somewhere else to a constant. */ note_stores (set, no_equiv, NULL); continue; } However, if we look at no_equiv we see the following: /* Mark REG as having no known equivalence. Some instructions might have been processed before and furnished with REG_EQUIV notes for this register; these notes will have to be removed. STORE is the piece of RTL that does the non-constant / conflicting assignment - a SET, CLOBBER or REG_INC note. It is currently not used, but needs to be there because this function is called from note_stores. */ static void no_equiv (rtx reg, const_rtx store ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) { int regno; rtx list; if (!REG_P (reg)) return; [ ... ] Thus no_equiv doesn't do anything when passed a MEM. I haven't tried triggering this problem with the mainline sources... What am I missing? jeff