summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2018-09-12 18:19:43 +0000
committerRoman Lebedev <lebedev.ri@gmail.com>2018-09-12 18:19:43 +0000
commit75404fb9f8a83cef60720cf504cb10a7b01b4271 (patch)
tree6785403bddf925e0e8ab10c552f8a9aff6b33f3e /llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
parentaad4027dc3b6e96fb949242a0635ef69151d6d70 (diff)
downloadbcm5719-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.cpp38
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;
OpenPOWER on IntegriCloud