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]

Re: Fwd: Possible fix for target/8812 (register allocation bug)


Michael Rendell wrote:
Am not sure that this is the correct fix - is this situation supposed to be
handled elsewhere?  If the fix is correct, other uses of TEST_HARD_REG_BIT()
are likely to suffer from the same problem.

This is the correct fix. This is a relatively common problem in reload, forgetting to verify all registers of a multi-reg hard register. We have already fixed a lot of these kinds of problems over the years. If you scan through reload, you will see that most tests are already inside a loop or near one. There may be more, but because of the complexity of reload, it is very risky to make any change without a testcase to justify it.


In addition to reload_reg_used_at_all, we also need to do the reg_class_contents check for every hard register. The reload convention is to do these tests with an in place loop, so I went ahead and wrote a patch to fix both problems that way.

This patch works for the avr testcase. It needs more testing though. My machine is tied up with powerpc testing today, so I will have to test this tomorrow.

Jim


2003-06-09  James E Wilson  <wilson@tuliptree.org>

	* reload1.c (choose_reload_regs): For equiv reg, add loop over all
	hard regs for reload_reg_used_at_all and reg_class_contents checks.

Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.395
diff -p -r1.395 reload1.c
*** reload1.c	7 Jun 2003 05:33:00 -0000	1.395
--- reload1.c	10 Jun 2003 05:48:24 -0000
*************** choose_reload_regs (chain)
*** 5685,5698 ****
  
  	      /* If we found a spill reg, reject it unless it is free
  		 and of the desired class.  */
! 	      if (equiv != 0
! 		  && ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno)
  		       && ! free_for_value_p (regno, rld[r].mode,
  					      rld[r].opnum, rld[r].when_needed,
  					      rld[r].in, rld[r].out, r, 1))
! 		      || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
! 					      regno)))
! 		equiv = 0;
  
  	      if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, rld[r].mode))
  		equiv = 0;
--- 5685,5711 ----
  
  	      /* 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;
! 		}
  
  	      if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, rld[r].mode))
  		equiv = 0;

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