diff options
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index a53f2f6..ee4f97f 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -26,6 +26,7 @@ #include "llvm/Analysis/AssumeBundleQueries.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/DomConditionCache.h" #include "llvm/Analysis/GuardUtils.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/Loads.h" @@ -706,9 +707,33 @@ static void computeKnownBitsFromCmp(const Value *V, CmpInst::Predicate Pred, void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known, unsigned Depth, const SimplifyQuery &Q) { - // Use of assumptions is context-sensitive. If we don't have a context, we - // cannot use them! - if (!Q.AC || !Q.CxtI) + if (!Q.CxtI) + return; + + if (Q.DC && Q.DT) { + // Handle dominating conditions. + for (BranchInst *BI : Q.DC->conditionsFor(V)) { + auto *Cmp = dyn_cast<ICmpInst>(BI->getCondition()); + if (!Cmp) + continue; + + BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0)); + if (Q.DT->dominates(Edge0, Q.CxtI->getParent())) + computeKnownBitsFromCmp(V, Cmp->getPredicate(), Cmp->getOperand(0), + Cmp->getOperand(1), Known, Depth, Q); + + BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1)); + if (Q.DT->dominates(Edge1, Q.CxtI->getParent())) + computeKnownBitsFromCmp(V, Cmp->getInversePredicate(), + Cmp->getOperand(0), Cmp->getOperand(1), Known, + Depth, Q); + } + + if (Known.hasConflict()) + Known.resetAll(); + } + + if (!Q.AC) return; unsigned BitWidth = Known.getBitWidth(); |