This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fwd: Possible fix for target/8812 (register allocation bug)
- From: Jim Wilson <wilson at tuliptree dot org>
- To: Michael Rendell <michaelgcc at mytelescope dot com>
- Cc: gcc-patches at gcc dot gnu dot org, wilson at tulitpree dot org
- Date: Mon, 09 Jun 2003 23:02:05 -0700
- Subject: Re: Fwd: Possible fix for target/8812 (register allocation bug)
- References: <200305222132.15279.michaelgcc@mytelescope.com>
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;