Repeat remat doesn't work with non-trivial remat
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Filing this to track a work item discovered when working on https://github.com/llvm/llvm-project/pull/160765. This is an interaction with non-trivial remat which we should probably return to once https://github.com/llvm/llvm-project/pull/159211 has landed. This doesn't appear to be a correctness issue, but might be an opt quality issue.
In LiveRangeEdit::eliminateDeadDef, we delete definitions whose uses have been fully eliminated *except* that we keep rematerializable definitions at the start of their original live range. Except that if the remat instruction has a virtual register use, we don't.
Keeping the instruction is important for our ability to further rematerialize within the original live interval. Once we delete it, all further remat stops.
So, if we get a series of events like this:
1) Given a very big live interval, split it into sub-ranges (say into a loop).
2) Perform non-trivial remat, delete the original instruction.
3) Further split the live interval
4) Eventually need to spill one of the sub-intervals
5) Try to remat the original def, fail, and spill instead.
The current heuristic is trying to balance the need to shrink the operand live ranges. This seems like a general valid concern.
I think we might be able to change how we find the rematerializable instruction in the original range, but haven't fully thought this through.
A test case which demonstrates this issue was added in https://github.com/llvm/llvm-project/pull/161614, as the same behavior triggered the violation of my newly added invariant. This is a rather hard to hit case.
Contributor guide
Assessment
This issue has not been assessed yet.