diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-12-04 15:35:17 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-12-04 15:35:17 +0000 |
commit | a40bf9fff7ee71d20451a3d0e380a85646e3a7df (patch) | |
tree | 1e16f9b3c8c09b6f6bde81ca484d9a47d0f36d09 /llvm/lib | |
parent | 2c1ff9dda762e010075f429e18ce1c499f1f4d0e (diff) | |
download | bcm5719-llvm-a40bf9fff7ee71d20451a3d0e380a85646e3a7df.tar.gz bcm5719-llvm-a40bf9fff7ee71d20451a3d0e380a85646e3a7df.zip |
[InstCombine] add helper for icmp with dominator; NFC
There's a potential small enhancement to this code that could
solve the cases currently under proposal in D54827 via SimplifyCFG.
Whether instcombine should be doing this kind of semi-non-local
analysis in the first place is an open question, but separating
the logic out can only help if/when we decide to move it to a
different pass.
AFAICT, any proposal to do this in SimplifyCFG could also be seen
as an overreach + it would be incomplete to start the fold from a
branch rather than an icmp.
There's another question here about the code for processUGT_ADDCST_ADD().
That part may be completely dead after rL234638 ?
llvm-svn: 348273
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 43 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineInternal.h | 1 |
2 files changed, 24 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index ab933d7d961..0a73b2402cc 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1335,17 +1335,12 @@ Instruction *InstCombiner::foldICmpWithZero(ICmpInst &Cmp) { return nullptr; } -// Fold icmp Pred X, C. +/// Fold icmp Pred X, C. +/// TODO: This code structure does not make much sense. The saturating add fold +/// should be moved to some other helper and extended as noted below (it is also +/// possible that code has been made unnecessary - no regression test failures). +/// The dominating compare fold should not be limited to compare with constant. Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &Cmp) { - CmpInst::Predicate Pred = Cmp.getPredicate(); - Value *X = Cmp.getOperand(0); - - const APInt *C; - if (!match(Cmp.getOperand(1), m_APInt(C))) - return nullptr; - - Value *A = nullptr, *B = nullptr; - // Match the following pattern, which is a common idiom when writing // overflow-safe integer arithmetic functions. The source performs an addition // in wider type and explicitly checks for overflow using comparisons against @@ -1357,21 +1352,29 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &Cmp) { // // sum = a + b // if (sum+128 >u 255) ... -> llvm.sadd.with.overflow.i8 - { - ConstantInt *CI2; // I = icmp ugt (add (add A, B), CI2), CI - if (Pred == ICmpInst::ICMP_UGT && - match(X, m_Add(m_Add(m_Value(A), m_Value(B)), m_ConstantInt(CI2)))) - if (Instruction *Res = processUGT_ADDCST_ADD( - Cmp, A, B, CI2, cast<ConstantInt>(Cmp.getOperand(1)), *this)) - return Res; - } + CmpInst::Predicate Pred = Cmp.getPredicate(); + Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1); + Value *A, *B; + ConstantInt *CI, *CI2; // I = icmp ugt (add (add A, B), CI2), CI + if (Pred == ICmpInst::ICMP_UGT && match(Op1, m_ConstantInt(CI)) && + match(Op0, m_Add(m_Add(m_Value(A), m_Value(B)), m_ConstantInt(CI2)))) + if (Instruction *Res = processUGT_ADDCST_ADD(Cmp, A, B, CI2, CI, *this)) + return Res; - // FIXME: Use m_APInt to allow folds for splat constants. + if (Instruction *I = foldICmpWithDominatingICmp(Cmp)) + return I; + + return nullptr; +} + +/// Canonicalize icmp instructions based on dominating conditions. +Instruction *InstCombiner::foldICmpWithDominatingICmp(ICmpInst &Cmp) { + CmpInst::Predicate Pred = Cmp.getPredicate(); + Value *X = Cmp.getOperand(0); ConstantInt *CI = dyn_cast<ConstantInt>(Cmp.getOperand(1)); if (!CI) return nullptr; - // Canonicalize icmp instructions based on dominating conditions. BasicBlock *Parent = Cmp.getParent(); BasicBlock *Dom = Parent->getSinglePredecessor(); auto *BI = Dom ? dyn_cast<BranchInst>(Dom->getTerminator()) : nullptr; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index 07e21225450..e507630f9ea 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -857,6 +857,7 @@ private: Instruction *foldICmpWithCastAndCast(ICmpInst &ICI); Instruction *foldICmpUsingKnownBits(ICmpInst &Cmp); + Instruction *foldICmpWithDominatingICmp(ICmpInst &Cmp); Instruction *foldICmpWithConstant(ICmpInst &Cmp); Instruction *foldICmpInstWithConstant(ICmpInst &Cmp); Instruction *foldICmpInstWithConstantNotInt(ICmpInst &Cmp); |