diff options
author | Artur Gainullin <artur.gainullin@intel.com> | 2018-04-11 10:29:37 +0000 |
---|---|---|
committer | Artur Gainullin <artur.gainullin@intel.com> | 2018-04-11 10:29:37 +0000 |
commit | d928201ac5ef2d61492720bd0f7323f225ffdb3e (patch) | |
tree | ee951c76977422f055ec8b0d1b33c0ef551ebae5 /llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | |
parent | 057f5a12594a26f9f2fd6d69446df517e14ec52f (diff) | |
download | bcm5719-llvm-d928201ac5ef2d61492720bd0f7323f225ffdb3e.tar.gz bcm5719-llvm-d928201ac5ef2d61492720bd0f7323f225ffdb3e.zip |
Eliminate a bitwise 'not' op of 'not' min/max by inverting the min/max.
Bitwise 'not' of the min/max could be eliminated in the pattern:
%notx = xor i32 %x, -1
%cmp1 = icmp sgt[slt/ugt/ult] i32 %notx, %y
%smax = select i1 %cmp1, i32 %notx, i32 %y
%res = xor i32 %smax, -1
https://rise4fun.com/Alive/lCN
Reviewers: spatel
Reviewed by: spatel
Subscribers: a.elovikov, llvm-commits
Differential Revision: https://reviews.llvm.org/D45317
llvm-svn: 329791
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 04a85c7a3e7..9ba92f7a637 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2696,5 +2696,35 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { return SelectInst::Create(Cmp, Builder.CreateNeg(A), A); } + // Eliminate a bitwise 'not' op of 'not' min/max by inverting the min/max: + // + // %notx = xor i32 %x, -1 + // %cmp1 = icmp sgt i32 %notx, %y + // %smax = select i1 %cmp1, i32 %notx, i32 %y + // %res = xor i32 %smax, -1 + // => + // %noty = xor i32 %y, -1 + // %cmp2 = icmp slt %x, %noty + // %res = select i1 %cmp2, i32 %x, i32 %noty + // + // Same is applicable for smin/umax/umin. + { + Value *LHS, *RHS; + SelectPatternFlavor SPF = matchSelectPattern(Op0, LHS, RHS).Flavor; + if (Op0->hasOneUse() && SelectPatternResult::isMinOrMax(SPF) && + match(Op1, m_AllOnes())) { + + Value *X; + if (match(RHS, m_Not(m_Value(X)))) + std::swap(RHS, LHS); + + if (match(LHS, m_Not(m_Value(X)))) { + Value *NotY = Builder.CreateNot(RHS); + return SelectInst::Create( + Builder.CreateICmp(getInverseMinMaxPred(SPF), X, NotY), X, NotY); + } + } + } + return Changed ? &I : nullptr; } |