diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-17 20:41:09 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-17 20:41:09 +0000 |
| commit | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (patch) | |
| tree | e6e4a4163840b73ba54bb0d3b70ee4899e4b7434 /llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | |
| parent | b1c73532ee8997fe5dfbeb7d223027bdf99758a0 (diff) | |
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 58 |
1 files changed, 29 insertions, 29 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index e42e011bd436..289976718e52 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -23,7 +23,6 @@ #include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/DataLayout.h" -#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/PatternMatch.h" #include "llvm/Support/KnownBits.h" @@ -1324,34 +1323,21 @@ Instruction *InstCombinerImpl::foldICmpWithConstant(ICmpInst &Cmp) { /// Canonicalize icmp instructions based on dominating conditions. Instruction *InstCombinerImpl::foldICmpWithDominatingICmp(ICmpInst &Cmp) { - // This is a cheap/incomplete check for dominance - just match a single - // predecessor with a conditional branch. - BasicBlock *CmpBB = Cmp.getParent(); - BasicBlock *DomBB = CmpBB->getSinglePredecessor(); - if (!DomBB) - return nullptr; - - Value *DomCond; - BasicBlock *TrueBB, *FalseBB; - if (!match(DomBB->getTerminator(), m_Br(m_Value(DomCond), TrueBB, FalseBB))) - return nullptr; - - assert((TrueBB == CmpBB || FalseBB == CmpBB) && - "Predecessor block does not point to successor?"); - - // The branch should get simplified. Don't bother simplifying this condition. - if (TrueBB == FalseBB) - return nullptr; - // We already checked simple implication in InstSimplify, only handle complex // cases here. - - CmpInst::Predicate Pred = Cmp.getPredicate(); Value *X = Cmp.getOperand(0), *Y = Cmp.getOperand(1); ICmpInst::Predicate DomPred; - const APInt *C, *DomC; - if (match(DomCond, m_ICmp(DomPred, m_Specific(X), m_APInt(DomC))) && - match(Y, m_APInt(C))) { + const APInt *C; + if (!match(Y, m_APInt(C))) + return nullptr; + + CmpInst::Predicate Pred = Cmp.getPredicate(); + ConstantRange CR = ConstantRange::makeExactICmpRegion(Pred, *C); + + auto handleDomCond = [&](Value *DomCond, bool CondIsTrue) -> Instruction * { + const APInt *DomC; + if (!match(DomCond, m_ICmp(DomPred, m_Specific(X), m_APInt(DomC)))) + return nullptr; // We have 2 compares of a variable with constants. Calculate the constant // ranges of those compares to see if we can transform the 2nd compare: // DomBB: @@ -1359,11 +1345,10 @@ Instruction *InstCombinerImpl::foldICmpWithDominatingICmp(ICmpInst &Cmp) { // br DomCond, CmpBB, FalseBB // CmpBB: // Cmp = icmp Pred X, C - ConstantRange CR = ConstantRange::makeExactICmpRegion(Pred, *C); + if (!CondIsTrue) + DomPred = CmpInst::getInversePredicate(DomPred); ConstantRange DominatingCR = - (CmpBB == TrueBB) ? ConstantRange::makeExactICmpRegion(DomPred, *DomC) - : ConstantRange::makeExactICmpRegion( - CmpInst::getInversePredicate(DomPred), *DomC); + ConstantRange::makeExactICmpRegion(DomPred, *DomC); ConstantRange Intersection = DominatingCR.intersectWith(CR); ConstantRange Difference = DominatingCR.difference(CR); if (Intersection.isEmptySet()) @@ -1391,6 +1376,21 @@ Instruction *InstCombinerImpl::foldICmpWithDominatingICmp(ICmpInst &Cmp) { return new ICmpInst(ICmpInst::ICMP_EQ, X, Builder.getInt(*EqC)); if (const APInt *NeC = Difference.getSingleElement()) return new ICmpInst(ICmpInst::ICMP_NE, X, Builder.getInt(*NeC)); + return nullptr; + }; + + for (BranchInst *BI : DC.conditionsFor(X)) { + auto *Cond = BI->getCondition(); + BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0)); + if (DT.dominates(Edge0, Cmp.getParent())) { + if (auto *V = handleDomCond(Cond, true)) + return V; + } else { + BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1)); + if (DT.dominates(Edge1, Cmp.getParent())) + if (auto *V = handleDomCond(Cond, false)) + return V; + } } return nullptr; |
