PING.
Since Jeff is away can another maintainer have a look at this please?
Cheers,
Andre
On 01/02/2019 14:31, Andre Vieira (lists) wrote:
On 11/01/2019 22:54, Jeff Law wrote:
On 1/8/19 8:21 AM, Andre Vieira (lists) wrote:
On 07/01/2019 22:50, Jeff Law wrote:
On 1/7/19 7:42 AM, Andre Vieira (lists) wrote:
Hi,
This patch fixes the way 'uses_hard_regs_p' handles paradoxical
subregs.
The function is supposed to detect whether a register access of 'x'
overlaps with 'set'. For SUBREGs it should check whether any of the
full multi-register overlaps with 'set'. The former behavior used to
grab the widest mode of the inner/outer registers of a SUBREG and the
inner register, and check all registers from the inner-register
onwards
for the given width. For normal SUBREGS this gives you the full
register, for paradoxical SUBREGS however it may give you the wrong
set
of registers if the index is not the first of the multi-register set.
The original error reported in PR target/86487 can no longer be
reproduced with the given test, this was due to an unrelated code-gen
change, regardless I believe this should still be fixed as it is
simply
wrong behavior by uses_hard_regs_p which may be triggered by a
different
test-case or by future changes to the compiler. Also it is useful to
point out that this isn't actually a 'target' issue as this code could
potentially hit any other target using paradoxical SUBREGS. Should I
change the Bugzilla ticket to reflect this is actually a target
agnostic
issue in RTL?
There is a gotcha here, I don't know what would happen if you hit the
cases of get_hard_regno where it would return -1, quoting the comment
above that function "If X is not a register or a subreg of a register,
return -1." though I think if we are hitting this then things must
have
gone wrong before?
Bootstrapped on aarch64, arm and x86, no regressions.
Is this OK for trunk?
gcc/ChangeLog:
2019-01-07 Andre Vieira <andre.simoesdiasvie...@arm.com>
PR target/86487
* lra-constraints.c(uses_hard_regs_p): Fix handling of
paradoxical SUBREGS.
But doesn't wider_subreg_mode give us the wider of the two modes here
and we use that wider mode when we call overlaps_hard_reg_set_p which
should ultimately check all the registers in the paradoxical.
I must be missing something here?!?
jeff
Hi Jeff,
It does give us the wider of the two modes, but we also then grab the
"subreg" of the paradoxical subreg. If you look at the first example
case of the bugzilla ticket, for an older gcc (say gcc-8) and the
options provided (using big-endian), it will generate the following
subreg:
(subreg:DI (reg:SI 122) 0)
This paradoxical subreg represents a register pair r0-r1, where because
of big-endian and subgreg index 0, r1 is the value we care about and r0
the one we say "it can be whatever" by using this paradoxical subreg.
When 'uses_hard_regs_p' sees this as a subreg, it sets 'mode' to the
wider, i.e. DImode, but it also sets 'x' to the subreg i.e. 'reg:SI
122', for which get_hard_regno correctly returns 'r1'. But if you now
pass 'overlaps_hard_reg_set_p' DImode and 'r1', it will check whether
'set' contains either 'r1-r2', and not 'r1'r0'.
To reproduce this again I now applied this patch to GCC 8 and found an
issue with it. 'REG_P (x)' returns false if x is a 'SUBREG'. So I will
need to change the later check to also include 'SUBREG_P (x)', I guess I
was testing with a too new version of gcc that didn't lead to the bogus
register allocation...
Which really encourages me to add some sort of testcase, but I'd very
much like to come up with a less flaky one, we basically need to force
the generation of a paradoxical subreg 'x', where 'get_hard_regno
(SUBREG_REG (x)) != get_hard_regno (x)'. This will cause
'uses_hard_regs_p' to give you a wrong answer.
BTW, you might look at 87305 which is another problem with big endian
pseudos and paradoxical subregs that Vlad just fixed.
jeff
Hi Jeff,
Thank you, I had a look but I don't think it is the same issue and even
though I can no longer reproduce this particular issue on trunk I do
believe the latent fault is still there and I would like to fix it.
As I mentioned in the earlier emails I forgot to make sure 'SUBREG_P
(x)' was also handled where we previously only accepted 'REG_P (x)' as
we would always strip away the parent subreg. I have also added the
testcase that triggered this issue on arm in previous GCC versions. This
does not trigger it on trunk any more due to other codegen changes.
Bootstrapped on aarch64, arm and x86, no regressions.
Is this OK for trunk?
gcc/ChangeLog:
2019-02-01 Andre Vieira <andre.simoesdiasvie...@arm.com>
PR target/86487
* lra-constraints.c(uses_hard_regs_p): Fix handling of
paradoxical SUBREGS.
gcc/testsuiteChangeLog:
2019-02-01 Andre Vieira <andre.simoesdiasvie...@arm.com>
PR target/86487
* gcc.target/arm/pr86487.c: New.