The previous handling for guard widening in InstCombine was extremely restrictive. In particular, it didn't handle the common case where we had two guards separated by a single icmp. Handle this by scanning through a small fixed window of instructions to find the next guard if needed.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
test/Transforms/InstCombine/call-guard.ll | ||
---|---|---|
36 ↗ | (On Diff #144378) | Note to self: before submit, this needs tests to show negative cases: i.e. why do the intermediate instructions have to be safe to execute? |
I would suggest a slightly different approach to handle such situations. Whenever we see consecutive guard followed by an instruction that is safe to speculate, we can just swap them. Doing so, we will collect all guards in one continuous sequence after all speculable code. And then we just fold consecutive pairs. What do you think about it?
lib/Transforms/InstCombine/InstCombineCalls.cpp | ||
---|---|---|
3631 ↗ | (On Diff #144378) | How about having this number as an option rather than a hard-coded constant? |
lib/Transforms/InstCombine/InstCombineCalls.cpp | ||
---|---|---|
3651 ↗ | (On Diff #144378) | We should assert that Temp is guaranteed to transfer execution to its successor, otherwise it might be illegal. |
I thought about this approach and I agree it's interesting. It does have one serious problem I haven't quite figured out yet though which is that hoisting above the guard changes placement in the final lowered IR. If we'd left it where it was, we might have been able to *sink* the instruction into a block with the only user.
My original plan was to do this patch, then spend more time thinking about the sinking problem. If we can solve that, then I agree, hoisting over guards by default is probably the right long term answer.