summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/InstCombine')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp20
1 files changed, 12 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index f153db177cac..cf6e7315114d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1465,20 +1465,24 @@ Instruction *InstCombinerImpl::foldICmpTruncConstant(ICmpInst &Cmp,
ConstantInt::get(V->getType(), 1));
}
- // TODO: Handle any shifted constant by subtracting trailing zeros.
// TODO: Handle non-equality predicates.
Value *Y;
- if (Cmp.isEquality() && match(X, m_Shl(m_One(), m_Value(Y)))) {
- // (trunc (1 << Y) to iN) == 0 --> Y u>= N
- // (trunc (1 << Y) to iN) != 0 --> Y u< N
+ const APInt *Pow2;
+ if (Cmp.isEquality() && match(X, m_Shl(m_Power2(Pow2), m_Value(Y))) &&
+ DstBits > Pow2->logBase2()) {
+ // (trunc (Pow2 << Y) to iN) == 0 --> Y u>= N - log2(Pow2)
+ // (trunc (Pow2 << Y) to iN) != 0 --> Y u< N - log2(Pow2)
+ // iff N > log2(Pow2)
if (C.isZero()) {
auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
- return new ICmpInst(NewPred, Y, ConstantInt::get(SrcTy, DstBits));
+ return new ICmpInst(NewPred, Y,
+ ConstantInt::get(SrcTy, DstBits - Pow2->logBase2()));
}
- // (trunc (1 << Y) to iN) == 2**C --> Y == C
- // (trunc (1 << Y) to iN) != 2**C --> Y != C
+ // (trunc (Pow2 << Y) to iN) == 2**C --> Y == C - log2(Pow2)
+ // (trunc (Pow2 << Y) to iN) != 2**C --> Y != C - log2(Pow2)
if (C.isPowerOf2())
- return new ICmpInst(Pred, Y, ConstantInt::get(SrcTy, C.logBase2()));
+ return new ICmpInst(
+ Pred, Y, ConstantInt::get(SrcTy, C.logBase2() - Pow2->logBase2()));
}
if (Cmp.isEquality() && (Trunc->hasOneUse() || Trunc->hasNoUnsignedWrap())) {