diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2018-09-12 18:19:43 +0000 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2018-09-12 18:19:43 +0000 |
commit | 75404fb9f8a83cef60720cf504cb10a7b01b4271 (patch) | |
tree | 6785403bddf925e0e8ab10c552f8a9aff6b33f3e /llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | |
parent | aad4027dc3b6e96fb949242a0635ef69151d6d70 (diff) | |
download | bcm5719-llvm-75404fb9f8a83cef60720cf504cb10a7b01b4271.tar.gz bcm5719-llvm-75404fb9f8a83cef60720cf504cb10a7b01b4271.zip |
[InstCombine] Inefficient pattern for high-bits checking (PR38708)
Summary:
It is sometimes important to check that some newly-computed value
is non-negative and only `n` bits wide (where `n` is a variable.)
There are **many** ways to check that:
https://godbolt.org/z/o4RB8D
The last variant seems best?
(I'm sure there are some other variations i haven't thought of..)
Let's handle the second variant first, since it is much simpler.
https://rise4fun.com/Alive/LYjY
https://bugs.llvm.org/show_bug.cgi?id=38708
Reviewers: spatel, craig.topper, RKSimon
Reviewed By: spatel
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D51985
llvm-svn: 342067
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 875d6d9f053..d0673d952d0 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4623,6 +4623,41 @@ static Instruction *canonicalizeICmpBool(ICmpInst &I, } } +// Transform pattern like: +// (1 << Y) u<= X +// (1 << Y) u> X +// Into: +// (X l>> Y) != 0 +// (X l>> Y) == 0 +static Instruction *foldICmpWithHighBitMask(ICmpInst &Cmp, + InstCombiner::BuilderTy &Builder) { + ICmpInst::Predicate Pred; + Value *X, *Y; + if (!match(&Cmp, + m_c_ICmp(Pred, m_OneUse(m_Shl(m_One(), m_Value(Y))), m_Value(X)))) + return nullptr; + + // We want X to be the icmp's second operand, so swap predicate if it is not. + if (Cmp.getOperand(0) == X) + Pred = Cmp.getSwappedPredicate(); + + ICmpInst::Predicate NewPred; + switch (Pred) { + case ICmpInst::ICMP_ULE: + NewPred = ICmpInst::ICMP_NE; + break; + case ICmpInst::ICMP_UGT: + NewPred = ICmpInst::ICMP_EQ; + break; + default: + return nullptr; + } + + Value *NewX = Builder.CreateLShr(X, Y, X->getName() + ".highbits"); + Constant *Zero = Constant::getNullValue(NewX->getType()); + return CmpInst::Create(Instruction::ICmp, NewPred, NewX, Zero); +} + static Instruction *foldVectorCmp(CmpInst &Cmp, InstCombiner::BuilderTy &Builder) { // If both arguments of the cmp are shuffles that use the same mask and @@ -4913,6 +4948,9 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { return foldICmpAddOpConst(X, *C, I.getSwappedPredicate()); } + if (Instruction *Res = foldICmpWithHighBitMask(I, Builder)) + return Res; + if (I.getType()->isVectorTy()) if (Instruction *Res = foldVectorCmp(I, Builder)) return Res; |