From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14874 invoked by alias); 9 Jun 2006 11:42:07 -0000 Received: (qmail 14743 invoked by uid 48); 9 Jun 2006 11:41:58 -0000 Date: Fri, 09 Jun 2006 12:40:00 -0000 Message-ID: <20060609114158.14742.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug target/27959] [4.1 regression] s390x miscompilation due to clobbering literal pool base reg In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "krebbel at gcc dot gnu dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2006-06/txt/msg01046.txt.bz2 List-Id: ------- Comment #3 from krebbel at gcc dot gnu dot org 2006-06-09 11:41 ------- On s390 we use a trick to make the literal pool base register available "on demand". It is defined as eliminable register which can be eliminated to itself with offset 0. When a reload round finds a r13 (literal pool base) it asks the back end whether it can be eliminated and the back end says no. So reload throws any pseudos out of r13 and marks it as bad_spill_regs_global hence it won't be used as a reload register. In your example there is no literal pool reference when entering reload. So the initial elimination step marks r13 as eliminable and therefore free to be used in reloads and it actually is used in a reload. In the second round reload forces a constant into the literal pool what creates a literal pool reference. When update_eliminables is called r13 is marked as cant_eliminate and the respective bit in bad_spill_regs_global is set. So far so good. Unfortunately reload seems to think that registers which were once good to be used in reloads will be good for future reloads as well - thats my impression at least. The bitmap used_spill_regs is not reset between the reload rounds. used_spill_regs is used in finish_spills to recalculate the spill_regs array which then contains r13 since it was used as reload reg in the first round. The following patch deletes all registers which are recognized by update_eliminables as eliminable_previous but cant_eliminate now from the used_spill_regs bitmap and fixes your testcase. Since reload is always a bit dodgy and tends to be unpredictable I would be interested in Ulrichs opinion about the patch. He knows much better whats going on in reload. So Ulrich do think this makes sense? Index: gcc/reload1.c =================================================================== *** gcc/reload1.c.orig 2006-06-09 13:12:39.000000000 +0200 --- gcc/reload1.c 2006-06-09 13:14:54.000000000 +0200 *************** reload (rtx first, int global) *** 987,992 **** --- 987,994 ---- HARD_REG_SET to_spill; CLEAR_HARD_REG_SET (to_spill); update_eliminables (&to_spill); + AND_COMPL_HARD_REG_SET(used_spill_regs, to_spill); + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (TEST_HARD_REG_BIT (to_spill, i)) { -- krebbel at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Ever Confirmed|0 |1 Last reconfirmed|0000-00-00 00:00:00 |2006-06-09 11:41:57 date| | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27959