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]

[PATCH] Fix reload inheritance bug


Hi,

This is another fallout of the zero-cost-for-subregs patch on SPARC:

FAIL: gcc.c-torture/execute/simd-2.c execution,  -O3 -fomit-frame-pointer 
FAIL: gcc.c-torture/execute/simd-2.c execution,  -O3 -g 

It turns out that, since the compiler is more inclined to generate or keep 
subregs in the RTL, it again hits the famous reload inheritance bug with 
subregs.  The most thorough analysis and IMHO the best fix can be found in 
this post by Richard Sandiford:

  http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00661.html

Mine is here:

  http://gcc.gnu.org/ml/gcc-patches/2004-04/msg01779.html

and the final patch:

  http://gcc.gnu.org/ml/gcc-patches/2004-06/msg01647.html

[Note that PR rtl-optimization/16028 was closed although the underlying bug 
was not fixed.]

To sum up, a subreg is chosen as an inherited reload register and then the 
inheritance is cancelled.  In this case the failure mode is to keep the 
subreg as a regular reload register and reload the value it contains.  But 
on LOAD_EXTEND_OP platforms, the load clobbers the whole reg and the game is 
over.

Bootstrapped/regtested today on amd64-mandrake-linux-gnu.  OK for mainline?


2005-01-24  Eric Botcazou  <ebotcazou@libertysurf.fr>

	Patch from Richard Sandiford <rsandifo@redhat.com>
	* reload1.c (choose_reload_regs): Prevent the find_equiv_reg() code
	from inheriting a subreg equivalence with a non-spill register.


-- 
Eric Botcazou
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.460
diff -u -p -r1.460 reload1.c
--- reload1.c	15 Jan 2005 16:06:16 -0000	1.460
+++ reload1.c	24 Jan 2005 07:41:50 -0000
@@ -5589,6 +5589,15 @@ choose_reload_regs (struct insn_chain *c
 		      gcc_assert (GET_CODE (equiv) == SUBREG);
 		      regno = subreg_regno (equiv);
 		      equiv = gen_rtx_REG (rld[r].mode, regno);
+		      /* If we choose EQUIV as the reload register, but the
+			 loop below decides to cancel the inheritance, we'll
+			 end up reloading EQUIV in rld[r].mode, not the mode
+			 it had originally.  That isn't safe when EQUIV isn't
+			 available as a spill register since its value might
+			 still be live at this point.  */
+		      for (i = regno; i < regno + (int) rld[r].nregs; i++)
+			if (TEST_HARD_REG_BIT (reload_reg_unavailable, i))
+			  equiv = 0;
 		    }
 		}
 

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