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?] PR middle-end/13938: ICE in subst_stack_regs_pat


I'm not sure if this is the correct solution, but I'm posting this patch
to solicit comments on a proposed fix for PRs middle-end/13938 and
probably optimization/13839, which are both ICE on legal on x86.


The problem is that the x86's fix_truncdi* patterns want to be able
to allocate their own scatch register, and do this by clobbering an
FP reg so that they're assured of an empty slot in the register stack.

The code that handles these clobbers in reg-stack calls the function
"find_reg_note (insn, REG_UNUSED, *dest)" looking to confirm that the
register in *dest is indeed unused.  In the test case, however, the
REG_UNUSED note contains "(reg/v:DF 9 st(1) [orig:59 x ] [59])" but
*dest contains "(reg:DF 9 st(1))".

Unfortunately, find_reg_note uses pointer equality when looking for
a particular datum, and although these both describe exactly the same
register, find_reg_note returns NULL, and we trigger the abort.


The obvious question, to which I don't know the answer, is whether
these two hard register RTXs *must* always be shared?  Clearly one
has aliasing and variable tracking information and the other doesn't.
Looking at reg-stack.c, I see that initialization of the top-level
"reg-to-stack" contains multiple calls to gen_rtx_REG:

>  /* Create the replacement registers up front.  */
>  for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
>    FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);

So my assumption is that the reg-stack pass can't expect/assume strict
pointer equality/shared RTL, if it's creating the problematic register
RTXs itself.


The following patch implements the minimum change, such that if the
existing code fails to find an exact REG_UNUSED note, it makes a
second attempt to retrieve the first REG_UNUSED note and checks whether
its contents are rtx_equal to what we are looking for.  If this second
"fuzzy" match fails, "two strikes and you're out", we call abort as
before.

This fix should be extremely safe, even if it isn't elegant, as it
only affects code that would have previously have called abort.
Searching bugzilla it looks like new-ra has also triped the same ICE.


Is this the correct fix?  If not, what is?


The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all languages except treelang, and regression tested
with a top-level "make -k check" with no new failures.

Ok for mainline?



2004-02-01  Roger Sayle  <roger@eyesopen.com>

	PR middle-end/13938
	PR optimization/13839
	* reg-stack.c (subst_stack_regs_pat): Handle unshared REG rtxes
	when checking/search for REG_UNUSED notes.

	* gcc.c-torture/compile/20040201-1.c: New test case.


Index: reg-stack.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reg-stack.c,v
retrieving revision 1.141
diff -c -3 -p -r1.141 reg-stack.c
*** reg-stack.c	21 Jan 2004 20:40:03 -0000	1.141
--- reg-stack.c	1 Feb 2004 04:12:02 -0000
*************** subst_stack_regs_pat (rtx insn, stack re
*** 1427,1433 ****
  		  {
  		    note = find_reg_note (insn, REG_UNUSED, *dest);
  		    if (!note)
! 		      abort ();
  		  }
  		remove_note (insn, note);
  		replace_reg (dest, FIRST_STACK_REG + 1);
--- 1427,1438 ----
  		  {
  		    note = find_reg_note (insn, REG_UNUSED, *dest);
  		    if (!note)
! 		      {
! 			/* Sometimes the REG rtx isn't shared.  */
! 			note = find_reg_note (insn, REG_UNUSED, 0);
! 			if (!note || !rtx_equal_p (XEXP (note, 0), *dest))
! 			  abort ();
! 		      }
  		  }
  		remove_note (insn, note);
  		replace_reg (dest, FIRST_STACK_REG + 1);


/* PR middle-end/13938  */
/* The following code used to cause an ICE in subst_stack_regs_pat in
   reg-stack.c.  */

long long d2ll(double x)
{
        return (long long)(x>0?(x-0.5):(x+0.5));
}


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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