lra: Stop registers being incorrectly marked live [PR92989]
authorRichard Sandiford <richard.sandiford@arm.com>
Sat, 18 Jan 2020 12:41:48 +0000 (12:41 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Mon, 27 Jan 2020 10:53:35 +0000 (10:53 +0000)
commite648e57efca6ce6d751ef8c2038608817b514fb4
treeff7b9ee6a3e7cf26d5e69879b49944a56cc9c99f
parent150760dd6dd1899705790183d646fa5fc004554e
lra: Stop registers being incorrectly marked live [PR92989]

lra_assign has an assert to make sure that no pseudo is allocated
to a conflicting hard register.  It used to be restricted to
!flag_ipa_ra, but in g:a1e6ee38e708ef2bdef4 I'd enabled it for
flag_ipa_ra too.  It then tripped while building libstdc++
for mips-mti-linux.

The failure was due to code at the end of process_bb_lives.  For an
abnormal/EH edge, we need to make sure that all pseudos that are live
on entry to the destination conflict with all hard registers that are
clobbered by an abnormal call return.  The usual way to do this would
be to simulate a clobber of the hard registers, by making them live and
them making them dead again.  Making the registers live creates the
conflict; making them dead again restores the correct live set for
whatever follows.

However, process_bb_lives skips the second step (making the registers
dead again) at the start of a BB, presumably on the basis that there's
no further code that needs a correct live set.  The problem for the PR
is that that wasn't quite true in practice.  There was code further
down process_bb_lives that updated the live-in set of the BB for some
registers, and this live set was "contaminated" by registers that
weren't live but that created conflicts.  This information then got
propagated to other blocks, so that registers that were made live
purely to create a conflict at the start of the EH receiver then became
needlessly live throughout preceding blocks.  This in turn created a
fake conflict with pseudos in those blocks, invalidating the choices
made by IRA.

The easiest fix seems to be to update the live-in set *before* adding
the fake live registers.  An alternative would be to simulate the full
clobber, but that seems a bit wasteful.

2020-01-27  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
PR rtl-optimization/92989
* lra-lives.c (process_bb_lives): Update the live-in set before
processing additional clobbers.
gcc/ChangeLog
gcc/lra-lives.c