This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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];


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]