This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/37296] [4.4 Regression] Bootstrap failure compiling libgcc
- From: "ebotcazou at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 2 Sep 2008 17:35:01 -0000
- Subject: [Bug rtl-optimization/37296] [4.4 Regression] Bootstrap failure compiling libgcc
- References: <bug-37296-10110@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #19 from ebotcazou at gcc dot gnu dot org 2008-09-02 17:35 -------
> I've looked at the cgraphbuild.i code and I think something is wrong with
> inlining. There are two paths achieving L21 with different stack adjustments.
> Here is the code. I marked insns adjusting SP by -> and the two insns should
> refer to the same location by !
Isn't that supposed to be detected by reload?
/* For each label, we record the offset of each elimination. If we reach
a label by more than one path and an offset differs, we cannot do the
elimination. This information is indexed by the difference of the
number of the label and the first label number. We can't offset the
pointer itself as this can cause problems on machines with segmented
memory. The first table is an array of flags that records whether we
have yet encountered a label and the second table is an array of arrays,
one entry in the latter array for each elimination. */
static int first_label_num;
static char *offsets_known_at;
static HOST_WIDE_INT (*offsets_at)[NUM_ELIMINABLE_REGS];
/* This function handles the tracking of elimination offsets around branches.
X is a piece of RTL being scanned.
INSN is the insn that it came from, if any.
INITIAL_P is nonzero if we are to set the offset to be the initial
offset and zero if we are setting the offset of the label to be the
current offset. */
static void
set_label_offsets (rtx x, rtx insn, int initial_p)
{
enum rtx_code code = GET_CODE (x);
rtx tem;
unsigned int i;
struct elim_table *p;
switch (code)
{
case LABEL_REF:
if (LABEL_REF_NONLOCAL_P (x))
return;
x = XEXP (x, 0);
/* ... fall through ... */
case CODE_LABEL:
/* If we know nothing about this label, set the desired offsets. Note
that this sets the offset at a label to be the offset before a label
if we don't know anything about the label. This is not correct for
the label after a BARRIER, but is the best guess we can make. If
we guessed wrong, we will suppress an elimination that might have
been possible had we been able to guess correctly. */
if (! offsets_known_at[CODE_LABEL_NUMBER (x) - first_label_num])
{
for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
offsets_at[CODE_LABEL_NUMBER (x) - first_label_num][i]
= (initial_p ? reg_eliminate[i].initial_offset
: reg_eliminate[i].offset);
offsets_known_at[CODE_LABEL_NUMBER (x) - first_label_num] = 1;
}
/* Otherwise, if this is the definition of a label and it is
preceded by a BARRIER, set our offsets to the known offset of
that label. */
else if (x == insn
&& (tem = prev_nonnote_insn (insn)) != 0
&& BARRIER_P (tem))
set_offsets_for_label (insn);
else
/* If neither of the above cases is true, compare each offset
with those previously recorded and suppress any eliminations
where the offsets disagree. */
for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
if (offsets_at[CODE_LABEL_NUMBER (x) - first_label_num][i]
!= (initial_p ? reg_eliminate[i].initial_offset
: reg_eliminate[i].offset))
reg_eliminate[i].can_eliminate = 0;
return;
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37296