This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.0] PR20973 (khtml miscompiled by reload)
- From: Michael Matz <matz at suse dot de>
- To: gcc-patches at gcc dot gnu dot org, Mark Mitchell <mark at codesourcery dot com>
- Date: Wed, 13 Apr 2005 22:50:29 +0200 (CEST)
- Subject: [4.0] PR20973 (khtml miscompiled by reload)
Hi,
I really would like to see this in gcc 4.0, as otherwise KDE can't be
usefully compiled with it (although it meanwhile contains a wordaround).
But the scope of the problem might also affect quite some other programs.
It's a problem in reload, which isn't handling uninitialized pseudos
correctly. Look at the bugreport for the gory details. The patch fixes
the problem in khtml. I've bootstrapped it with gcc 4.0 on
i686,x86_64,ppc,ppc64,ia64,s390 (s390x was breaking for different
reasons), all languages (with Ada ;) ). There were no regressions (in
fact some fixed Ada testcases, but I'm not sure if they were real).
As usual, this being a reload problem, it's hard to reduce this all to a
testcase with deterministic behaviour.
I also want to include it in trunk of course.
Ciao,
Michael.
--
PR20973
* reload.c (push_reload, find_dummy_reload): Check for uninitialized
pseudos.
Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.268
diff -u -p -r1.268 reload.c
--- gcc/reload.c 24 Feb 2005 22:06:06 -0000 1.268
+++ gcc/reload.c 12 Apr 2005 19:42:16 -0000
@@ -1520,7 +1520,7 @@ push_reload (rtx in, rtx out, rtx *inloc
But if there is no spilling in this block, that is OK.
An explicitly used hard reg cannot be a spill reg. */
- if (rld[i].reg_rtx == 0 && in != 0)
+ if (rld[i].reg_rtx == 0 && in != 0 && hard_regs_live_known)
{
rtx note;
int regno;
@@ -1534,6 +1534,9 @@ push_reload (rtx in, rtx out, rtx *inloc
&& REG_P (XEXP (note, 0))
&& (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
&& reg_mentioned_p (XEXP (note, 0), in)
+ && (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
+ || ! bitmap_bit_p (ENTRY_BLOCK_PTR->global_live_at_end,
+ ORIGINAL_REGNO (XEXP (note, 0))))
&& ! refers_to_regno_for_reload_p (regno,
(regno
+ hard_regno_nregs[regno]
@@ -1997,7 +2000,16 @@ find_dummy_reload (rtx real_in, rtx real
is a subreg, and in that case, out
has a real mode. */
(GET_MODE (out) != VOIDmode
- ? GET_MODE (out) : outmode)))
+ ? GET_MODE (out) : outmode))
+ /* But only do all this if we can be sure, that this input
+ operand doesn't correspond with an uninitialized pseudoreg.
+ global can assign some hardreg to it, which is the same as
+ a different pseudo also currently live (as it can ignore the
+ conflict). So we never must introduce writes to such hardregs,
+ as they would clobber the other live pseudo using the same. */
+ && (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER
+ || ! bitmap_bit_p (ENTRY_BLOCK_PTR->global_live_at_end,
+ ORIGINAL_REGNO (in))))
{
unsigned int regno = REGNO (in) + in_offset;
unsigned int nwords = hard_regno_nregs[regno][inmode];