llvm / llvm/llvm-project

Repeat remat doesn't work with non-trivial remat

Open
#161,972 0 comments 0 reactions 0 assignees View on GitHub
llvm:codegen missed-optimization
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.