416.gamess showed up two wrong-code bugs in early-ra. This patch
fixes the first of them. It was difficult to reduce the source code
to something that would meaningfully show the situation, so the
testcase uses a direct RTL sequence instead.
In the sequence:
(a) register <2> is set more than once
(b) register <2> is copied to a temporary (<4>)
(c) register <2> is the destination of an FCSEL between <4> and
another value (<5>)
(d) <4> and <2> are equivalent for <4>'s live range
(e) <5>'s and <2>'s live ranges do not intersect, and there is
a pseudo-copy between <5> and <2>
On its own, (d) implies that <4> can be treated as equivalent to <2>.
And on its own, (e) implies that <5> can share <2>'s register. But
<4>'s and <5>'s live ranges conflict, meaning that they cannot both
share the register together. A bit of missing bookkeeping meant that
the mechanism for detecting this didn't fire. We therefore ended up
with an FCSEL in which both inputs were the same register.
gcc/
PR target/113295
* config/aarch64/aarch64-early-ra.cc
(early_ra::find_related_start): Account for definitions by shared
registers when testing for a single register definition.
(early_ra::accumulate_defs): New function.
(early_ra::record_copy): If A shares B's register, fold A's
definition information into B's. Fold A's use information into B's.
gcc/testsuite/
PR target/113295
* gcc.dg/rtl/aarch64/pr113295-1.c: New test.