------- 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