summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3c01d979560..a6ad6bf8cae 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5378,3 +5378,35 @@ Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
}
return None;
}
+
+Optional<bool> llvm::isImpliedByDomCondition(const Value *Cond,
+ const Instruction *ContextI,
+ const DataLayout &DL) {
+ assert(Cond->getType()->isIntOrIntVectorTy(1) && "Condition must be bool");
+ if (!ContextI || !ContextI->getParent())
+ return None;
+
+ // TODO: This is a poor/cheap way to determine dominance. Should we use a
+ // dominator tree (eg, from a SimplifyQuery) instead?
+ const BasicBlock *ContextBB = ContextI->getParent();
+ const BasicBlock *PredBB = ContextBB->getSinglePredecessor();
+ if (!PredBB)
+ return None;
+
+ // We need a conditional branch in the predecessor.
+ Value *PredCond;
+ BasicBlock *TrueBB, *FalseBB;
+ if (!match(PredBB->getTerminator(), m_Br(m_Value(PredCond), TrueBB, FalseBB)))
+ return None;
+
+ // The branch should get simplified. Don't bother simplifying this condition.
+ if (TrueBB == FalseBB)
+ return None;
+
+ assert((TrueBB == ContextBB || FalseBB == ContextBB) &&
+ "Predecessor block does not point to successor?");
+
+ // Is this condition implied by the predecessor condition?
+ bool CondIsTrue = TrueBB == ContextBB;
+ return isImpliedCondition(PredCond, Cond, DL, CondIsTrue);
+}
OpenPOWER on IntegriCloud