This is an archive of the discontinued LLVM Phabricator instance.

shrink-wrap: fix shrink-wrapping for no-return paths
ClosedPublic

Authored by thegameg on May 1 2017, 12:24 PM.

Details

Reviewers
qcolombet
MatzeB
Summary

Shrink-wrapping uses post-dominators to find a restore point that post-dominates all the uses of CSR / stack.

The way dominator trees are modeled in LLVM today is that unreachable blocks are not present in a generic dominator tree. I am actually guessing this from some comments: include/llvm/Support/GenericDomTree.h:423,
So, an unreachable node is dominated by anything: include/llvm/Support/GenericDomTree.h:467.
There seems to be an explanation that an unreachable block may or may not appear in the dominator tree: include/llvm/IR/Dominators.h:103:

/// A forward unreachable block may appear in the dominator tree, or it may
/// not.  If it does, dominance queries will return results as if all reachable
/// blocks dominate it.  When asking for a Node corresponding to a potentially
/// unreachable block, calling code must handle the case where the block was
/// unreachable and the result of getNode() is nullptr.
///
/// Generally, a block known to be unreachable when the dominator tree is
/// constructed will not be in the tree.  One which becomes unreachable after
/// the dominator tree is initially constructed may still exist in the tree,
/// even if the tree is properly updated. Calling code should not rely on the
/// preceding statements; this is stated only to assist human understanding.

From that, I assume the MachineDominators might work in the same way.

Since for post-dominators, a no-return block is considered "unreachable", calling findNearestCommonDominator on an unreachable node A and a non-unreachable node B, will return B, which can be false.

I suggest that if we find such a node, we bail out since there is no good restore point.

Diff Detail

Event Timeline

thegameg created this revision.May 1 2017, 12:24 PM
This revision is now accepted and ready to land.May 12 2017, 11:31 AM
MatzeB requested changes to this revision.May 12 2017, 11:35 AM

Good find Francis. I am not convinced however the fix is save (see below). And for that matter the existing if (!Save) code path in FindIDom() seems to suffer the same problem.

lib/CodeGen/ShrinkWrap.cpp
292

Setting this to nullptr seems incorrect to me. From my understanding that resets us to a state where it seems like we haven't looked at any part of the function and will just pick the next block that comes along, which seems really sketchy to me. Shouldn't we rather abort the whole shrinkwrapping process at this point?

This revision now requires changes to proceed.May 12 2017, 11:35 AM
MatzeB accepted this revision.May 12 2017, 11:37 AM

Okay I misread the code, looks like ArePointsInteresting() abort if Save or Restore is nullptr. So this seems fine.

Would be nice to add a comment that setting it to nullptr will abort the shrinkwrapping when committing.

This revision is now accepted and ready to land.May 12 2017, 11:37 AM
thegameg closed this revision.May 15 2017, 4:31 PM

Sorry, I forgot to add the review link to the commit message. I added comments, fixed a Thumb2 test (test/CodeGen/Thumb2/v8_IT_5.ll) and committed as r303130.