This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: c/7871: ICE on legal code, global register variables problems
- From: Jim Wilson <wilson at tuliptree dot org>
- To: gcc-gnats at gcc dot gnu dot org, gcc-bugs at gcc dot gnu dot org, gcc-prs at gcc dot gnu dot org, rz at linux-m68k dot org, wilson at gcc dot gnu dot org, rth at redhat dot com
- Date: Thu, 27 Feb 2003 22:23:53 -0500
- Subject: Re: c/7871: ICE on legal code, global register variables problems
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=7871
PR 7871 was broken by this patch from Richard Henderson
http://gcc.gnu.org/ml/gcc-patches/2001-07/msg01050.html
This PR uses a global register, and a store to the global register
before a call gets deleted as a dead store.
The problem with this patch is that it doesn't distinguish between
regsters which are definitely set by calls, and registers which might be
set by calls. In both cases, we can't do optimizations like cse across
the call. However, only in the former case can we delete stores before
the call as dead. In the latter case, a store before the call is not
dead, because the register might not be set in the call.
I think every part of the patch is right except for the flow.c change.
The flow.c change marks global regs as killed by calls which is not
correct. They might be killed, but we can't assume that, because then
we might delete a store that isn't dead.
I propose the following patch to fix the bug. I will check it in after
running the tests, and add the testcase to the testsuite if there isn't
already an equivalent one.
Jim
2003-02-27 James E Wilson <wilson at tuliptree dot org>
* flow.c (propagate_one_insn): Don't assume that calls set global
registers.
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.548
diff -p -r1.548 flow.c
*** flow.c 31 Jan 2003 06:52:48 -0000 1.548
--- flow.c 28 Feb 2003 03:14:51 -0000
*************** propagate_one_insn (pbi, insn)
*** 1798,1806 ****
mark_set_1 (pbi, CLOBBER, XEXP (XEXP (note, 0), 0),
cond, insn, pbi->flags);
! /* Calls change all call-used and global registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
{
/* We do not want REG_UNUSED notes for these registers. */
mark_set_1 (pbi, CLOBBER, regno_reg_rtx[i], cond, insn,
--- 1798,1810 ----
mark_set_1 (pbi, CLOBBER, XEXP (XEXP (note, 0), 0),
cond, insn, pbi->flags);
! /* Calls change all call-used registers. Calls may or may not
! change global registers. Since this will cause previous stores
! to be deleted as dead, we must assume that global registers are
! not set in the call. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)
! && ! global_regs[i])
{
/* We do not want REG_UNUSED notes for these registers. */
mark_set_1 (pbi, CLOBBER, regno_reg_rtx[i], cond, insn,