This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Yet another reload_reg_free_for_value_p bug
- To: gcc-patches at gcc dot gnu dot org
- Subject: Yet another reload_reg_free_for_value_p bug
- From: Bernd Schmidt <bernds at cygnus dot co dot uk>
- Date: Tue, 21 Sep 1999 13:23:55 +0100 (BST)
This showed up in a bug report for one of the Cygnus toolchains.
Unfortunately, I don't have a test case that can be used to reproduce the
problem with the current gcc.
The situation is as follows (it's an i386 toolchain):
reg_last_reload_reg[59] == %edx
Reload 0: reload_in (SI) = (reg:SI 59)
GENERAL_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 1)
reload_in_reg: (reg:SI 59)
Reload 1: reload_in (SI) = (reg/v:SI 5 %edi)
reload_out (SI) = (reg/v:SI 1 %edx)
DREG, RELOAD_OTHER (opnum = 0)
reload_in_reg: (reg/v:SI 5 %edi)
reload_out_reg: (reg/v:SI 1 %edx)
reload_reg_rtx: (reg/v:SI 1 %edx)
Reload 2: reload_in (SI) = (mem/f:SI (reg:SI 59) 0)
reload_out (SI) = (reg/v:SI 62)
CREG, RELOAD_OTHER (opnum = 1)
reload_in_reg: (mem/f:SI (reg:SI 59) 0)
reload_out_reg: (reg/v:SI 62)
choose_reloads goes on and selects %ecx for reload 2 and %edx for reload 1
(it doesn't have a choice). Things go wrong when it tries to find a
register for reload 0. Since the value of reg 59 is still lying around in
%edx (see reg_last_reload_reg), it tries to use that as reload register. To
determine whether that's valid, it calls reload_reg_free_for_value_p. This
function fails to see that reload 0 conflicts with reload 1, and returns 1
to indicate that it's perfectly OK to use %edx - which is wrong.
The patch below changes reload_reg_free_for_value_p to correct this
(reloads_conflict already shows that RELOAD_FOR_OTHER_ADDRESS reloads
conflict with RELOAD_OTHER reloads).
Bernd
* reload1.c (reload_reg_free_for_value_p): Show
RELOAD_FOR_OTHER_ADDRESS reloads can conflict with RELOAD_OTHER
reloads.
Index: reload1.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/reload1.c,v
retrieving revision 1.166
diff -u -p -r1.166 reload1.c
--- reload1.c 1999/09/20 09:59:51 1.166
+++ reload1.c 1999/09/21 12:17:48
@@ -5230,7 +5230,7 @@ reload_reg_free_for_value_p (regno, opnu
switch (type)
{
case RELOAD_FOR_OTHER_ADDRESS:
- time1 = 0;
+ time1 = copy ? 0 : 1;
break;
case RELOAD_OTHER:
time1 = copy ? 1 : MAX_RECOG_OPERANDS * 5 + 5;