diff options
| author | Huihui Zhang <huihuiz@quicinc.com> | 2019-06-25 20:44:52 +0000 |
|---|---|---|
| committer | Huihui Zhang <huihuiz@quicinc.com> | 2019-06-25 20:44:52 +0000 |
| commit | b90cb57b63aec4a234d1a138e31af4e0b603ccff (patch) | |
| tree | a83b2dbd95e567f6bea556e4be5d5a21d79172f0 /llvm/lib/Transforms | |
| parent | dcd7eb710bc4b782c298ee30ee0143d788e72c97 (diff) | |
| download | bcm5719-llvm-b90cb57b63aec4a234d1a138e31af4e0b603ccff.tar.gz bcm5719-llvm-b90cb57b63aec4a234d1a138e31af4e0b603ccff.zip | |
[InstCombine] Simplify icmp ult/uge (shl %x, C2), C1 iff C1 is power of two -> icmp eq/ne (and %x, (lshr -C1, C2)), 0.
Simplify 'shl' inequality test into 'and' equality test.
This pattern happens in the middle-end while simplifying bitfield access,
Exposed in https://reviews.llvm.org/D63505
https://rise4fun.com/Alive/6uz
Reviewers: lebedev.ri, efriedma
Reviewed By: lebedev.ri
Subscribers: spatel, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D63675
llvm-svn: 364348
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index c62e2ba843c..29ac729682d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2028,6 +2028,27 @@ Instruction *InstCombiner::foldICmpShlConstant(ICmpInst &Cmp, And, Constant::getNullValue(ShType)); } + // Simplify 'shl' inequality test into 'and' equality test. + if (Cmp.isUnsigned() && Shl->hasOneUse()) { + // (X l<< C2) u<=/u> C1 iff C1+1 is power of two -> X & (~C1 l>> C2) ==/!= 0 + if ((C + 1).isPowerOf2() && + (Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_UGT)) { + Value *And = Builder.CreateAnd(X, (~C).lshr(ShiftAmt->getZExtValue())); + return new ICmpInst(Pred == ICmpInst::ICMP_ULE ? ICmpInst::ICMP_EQ + : ICmpInst::ICMP_NE, + And, Constant::getNullValue(ShType)); + } + // (X l<< C2) u</u>= C1 iff C1 is power of two -> X & (-C1 l>> C2) ==/!= 0 + if (C.isPowerOf2() && + (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_UGE)) { + Value *And = + Builder.CreateAnd(X, (~(C - 1)).lshr(ShiftAmt->getZExtValue())); + return new ICmpInst(Pred == ICmpInst::ICMP_ULT ? ICmpInst::ICMP_EQ + : ICmpInst::ICMP_NE, + And, Constant::getNullValue(ShType)); + } + } + // Transform (icmp pred iM (shl iM %v, N), C) // -> (icmp pred i(M-N) (trunc %v iM to i(M-N)), (trunc (C>>N)) // Transform the shl to a trunc if (trunc (C>>N)) has no loss and M-N. |

