This is an archive of the discontinued LLVM Phabricator instance.

[RegisterCoalescer] Avoid erasing copy that breaks subranges
AbandonedPublic

Authored by tpr on Jun 11 2018, 9:38 AM.

Details

Reviewers
MatzeB
kparzysz
Summary

I found a case where erasing a copy in coalescing causes a subrange to
be modified incorrectly.

It looks like it would be quite a large change to fix this properly,
such that subranges are updated correctly when a subreg is dead in and
live out of a copy being erased.

A possible alternative would be to recalculate subranges from scratch
for a register that is affected by this problem.

For now, I have just disabled that case of erasing a copy when subranges
are present.

Change-Id: Ib85a4e7e5458ec1b156cb84207c51cab63e92635

Diff Detail

Event Timeline

tpr created this revision.Jun 11 2018, 9:38 AM
tpr added subscribers: arsenm, dstuttard.

What exactly is done wrong in the testcase without your change? I see one extra IMPLICIT_DEF in the output, compared to running it with your change.

Updating live ranges should work correctly, disabling erasing copies is not the right thing to do.

Could you run the input through -run-pass=none first? It will produce a slightly better-looking .mir.

I missed the comment in the .mir file.

tpr updated this revision to Diff 150995.Jun 12 2018, 12:31 PM

V2: This is a revised fix. Still not the proper fix, but at least it
doesn't stop a copy being erased.

Also tidied the test as suggested.

Here's the new commit message, as I don't think phabricator updates the
summary box:

[RegisterCoalescer] Recalculate subranges in some cases

Summary:
I found a case where erasing a copy in coalescing causes a subrange to
be modified incorrectly.

It looks like it would be quite a large change to fix this properly,
such that subranges are updated correctly when a subreg is dead in and
live out of a copy being erased.

So for now, in the case causing my problem, it now just recalculates
the whole live interval after the coalesce.
tpr added a comment.Jun 12 2018, 12:35 PM

To try and diagnose this kind of problem in the future, I added code (not in this change) to always recalculate the live interval if there are subranges, and compare it with the one updated in RegisterCoalescer.cpp. The problem I ran into then is that RegisterCoalescer remembers more information about when subregs are undef and thus considered not live than is available in the MIR after coalescing. I wonder if there is some way of recording undef subregs in a use in MIR such that recalculating a live interval should always give the same result as updating in coalescing, and if it doesn't then you've found a bug.

Could you try D41802 and see if it works for you? I works with the testcase and it passes my local tests.

tpr abandoned this revision.Jun 18 2018, 1:17 PM

Superseded by D48102 from Krzysztof.