combine: Don't record for UNDO_MODE pointers into regno_reg_rtx array [PR104985]
The testcase in the PR fails under valgrind on mips64 (but only Martin can reproduce, I couldn't). But the problem reported there is that SUBST_MODE remembers addresses into the regno_reg_rtx array, then some splitter needs a new pseudo and calls gen_reg_rtx, which reallocates the regno_reg_rtx array and finally undo operation is done and dereferences the old regno_reg_rtx entry. The rtx values stored in regno_reg_rtx array seems to be created by gen_reg_rtx only and since then aren't modified, all we do for it is adjusting its fields (e.g. adjust_reg_mode that SUBST_MODE does). So, I think it is useless to use where.r for UNDO_MODE and store ®no_reg_rtx[regno] in struct undo, we can store just regno_reg_rtx[regno] (i.e. pointer to the REG itself instead of pointer to pointer to REG) or could also store just the regno. The following patch does the latter, and because SUBST_MODE no longer needs to be a macro, changes all SUBST_MODE uses to subst_mode. 2022-04-06 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/104985 * combine.cc (struct undo): Add where.regno member. (do_SUBST_MODE): Rename to ... (subst_mode): ... this. Change first argument from rtx * into int, operate on regno_reg_rtx[regno] and save regno into where.regno. (SUBST_MODE): Remove. (try_combine): Use subst_mode instead of SUBST_MODE, change first argument from regno_reg_rtx[whatever] to whatever. For UNDO_MODE, use regno_reg_rtx[undo->where.regno] instead of *undo->where.r. (undo_to_marker): For UNDO_MODE, use regno_reg_rtx[undo->where.regno] instead of *undo->where.r. (simplify_set): Use subst_mode instead of SUBST_MODE, change first argument from regno_reg_rtx[whatever] to whatever.
This commit is contained in:
parent
9fd377a747
commit
61bee6aed2
1 changed files with 13 additions and 13 deletions
|
@ -382,7 +382,7 @@ struct undo
|
|||
struct undo *next;
|
||||
enum undo_kind kind;
|
||||
union { rtx r; int i; machine_mode m; struct insn_link *l; } old_contents;
|
||||
union { rtx *r; int *i; struct insn_link **l; } where;
|
||||
union { rtx *r; int *i; int regno; struct insn_link **l; } where;
|
||||
};
|
||||
|
||||
/* Record a bunch of changes to be undone, up to MAX_UNDO of them.
|
||||
|
@ -761,10 +761,11 @@ do_SUBST_INT (int *into, int newval)
|
|||
well. */
|
||||
|
||||
static void
|
||||
do_SUBST_MODE (rtx *into, machine_mode newval)
|
||||
subst_mode (int regno, machine_mode newval)
|
||||
{
|
||||
struct undo *buf;
|
||||
machine_mode oldval = GET_MODE (*into);
|
||||
rtx reg = regno_reg_rtx[regno];
|
||||
machine_mode oldval = GET_MODE (reg);
|
||||
|
||||
if (oldval == newval)
|
||||
return;
|
||||
|
@ -775,15 +776,13 @@ do_SUBST_MODE (rtx *into, machine_mode newval)
|
|||
buf = XNEW (struct undo);
|
||||
|
||||
buf->kind = UNDO_MODE;
|
||||
buf->where.r = into;
|
||||
buf->where.regno = regno;
|
||||
buf->old_contents.m = oldval;
|
||||
adjust_reg_mode (*into, newval);
|
||||
adjust_reg_mode (reg, newval);
|
||||
|
||||
buf->next = undobuf.undos, undobuf.undos = buf;
|
||||
}
|
||||
|
||||
#define SUBST_MODE(INTO, NEWVAL) do_SUBST_MODE (&(INTO), (NEWVAL))
|
||||
|
||||
/* Similar to SUBST, but NEWVAL is a LOG_LINKS expression. */
|
||||
|
||||
static void
|
||||
|
@ -3186,7 +3185,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
|
|||
newpat_dest = gen_rtx_REG (compare_mode, regno);
|
||||
else
|
||||
{
|
||||
SUBST_MODE (regno_reg_rtx[regno], compare_mode);
|
||||
subst_mode (regno, compare_mode);
|
||||
newpat_dest = regno_reg_rtx[regno];
|
||||
}
|
||||
}
|
||||
|
@ -3576,7 +3575,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
|
|||
ni2dest = gen_rtx_REG (new_mode, REGNO (i2dest));
|
||||
else
|
||||
{
|
||||
SUBST_MODE (regno_reg_rtx[REGNO (i2dest)], new_mode);
|
||||
subst_mode (REGNO (i2dest), new_mode);
|
||||
ni2dest = regno_reg_rtx[REGNO (i2dest)];
|
||||
}
|
||||
|
||||
|
@ -3712,7 +3711,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
|
|||
newdest = gen_rtx_REG (split_mode, REGNO (i2dest));
|
||||
else
|
||||
{
|
||||
SUBST_MODE (regno_reg_rtx[REGNO (i2dest)], split_mode);
|
||||
subst_mode (REGNO (i2dest), split_mode);
|
||||
newdest = regno_reg_rtx[REGNO (i2dest)];
|
||||
}
|
||||
}
|
||||
|
@ -4082,7 +4081,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
|
|||
for (undo = undobuf.undos; undo; undo = undo->next)
|
||||
if (undo->kind == UNDO_MODE)
|
||||
{
|
||||
rtx reg = *undo->where.r;
|
||||
rtx reg = regno_reg_rtx[undo->where.regno];
|
||||
machine_mode new_mode = GET_MODE (reg);
|
||||
machine_mode old_mode = undo->old_contents.m;
|
||||
|
||||
|
@ -4755,7 +4754,8 @@ undo_to_marker (void *marker)
|
|||
*undo->where.i = undo->old_contents.i;
|
||||
break;
|
||||
case UNDO_MODE:
|
||||
adjust_reg_mode (*undo->where.r, undo->old_contents.m);
|
||||
adjust_reg_mode (regno_reg_rtx[undo->where.regno],
|
||||
undo->old_contents.m);
|
||||
break;
|
||||
case UNDO_LINKS:
|
||||
*undo->where.l = undo->old_contents.l;
|
||||
|
@ -6819,7 +6819,7 @@ simplify_set (rtx x)
|
|||
new_dest = gen_rtx_REG (compare_mode, regno);
|
||||
else
|
||||
{
|
||||
SUBST_MODE (regno_reg_rtx[regno], compare_mode);
|
||||
subst_mode (regno, compare_mode);
|
||||
new_dest = regno_reg_rtx[regno];
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue