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]

Fix PR rtl-optimization/16028 (reload inheritance)


Hi,

This is again the reload inheritance bug I ran into with the ACATS testsuite 
on i586.  Fariborz recently ran into it too, but with C code on PowerPC.

Description: http://gcc.gnu.org/ml/gcc-patches/2004-04/msg01779.html
Discussion (Joern): http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00061.html

How reload inheritance works appears to be a little unclear, especially its 
failure mode.  So I think a step in the right direction could be to make 
sure that both tests use the same criterion to determine whether a (spill) 
reg is suitable for inheritance.

The patch was bootstrapped/regtested on i586-redhat-linux-gnu by me and on 
ppc-darwin by Fariborz.  Fariborz also ran SPEC on G5 and saw no performance 
degradation.   OK for mainline?


2004-06-21  Eric Botcazou  <ebotcazou@act-europe.fr>

	PR rtl-optimization/16028
        * reload1.c (choose_reload_regs): When searching for an
        equivalent reload register, always check that it is free
	for the value being reloaded.


2004-06-21  Fariborz Jahanian  <fjahanian@apple.com>

	* gcc.c-torture/execute/20040621-1.c: New test.


-- 
Eric Botcazou
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.437
diff -c -p -r1.437 reload1.c
*** reload1.c	15 Jun 2004 18:02:34 -0000	1.437
--- reload1.c	20 Jun 2004 13:41:59 -0000
*************** choose_reload_regs (struct insn_chain *c
*** 5638,5664 ****
  		    abort ();
  		}
  
! 	      /* If we found a spill reg, reject it unless it is free
! 		 and of the desired class.  */
  	      if (equiv != 0)
  		{
- 		  int regs_used = 0;
  		  int bad_for_class = 0;
  		  int max_regno = regno + rld[r].nregs;
  
  		  for (i = regno; i < max_regno; i++)
! 		    {
! 		      regs_used |= TEST_HARD_REG_BIT (reload_reg_used_at_all,
! 						      i);
! 		      bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
! 							   i);
! 		    }
  
! 		  if ((regs_used
! 		       && ! free_for_value_p (regno, rld[r].mode,
! 					      rld[r].opnum, rld[r].when_needed,
! 					      rld[r].in, rld[r].out, r, 1))
! 		      || bad_for_class)
  		    equiv = 0;
  		}
  
--- 5638,5658 ----
  		    abort ();
  		}
  
! 	      /* If we found a spill reg, reject it unless it is of the
! 		 desired class and free.  */
  	      if (equiv != 0)
  		{
  		  int bad_for_class = 0;
  		  int max_regno = regno + rld[r].nregs;
  
  		  for (i = regno; i < max_regno; i++)
! 		    bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
! 							  i);
  
! 		  if (bad_for_class
! 		      || ! free_for_value_p (regno, rld[r].mode,
! 					     rld[r].opnum, rld[r].when_needed,
! 					     rld[r].in, rld[r].out, r, 1))
  		    equiv = 0;
  		}
  
/* PR rtl-optimization/16028 */
/* Origin: Fariborz Jahanian <fjahanian@apple.com> */

typedef short __attribute__ ((vector_size (16))) vecint;

vecint i = { 150, 100, 150, 200, 0, 0, 0, 0 };
vecint j = { 10, 13, 20, 30, 1, 1, 1, 1 };
vecint k;

union {
  vecint v;
  short i[8];
} res;

void
verify (int a1, int b1)
{
  if (a1 != b1)
    abort ();
}

int
main ()
{
  k = i + j;
  res.v = k;

  verify (res.i[0], 160);

  k = i & j; /* bad code gen for this statement causes the abort. */
  res.v = k;
  verify (res.i[0], 2);

  k = i * j;
  res.v = k;
  verify (res.i[0], 1500);

  exit (0);
}

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