diff options
| author | Roman Lebedev <lebedev.ri@gmail.com> | 2019-08-29 12:47:34 +0000 | 
|---|---|---|
| committer | Roman Lebedev <lebedev.ri@gmail.com> | 2019-08-29 12:47:34 +0000 | 
| commit | 9f35d2b564041da3a661b763414b75a51eda9a77 (patch) | |
| tree | 5dde52e57fd21f91bc9e4b4b632437213096b8cb /llvm/lib/Transforms | |
| parent | 473a063a5e1381287880e8b9c54cce901712f01d (diff) | |
| download | bcm5719-llvm-9f35d2b564041da3a661b763414b75a51eda9a77.tar.gz bcm5719-llvm-9f35d2b564041da3a661b763414b75a51eda9a77.zip | |
[SimplifyCFG] FoldTwoEntryPHINode(): don't bailout on i1 PHI's if we can hoist a 'not' from incoming values
Summary:
As it can be seen in the tests in D65143/D65144, even though we have formed an '@llvm.umul.with.overflow'
and got rid of potential for division-by-zero, the control flow remains, we still have that branch.
We have this condition:
```
  // Don't fold i1 branches on PHIs which contain binary operators
  // These can often be turned into switches and other things.
  if (PN->getType()->isIntegerTy(1) &&
      (isa<BinaryOperator>(PN->getIncomingValue(0)) ||
       isa<BinaryOperator>(PN->getIncomingValue(1)) ||
       isa<BinaryOperator>(IfCond)))
    return false;
```
which was added back in rL121764 to help with `select` formation i think?
That check prevents us to flatten the CFG here, even though we know
we no longer need that guard and will be able to drop everything
but the '@llvm.umul.with.overflow' + `not`.
As it can be seen from tests, we end here because the `not` is being
sinked into the PHI's incoming values by InstCombine,
so we can't workaround this by hoisting it to after PHI.
Thus i suggest that we relax that check to not bailout if we'd get to hoist the `not`.
Reviewers: craig.topper, spatel, fhahn, nikic
Reviewed By: spatel
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65147
llvm-svn: 370349
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 18 | 
1 files changed, 15 insertions, 3 deletions
| diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 33dbbf91cd6..478f32a8f45 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -2329,12 +2329,24 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,    if (!PN)      return true; -  // Don't fold i1 branches on PHIs which contain binary operators.  These can -  // often be turned into switches and other things. +  // Return true if at least one of these is a 'not', and another is either +  // a 'not' too, or a constant. +  auto CanHoistNotFromBothValues = [](Value *V0, Value *V1) { +    if (!match(V0, m_Not(m_Value()))) +      std::swap(V0, V1); +    auto Invertible = m_CombineOr(m_Not(m_Value()), m_AnyIntegralConstant()); +    return match(V0, m_Not(m_Value())) && match(V1, Invertible); +  }; + +  // Don't fold i1 branches on PHIs which contain binary operators, unless one +  // of the incoming values is an 'not' and another one is freely invertible. +  // These can often be turned into switches and other things.    if (PN->getType()->isIntegerTy(1) &&        (isa<BinaryOperator>(PN->getIncomingValue(0)) ||         isa<BinaryOperator>(PN->getIncomingValue(1)) || -       isa<BinaryOperator>(IfCond))) +       isa<BinaryOperator>(IfCond)) && +      !CanHoistNotFromBothValues(PN->getIncomingValue(0), +                                 PN->getIncomingValue(1)))      return false;    // If all PHI nodes are promotable, check to make sure that all instructions | 

