This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: More bug in reload_reg_free_for_value_p in reload1.c
- To: hjl at lucon dot org (H.J. Lu)
- Subject: Re: More bug in reload_reg_free_for_value_p in reload1.c
- From: Joern Rennecke <amylaar at cygnus dot co dot uk>
- Date: Tue, 2 Jun 1998 20:55:00 +0100 (BST)
- Cc: egcs at cygnus dot com, libc-hacker at cygnus dot com, law at cygnus dot com, wilson at cygnus dot com
> Hi,
>
> There is another bug in reload_reg_free_for_value_p in reload1.c. The
> result is manager.c in linuxthreads is miscompiled on x86. I am
> enclosing 3 files here. manager1.c, ok.S and bad.S. bad.S is compiled
> from manager1.c with -fPIC -march=pentium -mcpu=pentium -S -O and ok.S
> is bad.S plus a fix by hand.
>
> If I backed out the reload_reg_free_for_value_p change, manager1.c is
> compiled fine.
Thanks.
I have appended a patch. Does this fix your problem?
Jim, Jeff, can this go in?
Tue Jun 2 20:51:57 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* reload1.c (reload_reg_free_for_value_p): New arguments out and
reloadnum. Changed all callers.
Index: reload1.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/reload1.c,v
retrieving revision 1.33
diff -p -r1.33 reload1.c
*** reload1.c 1998/05/21 11:52:31 1.33
--- reload1.c 1998/06/02 19:52:12
*************** static void clear_reload_reg_in_use PROT
*** 378,384 ****
enum machine_mode));
static int reload_reg_free_p PROTO((int, int, enum reload_type));
static int reload_reg_free_before_p PROTO((int, int, enum reload_type));
! static int reload_reg_free_for_value_p PROTO((int, int, enum reload_type, rtx));
static int reload_reg_reaches_end_p PROTO((int, int, enum reload_type));
static int allocate_reload_reg PROTO((int, rtx, int, int));
static void choose_reload_regs PROTO((rtx, rtx));
--- 378,384 ----
enum machine_mode));
static int reload_reg_free_p PROTO((int, int, enum reload_type));
static int reload_reg_free_before_p PROTO((int, int, enum reload_type));
! static int reload_reg_free_for_value_p PROTO((int, int, enum reload_type, rtx, rtx, int));
static int reload_reg_reaches_end_p PROTO((int, int, enum reload_type));
static int allocate_reload_reg PROTO((int, rtx, int, int));
static void choose_reload_regs PROTO((rtx, rtx));
*************** int reload_spill_index[MAX_RELOADS];
*** 4983,4997 ****
/* Return 1 if the value in reload reg REGNO, as used by a reload
needed for the part of the insn specified by OPNUM and TYPE,
may be used to load VALUE into it.
! Other read-only reloads with the same value do not conflict.
The caller has to make sure that there is no conflict with the return
register. */
static int
! reload_reg_free_for_value_p (regno, opnum, type, value)
int regno;
int opnum;
enum reload_type type;
! rtx value;
{
int time1;
int i;
--- 4983,5002 ----
/* Return 1 if the value in reload reg REGNO, as used by a reload
needed for the part of the insn specified by OPNUM and TYPE,
may be used to load VALUE into it.
! Other read-only reloads with the same value do not conflict,
! unless OUT is non-zero and these other reloads have to life while
! output reloads live.
! RELOADNUM is the number of the reload we want to load this value for;
! that reload does not conflict with itself.
The caller has to make sure that there is no conflict with the return
register. */
static int
! reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum)
int regno;
int opnum;
enum reload_type type;
! rtx value, out;
! int reloadnum;
{
int time1;
int i;
*************** reload_reg_free_for_value_p (regno, opnu
*** 5048,5086 ****
if (reg && GET_CODE (reg) == REG
&& ((unsigned) regno - true_regnum (reg)
<= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - 1U)
! && (! reload_in[i] || ! rtx_equal_p (reload_in[i], value)
! || reload_out[i]))
{
! int time2;
! switch (reload_when_needed[i])
{
! case RELOAD_FOR_OTHER_ADDRESS:
! time2 = 0;
! break;
! case RELOAD_FOR_INPADDR_ADDRESS:
! time2 = reload_opnum[i] * 4 + 1;
! break;
! case RELOAD_FOR_INPUT_ADDRESS:
! time2 = reload_opnum[i] * 4 + 2;
! break;
! case RELOAD_FOR_INPUT:
! time2 = reload_opnum[i] * 4 + 3;
! break;
! case RELOAD_FOR_OUTPUT:
! /* All RELOAD_FOR_OUTPUT reloads become live just after the
! instruction is executed. */
! time2 = MAX_RECOG_OPERANDS * 4;
! break;
! /* The first RELOAD_FOR_OUTPUT_ADDRESS reload conflicts with the
! RELOAD_FOR_OUTPUT reloads, so assign it the same time value. */
! case RELOAD_FOR_OUTPUT_ADDRESS:
! time2 = MAX_RECOG_OPERANDS * 4 + reload_opnum[i];
! break;
! default:
! time2 = 0;
}
- if (time1 >= time2)
- return 0;
}
}
return 1;
--- 5053,5105 ----
if (reg && GET_CODE (reg) == REG
&& ((unsigned) regno - true_regnum (reg)
<= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - 1U)
! && i != reloadnum)
{
! if (out
! && reload_when_needed[i] != RELOAD_FOR_INPUT
! && reload_when_needed[i] != RELOAD_FOR_INPUT_ADDRESS
! && reload_when_needed[i] != RELOAD_FOR_INPADDR_ADDRESS)
! return 0;
! if (! reload_in[i] || ! rtx_equal_p (reload_in[i], value)
! || reload_out[i])
{
! int time2;
! switch (reload_when_needed[i])
! {
! case RELOAD_FOR_OTHER_ADDRESS:
! time2 = 0;
! break;
! case RELOAD_FOR_INPADDR_ADDRESS:
! time2 = reload_opnum[i] * 4 + 1;
! break;
! case RELOAD_FOR_INPUT_ADDRESS:
! time2 = reload_opnum[i] * 4 + 2;
! break;
! case RELOAD_FOR_INPUT:
! time2 = reload_opnum[i] * 4 + 3;
! break;
! case RELOAD_FOR_OUTPUT:
! /* All RELOAD_FOR_OUTPUT reloads become live just after the
! instruction is executed. */
! time2 = MAX_RECOG_OPERANDS * 4;
! break;
! /* The first RELOAD_FOR_OUTPUT_ADDRESS reload conflicts with the
! RELOAD_FOR_OUTPUT reloads, so assign it the same time value. */
! case RELOAD_FOR_OUTPUT_ADDRESS:
! time2 = MAX_RECOG_OPERANDS * 4 + reload_opnum[i];
! break;
! case RELOAD_OTHER:
! if (! reload_in[i] || rtx_equal_p (reload_in[i], value))
! {
! time2 = MAX_RECOG_OPERANDS * 4;
! break;
! }
! default:
! time2 = 0;
! }
! if (time1 >= time2)
! return 0;
}
}
}
return 1;
*************** allocate_reload_reg (r, insn, last_reloa
*** 5160,5173 ****
if ((reload_reg_free_p (spill_regs[i], reload_opnum[r],
reload_when_needed[r])
! || (reload_in[r] && ! reload_out[r]
/* We check reload_reg_used to make sure we
don't clobber the return register. */
&& ! TEST_HARD_REG_BIT (reload_reg_used, spill_regs[i])
&& reload_reg_free_for_value_p (spill_regs[i],
reload_opnum[r],
reload_when_needed[r],
! reload_in[r])))
&& TEST_HARD_REG_BIT (reg_class_contents[class], spill_regs[i])
&& HARD_REGNO_MODE_OK (spill_regs[i], reload_mode[r])
/* Look first for regs to share, then for unshared. But
--- 5179,5193 ----
if ((reload_reg_free_p (spill_regs[i], reload_opnum[r],
reload_when_needed[r])
! || (reload_in[r]
/* We check reload_reg_used to make sure we
don't clobber the return register. */
&& ! TEST_HARD_REG_BIT (reload_reg_used, spill_regs[i])
&& reload_reg_free_for_value_p (spill_regs[i],
reload_opnum[r],
reload_when_needed[r],
! reload_in[r],
! reload_out[r], r)))
&& TEST_HARD_REG_BIT (reg_class_contents[class], spill_regs[i])
&& HARD_REGNO_MODE_OK (spill_regs[i], reload_mode[r])
/* Look first for regs to share, then for unshared. But
*************** choose_reload_regs (insn, avoid_return_r
*** 5634,5640 ****
reload_when_needed[r]))
|| reload_reg_free_for_value_p (i, reload_opnum[r],
reload_when_needed[r],
! reload_in[r])))
{
/* If a group is needed, verify that all the subsequent
registers still have their values intact. */
--- 5654,5661 ----
reload_when_needed[r]))
|| reload_reg_free_for_value_p (i, reload_opnum[r],
reload_when_needed[r],
! reload_in[r],
! reload_out[r], r)))
{
/* If a group is needed, verify that all the subsequent
registers still have their values intact. */
*************** choose_reload_regs (insn, avoid_return_r
*** 5741,5747 ****
|| reload_reg_free_for_value_p (regno,
reload_opnum[r],
reload_when_needed[r],
! reload_in[r])))
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
regno)))
equiv = 0;
--- 5762,5769 ----
|| reload_reg_free_for_value_p (regno,
reload_opnum[r],
reload_when_needed[r],
! reload_in[r],
! reload_out[r], r)))
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
regno)))
equiv = 0;
*************** choose_reload_regs (insn, avoid_return_r
*** 5924,5930 ****
|| reload_reg_free_for_value_p (true_regnum (reload_reg_rtx[r]),
reload_opnum[r],
reload_when_needed[r],
! reload_in[r])))
reload_inherited[r] = 0;
/* If we can inherit a RELOAD_FOR_INPUT, then we do not need its related
RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads.
--- 5946,5953 ----
|| reload_reg_free_for_value_p (true_regnum (reload_reg_rtx[r]),
reload_opnum[r],
reload_when_needed[r],
! reload_in[r],
! reload_out[r], r)))
reload_inherited[r] = 0;
/* If we can inherit a RELOAD_FOR_INPUT, then we do not need its related
RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads.