diff options
author | Michael Matz <matz@suse.de> | 2024-08-22 17:09:11 +0200 |
---|---|---|
committer | Michael Matz <matz@suse.de> | 2024-08-27 15:31:28 +0200 |
commit | 542773888190ef67dca194f4861abab104fa9b5b (patch) | |
tree | 5f920f3f68783db9fdf27e403a19516f60bd276b /gcc | |
parent | 359209bdc7245f8768b5044acded8509545e4990 (diff) | |
download | gcc-542773888190ef67dca194f4861abab104fa9b5b.zip gcc-542773888190ef67dca194f4861abab104fa9b5b.tar.gz gcc-542773888190ef67dca194f4861abab104fa9b5b.tar.bz2 |
LRA: Don't use 0 as initialization for sp_offset
this is part of making m68k work with LRA. See PR116374.
m68k has the property that sometimes the elimation offset
between %sp and %argptr is zero. During setting up elimination
infrastructure it's changes between sp_offset and previous_offset
that feed into insns_with_changed_offsets that ultimately will
setup looking at the instructions so marked.
But the initial values for sp_offset and previous_offset are
also zero. So if the targets INITIAL_ELIMINATION_OFFSET (called
in update_reg_eliminate) is zero then nothing changes, the
instructions in question don't get into the list to consider and
the sp_offset tracking goes wrong.
Solve this by initializing those member with -1 instead of zero.
An initial offset of that value seems very unlikely, as it's
in word-sized increments. This then also reveals a problem in
eliminate_regs_in_insn where it always uses sp_offset-previous_offset
as offset adjustment, even in the first_p pass. That was harmless
when previous_offset was uninitialized as zero. But all the other
code uses a different idiom of checking for first_p (or rather
update_p which is !replace_p&&!first_p), and using sp_offset directly.
So use that as well in eliminate_regs_in_insn.
PR target/116374
* lra-eliminations.cc (init_elim_table): Use -1 as initializer.
(update_reg_eliminate): Accept -1 as not-yet-used marker.
(eliminate_regs_in_insn): Use previous_sp_offset only when
not first_p.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/lra-eliminations.cc | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index 5bed259c..96772f2 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -969,7 +969,8 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, if (! replace_p) { if (known_eq (update_sp_offset, 0)) - offset += (ep->offset - ep->previous_offset); + offset += (!first_p + ? ep->offset - ep->previous_offset : ep->offset); if (ep->to_rtx == stack_pointer_rtx) { if (first_p) @@ -1212,7 +1213,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) if (lra_dump_file != NULL) fprintf (lra_dump_file, " Using elimination %d to %d now\n", ep1->from, ep1->to); - lra_assert (known_eq (ep1->previous_offset, 0)); + lra_assert (known_eq (ep1->previous_offset, -1)); ep1->previous_offset = ep->offset; } else @@ -1283,7 +1284,7 @@ init_elim_table (void) for (ep = reg_eliminate, ep1 = reg_eliminate_1; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++) { - ep->offset = ep->previous_offset = 0; + ep->offset = ep->previous_offset = -1; ep->from = ep1->from; ep->to = ep1->to; value_p = (targetm.can_eliminate (ep->from, ep->to) |