diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2022-08-16 16:32:56 +0100 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2022-08-16 16:54:44 +0100 |
commit | 08d153d806b500a3d819bbc57d8c4ddcb568f26e (patch) | |
tree | c2c3b84aee0dcd7bbe933be29987fc94f40c5895 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 4fc7e9cba24b3f96f274126218a7985f31aa5861 (diff) | |
download | llvm-08d153d806b500a3d819bbc57d8c4ddcb568f26e.zip llvm-08d153d806b500a3d819bbc57d8c4ddcb568f26e.tar.gz llvm-08d153d806b500a3d819bbc57d8c4ddcb568f26e.tar.bz2 |
[ValueTracking] computeKnownBits - attempt to use a branch condition feeding a phi to improve known bits range (PR38280)
If computeKnownBits encounters a phi node, and we fail to determine any known bits through direct analysis, see if the incoming value is part of a branch condition feeding the phi.
Handle cases where icmp(IncomingValue PRED Constant) is driving a branch instruction feeding that phi node - at the moment this only handles EQ/ULT/ULE predicate cases as they are the most straightforward to handle and most likely for branch-loop 'max upper bound' cases - we can extend this if/when necessary.
I investigated a more general icmp(LHS PRED RHS) KnownBits system, but the hard limits we put on value tracking depth through phi nodes meant that we were mainly catching constants anyhow.
Fixes the pointless vectorization in PR38280 / Issue #37628 (excessive unrolling still needs handling though)
Differential Revision: https://reviews.llvm.org/D131838
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 65975d2..c4f6781 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1575,9 +1575,45 @@ static void computeKnownBitsFromOperator(const Operator *I, RecQ.CxtI = P->getIncomingBlock(u)->getTerminator(); Known2 = KnownBits(BitWidth); + // Recurse, but cap the recursion to one level, because we don't // want to waste time spinning around in loops. computeKnownBits(IncValue, Known2, MaxAnalysisRecursionDepth - 1, RecQ); + + // If this failed, see if we can use a conditional branch into the phi + // to help us determine the range of the value. + if (Known2.isUnknown()) { + ICmpInst::Predicate Pred; + const APInt *RHSC; + BasicBlock *TrueSucc, *FalseSucc; + // TODO: Use RHS Value and compute range from its known bits. + if (match(RecQ.CxtI, + m_Br(m_c_ICmp(Pred, m_Specific(IncValue), m_APInt(RHSC)), + m_BasicBlock(TrueSucc), m_BasicBlock(FalseSucc)))) { + // Check for cases of duplicate successors. + if ((TrueSucc == P->getParent()) != (FalseSucc == P->getParent())) { + // If we're using the false successor, invert the predicate. + if (FalseSucc == P->getParent()) + Pred = CmpInst::getInversePredicate(Pred); + + switch (Pred) { + case CmpInst::Predicate::ICMP_EQ: + Known2 = KnownBits::makeConstant(*RHSC); + break; + case CmpInst::Predicate::ICMP_ULE: + Known2.Zero.setHighBits(RHSC->countLeadingZeros()); + break; + case CmpInst::Predicate::ICMP_ULT: + Known2.Zero.setHighBits((*RHSC - 1).countLeadingZeros()); + break; + default: + // TODO - add additional integer predicate handling. + break; + } + } + } + } + Known = KnownBits::commonBits(Known, Known2); // If all bits have been ruled out, there's no need to check // more operands. |