aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-17 20:41:09 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-17 20:41:09 +0000
commit312c0ed19cc5276a17bacf2120097bec4515b0f1 (patch)
treee6e4a4163840b73ba54bb0d3b70ee4899e4b7434 /llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
parentb1c73532ee8997fe5dfbeb7d223027bdf99758a0 (diff)
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp58
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;